{"openapi":"3.1.0","info":{"title":"Enginy API","version":"1.0.0","description":"Public API for Enginy platform"},"servers":[{"url":"https://openapi.enginy.ai","description":"Configured server"}],"tags":[{"name":"AI Variables","description":"Manage AI variables and discover the entity fields you can reference in prompts and entity requests."},{"name":"Inbox","description":"Inbox endpoints for listing contact threads, reading thread messages, managing tags, and sending manual replies."}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{},"parameters":{}},"paths":{"/v1/ai-variables/folders/contacts":{"get":{"summary":"List contact AI variable folders","description":"List contact AI variable folders. By default this returns only root folders. Use `includeChildren=true` to return nested folders too..\n\n    > **Required scope:** `AI_VARIABLES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes nested folders instead of returning only root folders."},"required":false,"description":"When `true`, includes nested folders instead of returning only root folders.","name":"includeChildren","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes recursive subfolder and AI variable counts."},"required":false,"description":"When `true`, includes recursive subfolder and AI variable counts.","name":"includeRecursiveCounts","in":"query"}],"responses":{"200":{"description":"Folders retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"aiVariablesCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalAiVariablesCount":{"type":"number"}},"required":["id","name","parentId","entity","createdAt","updatedAt","aiVariablesCount","subfoldersCount"]}}},"required":["status","message","data"]}}}}}},"post":{"summary":"Create contact AI variable folder","description":"Create a contact AI variable folder. Folder names must be unique per entity..\n\n    > **Required scope:** `AI_VARIABLES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Optional parent folder ID."}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Folder created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","entity","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}}},"/v1/ai-variables/folders/contacts/{folderId}":{"get":{"summary":"Get contact AI variable folder","description":"Get a contact AI variable folder with its child folders, AI variables, and breadcrumb ancestors..\n\n    > **Required scope:** `AI_VARIABLES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"AI variable folder ID"},"required":true,"description":"AI variable folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Folder retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"aiVariablesCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalAiVariablesCount":{"type":"number"},"children":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"aiVariablesCount":{"type":"number"},"subfoldersCount":{"type":"number"}},"required":["id","name","parentId","createdAt","updatedAt","entity","aiVariablesCount","subfoldersCount"]}},"parent":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"aiVariables":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the AI variable."},"name":{"type":"string","description":"Unique AI variable name. Use this exact name in prompts and entity field requests."},"prompt":{"type":"string","description":"Plain-text prompt template. Field references use the `{fieldName}` syntax."},"model":{"type":["string","null"],"description":"Model ID used to run the variable. If omitted on create, Enginy uses the default AI model."},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["text","number","date","oneOf","url","email"],"description":"Controls the output format Enginy expects from the AI variable."},"values":{"type":"array","items":{"type":"string"},"description":"Required when `type` is `oneOf`. Lists the allowed values the model should return."},"provideExplanation":{"type":"boolean","description":"When true, Enginy also stores an explanation alongside the generated value."},"jsonSchema":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}],"description":"Advanced JSON schema override used by some structured-output AI variables."}},"required":["type"],"additionalProperties":false,"description":"Output contract for the AI variable."},"search":{"type":"boolean","description":"Enable or disable Deep Search for this AI variable. This is the only public search option."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Which entity stores the resulting value."},"folderId":{"type":["number","null"],"description":"Folder ID used to organize the AI variable."},"customWebsiteField":{"type":["string","null"],"description":"Optional custom website source field used by variables that crawl a specific website field."},"description":{"type":["string","null"],"description":"Auto-generated variable description, when available."},"isPublic":{"type":"boolean","description":"Whether the AI variable is globally public inside Enginy."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"Archive timestamp. Archived variables are excluded from list results unless requested."},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp."},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp."}},"required":["id","name","prompt","model","outputSchema","search","entity","folderId","customWebsiteField","description","isPublic","archivedAt","createdAt","updatedAt"]}},"ancestors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]}},"required":["id","name","parentId"]}}},"required":["id","name","parentId","entity","createdAt","updatedAt","aiVariablesCount","subfoldersCount","children","parent","aiVariables","ancestors"]}},"required":["status","message","data"]}}}},"404":{"description":"Folder not found"}}},"patch":{"summary":"Update contact AI variable folder","description":"Update a contact AI variable folder name or parent. Moving a folder into one of its descendants is not allowed..\n\n    > **Required scope:** `AI_VARIABLES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"AI variable folder ID"},"required":true,"description":"AI variable folder ID","name":"folderId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Updated folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Updated parent folder ID or `null` to move to root."}},"additionalProperties":false}}}},"responses":{"200":{"description":"Folder updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","entity","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}},"delete":{"summary":"Delete contact AI variable folder","description":"Delete a contact AI variable folder. Child folders are moved to the deleted folder's parent, and AI variables inside the deleted folder are reassigned to that same parent instead of being deleted..\n\n    > **Required scope:** `AI_VARIABLES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"AI variable folder ID"},"required":true,"description":"AI variable folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Folder deleted successfully"}}}},"/v1/ai-variables/folders/companies":{"get":{"summary":"List company AI variable folders","description":"List company AI variable folders. By default this returns only root folders. Use `includeChildren=true` to return nested folders too..\n\n    > **Required scope:** `AI_VARIABLES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes nested folders instead of returning only root folders."},"required":false,"description":"When `true`, includes nested folders instead of returning only root folders.","name":"includeChildren","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes recursive subfolder and AI variable counts."},"required":false,"description":"When `true`, includes recursive subfolder and AI variable counts.","name":"includeRecursiveCounts","in":"query"}],"responses":{"200":{"description":"Folders retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"aiVariablesCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalAiVariablesCount":{"type":"number"}},"required":["id","name","parentId","entity","createdAt","updatedAt","aiVariablesCount","subfoldersCount"]}}},"required":["status","message","data"]}}}}}},"post":{"summary":"Create company AI variable folder","description":"Create a company AI variable folder. Folder names must be unique per entity..\n\n    > **Required scope:** `AI_VARIABLES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Optional parent folder ID."}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Folder created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","entity","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}}},"/v1/ai-variables/folders/companies/{folderId}":{"get":{"summary":"Get company AI variable folder","description":"Get a company AI variable folder with its child folders, AI variables, and breadcrumb ancestors..\n\n    > **Required scope:** `AI_VARIABLES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"AI variable folder ID"},"required":true,"description":"AI variable folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Folder retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"aiVariablesCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalAiVariablesCount":{"type":"number"},"children":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"aiVariablesCount":{"type":"number"},"subfoldersCount":{"type":"number"}},"required":["id","name","parentId","createdAt","updatedAt","entity","aiVariablesCount","subfoldersCount"]}},"parent":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"aiVariables":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the AI variable."},"name":{"type":"string","description":"Unique AI variable name. Use this exact name in prompts and entity field requests."},"prompt":{"type":"string","description":"Plain-text prompt template. Field references use the `{fieldName}` syntax."},"model":{"type":["string","null"],"description":"Model ID used to run the variable. If omitted on create, Enginy uses the default AI model."},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["text","number","date","oneOf","url","email"],"description":"Controls the output format Enginy expects from the AI variable."},"values":{"type":"array","items":{"type":"string"},"description":"Required when `type` is `oneOf`. Lists the allowed values the model should return."},"provideExplanation":{"type":"boolean","description":"When true, Enginy also stores an explanation alongside the generated value."},"jsonSchema":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}],"description":"Advanced JSON schema override used by some structured-output AI variables."}},"required":["type"],"additionalProperties":false,"description":"Output contract for the AI variable."},"search":{"type":"boolean","description":"Enable or disable Deep Search for this AI variable. This is the only public search option."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Which entity stores the resulting value."},"folderId":{"type":["number","null"],"description":"Folder ID used to organize the AI variable."},"customWebsiteField":{"type":["string","null"],"description":"Optional custom website source field used by variables that crawl a specific website field."},"description":{"type":["string","null"],"description":"Auto-generated variable description, when available."},"isPublic":{"type":"boolean","description":"Whether the AI variable is globally public inside Enginy."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"Archive timestamp. Archived variables are excluded from list results unless requested."},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp."},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp."}},"required":["id","name","prompt","model","outputSchema","search","entity","folderId","customWebsiteField","description","isPublic","archivedAt","createdAt","updatedAt"]}},"ancestors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]}},"required":["id","name","parentId"]}}},"required":["id","name","parentId","entity","createdAt","updatedAt","aiVariablesCount","subfoldersCount","children","parent","aiVariables","ancestors"]}},"required":["status","message","data"]}}}},"404":{"description":"Folder not found"}}},"patch":{"summary":"Update company AI variable folder","description":"Update a company AI variable folder name or parent. Moving a folder into one of its descendants is not allowed..\n\n    > **Required scope:** `AI_VARIABLES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"AI variable folder ID"},"required":true,"description":"AI variable folder ID","name":"folderId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Updated folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Updated parent folder ID or `null` to move to root."}},"additionalProperties":false}}}},"responses":{"200":{"description":"Folder updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"entity":{"type":"string","enum":["CONTACT","COMPANY"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","entity","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}},"delete":{"summary":"Delete company AI variable folder","description":"Delete a company AI variable folder. Child folders are moved to the deleted folder's parent, and AI variables inside the deleted folder are reassigned to that same parent instead of being deleted..\n\n    > **Required scope:** `AI_VARIABLES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"AI variable folder ID"},"required":true,"description":"AI variable folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Folder deleted successfully"}}}},"/v1/contacts/fields":{"get":{"summary":"Get contact field metadata","description":"Retrieve the contact fields you can reference in prompts and request through the contacts endpoints..\n\n    > **Required scope:** `CONTACTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Contacts","AI Variables"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Contact field metadata retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Entity these fields belong to."},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Exact field identifier used in prompts (`{fieldName}`) and `fields` query params across the entity endpoints."},"label":{"type":"string","description":"Human-readable field label."},"fieldType":{"type":"string","enum":["STANDARD","AI_VARIABLE","CRM_FIELD","FORMULA_FIELD","EMPTY_FIELD"],"description":"Whether this is a standard field or a smart field type."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Entity the field belongs to."},"dataType":{"type":"string","description":"Underlying data type."},"editable":{"type":"boolean","description":"Whether this field is editable via the entity update endpoint."},"searchable":{"type":"boolean","description":"Whether this field is searchable in Enginy."},"sortable":{"type":"boolean","description":"Whether this field is sortable in Enginy."},"importable":{"type":"boolean","description":"Whether this field is importable in Enginy."},"exportable":{"type":"boolean","description":"Whether this field is exportable in Enginy."},"promptReference":{"type":"string","description":"Copy-paste-ready placeholder syntax for prompts. Example: `{firstName}`."}},"required":["id","label","fieldType","entity","dataType","editable","searchable","sortable","importable","exportable","promptReference"]},"description":"Field metadata available for this entity."}},"required":["entity","fields"]}},"required":["status","message","data"]}}}}}}},"/v1/companies/fields":{"get":{"summary":"Get company field metadata","description":"Retrieve the company fields you can reference in prompts and request through the companies endpoints..\n\n    > **Required scope:** `COMPANIES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Companies","AI Variables"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Company field metadata retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Entity these fields belong to."},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Exact field identifier used in prompts (`{fieldName}`) and `fields` query params across the entity endpoints."},"label":{"type":"string","description":"Human-readable field label."},"fieldType":{"type":"string","enum":["STANDARD","AI_VARIABLE","CRM_FIELD","FORMULA_FIELD","EMPTY_FIELD"],"description":"Whether this is a standard field or a smart field type."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Entity the field belongs to."},"dataType":{"type":"string","description":"Underlying data type."},"editable":{"type":"boolean","description":"Whether this field is editable via the entity update endpoint."},"searchable":{"type":"boolean","description":"Whether this field is searchable in Enginy."},"sortable":{"type":"boolean","description":"Whether this field is sortable in Enginy."},"importable":{"type":"boolean","description":"Whether this field is importable in Enginy."},"exportable":{"type":"boolean","description":"Whether this field is exportable in Enginy."},"promptReference":{"type":"string","description":"Copy-paste-ready placeholder syntax for prompts. Example: `{firstName}`."}},"required":["id","label","fieldType","entity","dataType","editable","searchable","sortable","importable","exportable","promptReference"]},"description":"Field metadata available for this entity."}},"required":["entity","fields"]}},"required":["status","message","data"]}}}}}}},"/v1/ai-variables":{"get":{"summary":"List AI variables","description":"Retrieve a paginated list of AI variables.\n\nUse this endpoint to browse the AI variables that appear in the platform AI Variables page. By default archived variables are excluded..\n\n    > **Required scope:** `AI_VARIABLES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","default":"1","description":"Page number for pagination. Minimum value is 1. Defaults to 1."},"required":false,"description":"Page number for pagination. Minimum value is 1. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"string","default":"25","description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25."},"required":false,"description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25.","name":"pageSize","in":"query"},{"schema":{"type":"string","description":"Optional case-insensitive search over AI variable names."},"required":false,"description":"Optional case-insensitive search over AI variable names.","name":"search","in":"query"},{"schema":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Filter AI variables by entity type."},"required":false,"description":"Filter AI variables by entity type.","name":"entity","in":"query"},{"schema":{"type":"string","description":"Filter AI variables by folder ID."},"required":false,"description":"Filter AI variables by folder ID.","name":"folderId","in":"query"},{"schema":{"type":"string","description":"Set to `true` to include archived AI variables. Defaults to false."},"required":false,"description":"Set to `true` to include archived AI variables. Defaults to false.","name":"includeArchived","in":"query"}],"responses":{"200":{"description":"Successful response with paginated AI variables","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the AI variable."},"name":{"type":"string","description":"Unique AI variable name. Use this exact name in prompts and entity field requests."},"prompt":{"type":"string","description":"Plain-text prompt template. Field references use the `{fieldName}` syntax."},"model":{"type":["string","null"],"description":"Model ID used to run the variable. If omitted on create, Enginy uses the default AI model."},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["text","number","date","oneOf","url","email"],"description":"Controls the output format Enginy expects from the AI variable."},"values":{"type":"array","items":{"type":"string"},"description":"Required when `type` is `oneOf`. Lists the allowed values the model should return."},"provideExplanation":{"type":"boolean","description":"When true, Enginy also stores an explanation alongside the generated value."},"jsonSchema":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}],"description":"Advanced JSON schema override used by some structured-output AI variables."}},"required":["type"],"additionalProperties":false,"description":"Output contract for the AI variable."},"search":{"type":"boolean","description":"Enable or disable Deep Search for this AI variable. This is the only public search option."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Which entity stores the resulting value."},"folderId":{"type":["number","null"],"description":"Folder ID used to organize the AI variable."},"customWebsiteField":{"type":["string","null"],"description":"Optional custom website source field used by variables that crawl a specific website field."},"description":{"type":["string","null"],"description":"Auto-generated variable description, when available."},"isPublic":{"type":"boolean","description":"Whether the AI variable is globally public inside Enginy."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"Archive timestamp. Archived variables are excluded from list results unless requested."},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp."},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp."}},"required":["id","name","prompt","model","outputSchema","search","entity","folderId","customWebsiteField","description","isPublic","archivedAt","createdAt","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}},"post":{"summary":"Create an AI variable","description":"Create a new AI variable.\n\nEnginy automatically converts `prompt` into the internal editor format used by the platform..\n\n    > **Required scope:** `AI_VARIABLES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Unique AI variable name."},"prompt":{"type":"string","minLength":1,"description":"Prompt template. Reference entity fields with `{fieldName}` placeholders. Use `GET /v1/contacts/fields` or `GET /v1/companies/fields` to discover valid field names."},"model":{"type":["string","null"],"description":"Optional model ID. Defaults to Enginy’s default AI model."},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["text","number","date","oneOf","url","email"],"description":"Controls the output format Enginy expects from the AI variable."},"values":{"type":"array","items":{"type":"string"},"description":"Required when `type` is `oneOf`. Lists the allowed values the model should return."},"provideExplanation":{"type":"boolean","description":"When true, Enginy also stores an explanation alongside the generated value."},"jsonSchema":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}],"description":"Advanced JSON schema override used by some structured-output AI variables."}},"default":{"type":"text","provideExplanation":false},"required":["type"],"additionalProperties":false,"description":"Optional output contract. Defaults to `{ \"type\": \"text\", \"provideExplanation\": false }`."},"search":{"type":"boolean","default":false,"description":"Enable Deep Search for this AI variable. Defaults to `false`."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Entity that will store the generated value."},"folderId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Optional folder ID."},"customWebsiteField":{"type":["string","null"],"description":"Optional custom website field source."}},"required":["name","prompt","entity"],"additionalProperties":false},"examples":{"contactVariable":{"summary":"Create a contact AI variable","value":{"name":"iceBreaker","entity":"CONTACT","prompt":"Write a short ice breaker using {firstName}, {jobTitle}, {companyName}, and {lastLinkedInPost}.","outputSchema":{"type":"text","provideExplanation":true},"search":true}},"companyVariable":{"summary":"Create a company AI variable with categorical output","value":{"name":"accountPriority","entity":"COMPANY","prompt":"Classify {name} as High, Medium, or Low priority based on {industry}, {numberOfEmployees}, and {openJobPositions}.","outputSchema":{"type":"oneOf","values":["High","Medium","Low"]},"search":true}}}}}},"responses":{"201":{"description":"AI variable created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the AI variable."},"name":{"type":"string","description":"Unique AI variable name. Use this exact name in prompts and entity field requests."},"prompt":{"type":"string","description":"Plain-text prompt template. Field references use the `{fieldName}` syntax."},"model":{"type":["string","null"],"description":"Model ID used to run the variable. If omitted on create, Enginy uses the default AI model."},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["text","number","date","oneOf","url","email"],"description":"Controls the output format Enginy expects from the AI variable."},"values":{"type":"array","items":{"type":"string"},"description":"Required when `type` is `oneOf`. Lists the allowed values the model should return."},"provideExplanation":{"type":"boolean","description":"When true, Enginy also stores an explanation alongside the generated value."},"jsonSchema":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}],"description":"Advanced JSON schema override used by some structured-output AI variables."}},"required":["type"],"additionalProperties":false,"description":"Output contract for the AI variable."},"search":{"type":"boolean","description":"Enable or disable Deep Search for this AI variable. This is the only public search option."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Which entity stores the resulting value."},"folderId":{"type":["number","null"],"description":"Folder ID used to organize the AI variable."},"customWebsiteField":{"type":["string","null"],"description":"Optional custom website source field used by variables that crawl a specific website field."},"description":{"type":["string","null"],"description":"Auto-generated variable description, when available."},"isPublic":{"type":"boolean","description":"Whether the AI variable is globally public inside Enginy."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"Archive timestamp. Archived variables are excluded from list results unless requested."},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp."},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp."}},"required":["id","name","prompt","model","outputSchema","search","entity","folderId","customWebsiteField","description","isPublic","archivedAt","createdAt","updatedAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid input or folder/entity mismatch"},"409":{"description":"Conflict - AI variable name already exists for this entity"}}}},"/v1/ai-variables/{aiVariableId}":{"get":{"summary":"Get an AI variable","description":"Retrieve a single AI variable by ID..\n\n    > **Required scope:** `AI_VARIABLES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The AI variable ID"},"required":true,"description":"The AI variable ID","name":"aiVariableId","in":"path"}],"responses":{"200":{"description":"AI variable retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the AI variable."},"name":{"type":"string","description":"Unique AI variable name. Use this exact name in prompts and entity field requests."},"prompt":{"type":"string","description":"Plain-text prompt template. Field references use the `{fieldName}` syntax."},"model":{"type":["string","null"],"description":"Model ID used to run the variable. If omitted on create, Enginy uses the default AI model."},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["text","number","date","oneOf","url","email"],"description":"Controls the output format Enginy expects from the AI variable."},"values":{"type":"array","items":{"type":"string"},"description":"Required when `type` is `oneOf`. Lists the allowed values the model should return."},"provideExplanation":{"type":"boolean","description":"When true, Enginy also stores an explanation alongside the generated value."},"jsonSchema":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}],"description":"Advanced JSON schema override used by some structured-output AI variables."}},"required":["type"],"additionalProperties":false,"description":"Output contract for the AI variable."},"search":{"type":"boolean","description":"Enable or disable Deep Search for this AI variable. This is the only public search option."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Which entity stores the resulting value."},"folderId":{"type":["number","null"],"description":"Folder ID used to organize the AI variable."},"customWebsiteField":{"type":["string","null"],"description":"Optional custom website source field used by variables that crawl a specific website field."},"description":{"type":["string","null"],"description":"Auto-generated variable description, when available."},"isPublic":{"type":"boolean","description":"Whether the AI variable is globally public inside Enginy."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"Archive timestamp. Archived variables are excluded from list results unless requested."},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp."},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp."}},"required":["id","name","prompt","model","outputSchema","search","entity","folderId","customWebsiteField","description","isPublic","archivedAt","createdAt","updatedAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid aiVariableId parameter"},"404":{"description":"AI variable not found"}}},"patch":{"summary":"Update an AI variable","description":"Update an existing AI variable.\n\nWhen `prompt` is updated, Enginy regenerates the internal editor format from the new prompt text..\n\n    > **Required scope:** `AI_VARIABLES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The AI variable ID"},"required":true,"description":"The AI variable ID","name":"aiVariableId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"New AI variable name."},"prompt":{"type":"string","minLength":1,"description":"New prompt template. Enginy regenerates the internal prompt representation from this value. Use `GET /v1/contacts/fields` or `GET /v1/companies/fields` to discover valid field names."},"model":{"type":["string","null"],"description":"Optional new model ID."},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["text","number","date","oneOf","url","email"],"description":"Controls the output format Enginy expects from the AI variable."},"values":{"type":"array","items":{"type":"string"},"description":"Required when `type` is `oneOf`. Lists the allowed values the model should return."},"provideExplanation":{"type":"boolean","description":"When true, Enginy also stores an explanation alongside the generated value."},"jsonSchema":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}],"description":"Advanced JSON schema override used by some structured-output AI variables."}},"required":["type"],"additionalProperties":false,"description":"Optional new output contract."},"search":{"type":"boolean","description":"Enable or disable Deep Search."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Optional new entity."},"folderId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Optional new folder ID."},"customWebsiteField":{"type":["string","null"],"description":"Optional new custom website field source."}},"additionalProperties":false},"examples":{"updatePrompt":{"summary":"Update the prompt and Deep Search toggle","value":{"prompt":"Summarize why {firstName} at {companyName} is relevant based on {jobTitle} and {lastLinkedInPost}.","search":true}},"moveEntityFolder":{"summary":"Move a variable to a folder","value":{"folderId":42}}}}}},"responses":{"200":{"description":"AI variable updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the AI variable."},"name":{"type":"string","description":"Unique AI variable name. Use this exact name in prompts and entity field requests."},"prompt":{"type":"string","description":"Plain-text prompt template. Field references use the `{fieldName}` syntax."},"model":{"type":["string","null"],"description":"Model ID used to run the variable. If omitted on create, Enginy uses the default AI model."},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["text","number","date","oneOf","url","email"],"description":"Controls the output format Enginy expects from the AI variable."},"values":{"type":"array","items":{"type":"string"},"description":"Required when `type` is `oneOf`. Lists the allowed values the model should return."},"provideExplanation":{"type":"boolean","description":"When true, Enginy also stores an explanation alongside the generated value."},"jsonSchema":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}],"description":"Advanced JSON schema override used by some structured-output AI variables."}},"required":["type"],"additionalProperties":false,"description":"Output contract for the AI variable."},"search":{"type":"boolean","description":"Enable or disable Deep Search for this AI variable. This is the only public search option."},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Which entity stores the resulting value."},"folderId":{"type":["number","null"],"description":"Folder ID used to organize the AI variable."},"customWebsiteField":{"type":["string","null"],"description":"Optional custom website source field used by variables that crawl a specific website field."},"description":{"type":["string","null"],"description":"Auto-generated variable description, when available."},"isPublic":{"type":"boolean","description":"Whether the AI variable is globally public inside Enginy."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"Archive timestamp. Archived variables are excluded from list results unless requested."},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp."},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp."}},"required":["id","name","prompt","model","outputSchema","search","entity","folderId","customWebsiteField","description","isPublic","archivedAt","createdAt","updatedAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid input or folder/entity mismatch"},"404":{"description":"AI variable not found"},"409":{"description":"Conflict - AI variable name already exists for this entity"}}},"delete":{"summary":"Delete an AI variable","description":"Delete an AI variable and its generated smart-field values..\n\n    > **Required scope:** `AI_VARIABLES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["AI Variables"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The AI variable ID"},"required":true,"description":"The AI variable ID","name":"aiVariableId","in":"path"}],"responses":{"200":{"description":"AI variable deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"deleted":{"type":"boolean"}},"required":["id","deleted"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid aiVariableId parameter"},"404":{"description":"AI variable not found"}}}},"/v1/identities":{"get":{"summary":"Get identities","description":"Retrieve a paginated list of identities.\n\n    > **Required scope:** `IDENTITIES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Identities"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","default":"1","description":"Page number for pagination. Minimum value is 1. Defaults to 1."},"required":false,"description":"Page number for pagination. Minimum value is 1. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"string","default":"25","description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25."},"required":false,"description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25.","name":"pageSize","in":"query"},{"schema":{"type":"string","description":"Search term to filter identities by name (case-insensitive)."},"required":false,"description":"Search term to filter identities by name (case-insensitive).","name":"search","in":"query"}],"responses":{"200":{"description":"Successful response with paginated identities","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the identity"},"name":{"type":["string","null"],"description":"Full name of the identity"},"firstName":{"type":["string","null"],"description":"First name of the identity"},"lastName":{"type":["string","null"],"description":"Last name of the identity"},"jobTitle":{"type":["string","null"],"description":"Job title of the identity"},"email":{"type":["string","null"],"description":"Email address of the identity"},"emails":{"type":"array","items":{"type":"string"},"description":"All mailbox email addresses associated with the identity"},"linkedInUrl":{"type":["string","null"],"description":"LinkedIn profile URL of the identity"},"timezone":{"type":["string","null"],"description":"Timezone of the identity"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the identity was created"}},"required":["id","name","firstName","lastName","jobTitle","email","emails","linkedInUrl","timezone","createdAt"]}},"pagination":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"},"totalPages":{"type":"number"}},"required":["page","pageSize","total","totalPages"]}},"required":["status","data","pagination"]}}}}}}},"/v1/identities/performance":{"get":{"summary":"Get identity performance metrics","description":"Retrieve identity performance metrics for a date range.\n\n    > **Required scope:** `IDENTITIES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Identities"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Start date in ISO 8601 format."},"required":true,"description":"Start date in ISO 8601 format.","name":"startDate","in":"query"},{"schema":{"type":"string","description":"End date in ISO 8601 format (must be after startDate)."},"required":true,"description":"End date in ISO 8601 format (must be after startDate).","name":"endDate","in":"query"},{"schema":{"type":"string","enum":["day","week","month"],"description":"Time grouping for metrics. Defaults to day."},"required":false,"description":"Time grouping for metrics. Defaults to day.","name":"granularity","in":"query"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Optional identity IDs (comma-separated string or repeated query parameter)."},"required":false,"description":"Optional identity IDs (comma-separated string or repeated query parameter).","name":"identityIds","in":"query"}],"responses":{"200":{"description":"Successful response with identity performance metrics","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time"},"granularity":{"type":"string","enum":["day","week","month"]},"identities":{"type":"array","items":{"type":"object","properties":{"identityId":{"type":"number","description":"Identity ID."},"identityName":{"type":["string","null"],"description":"Identity display name."},"identityEmail":{"type":["string","null"],"description":"Identity email."},"totals":{"type":"object","properties":{"emailsSent":{"type":"number","description":"Total emails sent in the selected period."},"linkedinActions":{"type":"object","properties":{"connectionRequests":{"type":"number","description":"Total LinkedIn connection requests sent."},"messages":{"type":"number","description":"Total LinkedIn messages sent."},"profileViews":{"type":"number","description":"Total LinkedIn profile view actions executed."},"postLikes":{"type":"number","description":"Total LinkedIn post like actions executed."},"total":{"type":"number","description":"Total LinkedIn actions across all action types."}},"required":["connectionRequests","messages","profileViews","postLikes","total"],"description":"Total LinkedIn actions in the selected period."}},"required":["emailsSent","linkedinActions"]},"timeSeries":{"type":"array","items":{"type":"object","properties":{"periodStart":{"type":"string","format":"date-time","description":"Bucket start timestamp based on selected granularity."},"emailsSent":{"type":"number","description":"Emails sent during this time bucket."},"linkedinActions":{"type":"object","properties":{"connectionRequests":{"type":"number","description":"Total LinkedIn connection requests sent."},"messages":{"type":"number","description":"Total LinkedIn messages sent."},"profileViews":{"type":"number","description":"Total LinkedIn profile view actions executed."},"postLikes":{"type":"number","description":"Total LinkedIn post like actions executed."},"total":{"type":"number","description":"Total LinkedIn actions across all action types."}},"required":["connectionRequests","messages","profileViews","postLikes","total"],"description":"LinkedIn action counts during this time bucket."}},"required":["periodStart","emailsSent","linkedinActions"]},"description":"Performance buckets over time."}},"required":["identityId","identityName","identityEmail","totals","timeSeries"]}}},"required":["startDate","endDate","granularity","identities"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid query parameters"}}}},"/v1/identities/{identityId}/mailboxes":{"get":{"summary":"Get identity mailboxes","description":"Retrieve all configured mailboxes for a specific identity.\n\n    > **Required scope:** `IDENTITIES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Identities"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The identity ID whose mailboxes should be returned."},"required":true,"description":"The identity ID whose mailboxes should be returned.","name":"identityId","in":"path"}],"responses":{"200":{"description":"Successful response with the identity mailboxes","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"identityId":{"type":"number"},"mailboxes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the mailbox"},"identityId":{"type":"number","description":"Identity ID that owns the mailbox"},"email":{"type":"string","description":"Mailbox email address"},"provider":{"type":"string","enum":["google","microsoft","imap","unknown"],"description":"Mailbox provider inferred from the configured credentials"},"isPrimary":{"type":"boolean","description":"Whether this mailbox matches the identity primary email field"},"emailCredentialsExpired":{"type":"boolean","description":"Whether the stored mailbox credentials are expired"},"healthStatus":{"type":"string","enum":["healthy","credentials_expired","missing_credentials"],"description":"High-level mailbox credential health"},"warmup":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether warmup is configured for this mailbox"},"mailboxId":{"type":["number","null"],"description":"Warmup mailbox identifier when configured"}},"required":["enabled","mailboxId"]}},"required":["id","identityId","email","provider","isPrimary","emailCredentialsExpired","healthStatus","warmup"]}}},"required":["identityId","mailboxes"]}},"required":["status","message","data"]}}}},"404":{"description":"Identity not found"}}},"post":{"summary":"Create or update an identity mailbox","description":"Create or update an IMAP mailbox for a specific identity so mailbox setup can be automated over API. Programmatic setup currently supports IMAP credentials only..\n\n    > **Required scope:** `ALL`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Identities"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The identity ID that will own the mailbox."},"required":true,"description":"The identity ID that will own the mailbox.","name":"identityId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Mailbox email address"},"provider":{"type":"string","enum":["imap"],"description":"Mailbox provider. Programmatic setup currently supports IMAP mailboxes only."},"credentials":{"type":"object","properties":{"password":{"type":"string","minLength":1,"description":"Mailbox password or app password"},"imapHost":{"type":"string","minLength":1,"description":"IMAP hostname"},"imapPort":{"type":"integer","minimum":1,"maximum":65535,"description":"IMAP port"},"smtpHost":{"type":"string","minLength":1,"description":"SMTP hostname"},"smtpPort":{"type":"integer","minimum":1,"maximum":65535,"description":"SMTP port"}},"required":["password","imapHost","imapPort","smtpHost","smtpPort"]},"makePrimary":{"type":"boolean","default":false,"description":"When true, also updates the identity primary email to this mailbox address."}},"required":["email","provider","credentials"]}}}},"responses":{"200":{"description":"Mailbox updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the mailbox"},"identityId":{"type":"number","description":"Identity ID that owns the mailbox"},"email":{"type":"string","description":"Mailbox email address"},"provider":{"type":"string","enum":["google","microsoft","imap","unknown"],"description":"Mailbox provider inferred from the configured credentials"},"isPrimary":{"type":"boolean","description":"Whether this mailbox matches the identity primary email field"},"emailCredentialsExpired":{"type":"boolean","description":"Whether the stored mailbox credentials are expired"},"healthStatus":{"type":"string","enum":["healthy","credentials_expired","missing_credentials"],"description":"High-level mailbox credential health"},"warmup":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether warmup is configured for this mailbox"},"mailboxId":{"type":["number","null"],"description":"Warmup mailbox identifier when configured"}},"required":["enabled","mailboxId"]}},"required":["id","identityId","email","provider","isPrimary","emailCredentialsExpired","healthStatus","warmup"]}},"required":["status","message","data"]}}}},"201":{"description":"Mailbox created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the mailbox"},"identityId":{"type":"number","description":"Identity ID that owns the mailbox"},"email":{"type":"string","description":"Mailbox email address"},"provider":{"type":"string","enum":["google","microsoft","imap","unknown"],"description":"Mailbox provider inferred from the configured credentials"},"isPrimary":{"type":"boolean","description":"Whether this mailbox matches the identity primary email field"},"emailCredentialsExpired":{"type":"boolean","description":"Whether the stored mailbox credentials are expired"},"healthStatus":{"type":"string","enum":["healthy","credentials_expired","missing_credentials"],"description":"High-level mailbox credential health"},"warmup":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether warmup is configured for this mailbox"},"mailboxId":{"type":["number","null"],"description":"Warmup mailbox identifier when configured"}},"required":["enabled","mailboxId"]}},"required":["id","identityId","email","provider","isPrimary","emailCredentialsExpired","healthStatus","warmup"]}},"required":["status","message","data"]}}}},"404":{"description":"Identity not found"},"409":{"description":"Mailbox already belongs to another active identity"},"422":{"description":"Mailbox credentials are invalid or the identity exceeded mailbox limits"}}}},"/v1/campaigns/folders":{"get":{"summary":"List campaign folders","description":"List campaign folders. By default this returns only root folders. Use `includeChildren=true` to return nested folders too..\n\n    > **Required scope:** `CAMPAIGNS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes nested folders instead of returning only root folders."},"required":false,"description":"When `true`, includes nested folders instead of returning only root folders.","name":"includeChildren","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes recursive subfolder and campaign counts."},"required":false,"description":"When `true`, includes recursive subfolder and campaign counts.","name":"includeRecursiveCounts","in":"query"}],"responses":{"200":{"description":"Campaign folders retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"campaignsCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalCampaignsCount":{"type":"number"}},"required":["id","name","parentId","createdAt","updatedAt","campaignsCount","subfoldersCount"]}}},"required":["status","message","data"]}}}}}},"post":{"summary":"Create campaign folder","description":"Create a campaign folder. Folder names must be unique within the same parent folder..\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Optional parent folder ID."}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Campaign folder created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}}},"/v1/campaigns/folders/{folderId}":{"get":{"summary":"Get campaign folder","description":"Get a campaign folder with its child folders, campaigns, and breadcrumb ancestors..\n\n    > **Required scope:** `CAMPAIGNS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Campaign folder ID"},"required":true,"description":"Campaign folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Campaign folder retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"campaignsCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalCampaignsCount":{"type":"number"},"children":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"_count":{"type":"object","properties":{"campaign":{"type":"number"},"children":{"type":"number"}},"required":["campaign","children"]}},"required":["id","name","_count"]}},"parent":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"campaign":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"description":{"type":["string","null"]},"folderId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"_count":{"type":"object","properties":{"conversation":{"type":"number"}},"required":["conversation"]}},"required":["id","name","description","folderId","createdAt","updatedAt","createdBy","_count"]}},"ancestors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]}},"required":["id","name","parentId"]}}},"required":["id","name","parentId","createdAt","updatedAt","campaignsCount","subfoldersCount","children","parent","campaign","ancestors"]}},"required":["status","message","data"]}}}},"404":{"description":"Folder not found"}}},"patch":{"summary":"Update campaign folder","description":"Update a campaign folder name or parent. Moving a folder into one of its descendants is not allowed..\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Campaign folder ID"},"required":true,"description":"Campaign folder ID","name":"folderId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Updated folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Updated parent folder ID or `null` to move to root."}},"additionalProperties":false}}}},"responses":{"200":{"description":"Campaign folder updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}},"delete":{"summary":"Delete campaign folder","description":"Delete a campaign folder. Descendant folders are deleted too. Campaigns inside the deleted folders are not deleted; they are unassigned from the folder hierarchy..\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Campaign folder ID"},"required":true,"description":"Campaign folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Campaign folder deleted successfully"}}}},"/v1/campaigns":{"post":{"summary":"Create campaign","description":"Create a draft campaign from a simplified high-level sequence.\n\nCreate a draft campaign from the public `steps` format.\n\nHow to structure the request:\n- Start `steps` with the first action that should happen.\n- Keep adding the next action in the order it should run.\n- Use `condition` when you want to branch on lead data.\n- Use `linkedin_connection` when you want to branch on connection acceptance after sending a connection request.\n- Put shared follow-up work after the branching step instead of duplicating the same steps inside both branches.\n\nBefore you send a request:\n- Send an ordered `steps` array that describes the campaign flow from first action to last action.\n- Use branch arrays on `condition` and `linkedin_connection` steps to describe branch-specific work.\n- Place shared follow-up steps after a branching step when both live branches should continue together.\n- `waitForAcceptance.unit` must be `days` and `waitForAcceptance.value` must be an integer greater than or equal to `1`.\n- Use `GET /v1/tasks/owners` first when your campaign includes `task` steps. If owners are returned, every `task` step must include `ownerId`.\n- Validation errors use full paths like `steps[0].onTrue[1].subject` so nested input issues are easy to fix.\n- Personalization placeholders use Enginy single-brace syntax such as `{firstName}`, `{company}`, and `{identity.name}`. Do not send Handlebars-style placeholders like `{{firstName}}`.\n\nSupported `condition.type` values:\n- `has_linkedin_profile`: `onTrue` runs when the lead has a LinkedIn profile.\n- `has_professional_email`: `onTrue` runs when the lead has a professional email.\n- `is_already_connected`: `onTrue` runs when the lead is already a LinkedIn connection.\n- `has_been_contacted`: `onTrue` runs when the lead has already been contacted.\n\nBranch fields:\n- `condition` uses `onTrue` and `onFalse`.\n- `linkedin_connection` uses `onAccepted` and `onNotAccepted`.\n- Use `[{ \"type\": \"end\" }]` when a branch should stop explicitly.\n\nFor examples and a full step-by-step guide, see `/api-reference/campaigns-guide` in the docs site..\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Campaign name."},"description":{"type":["string","null"],"description":"Optional campaign description."},"identityId":{"type":["integer","null"],"exclusiveMinimum":0},"shouldAutomaticallySend":{"type":"boolean"},"shouldSendTrackingPixel":{"type":"boolean"},"shouldTrackEmailLinks":{"type":"boolean"},"excludeContactedLeads":{"type":"boolean"},"allowedEmails":{"type":"array","items":{"type":"string","format":"email"}},"steps":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"subject":{"type":"string","minLength":1},"content":{"type":"string","minLength":1},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","subject","content"],"additionalProperties":false,"title":"email"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_message"]},"content":{"type":"string","minLength":1},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","content"],"additionalProperties":false,"title":"linkedin_message"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_inmail"]},"subject":{"type":"string","minLength":1},"content":{"type":"string","minLength":1},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","subject","content"],"additionalProperties":false,"title":"linkedin_inmail"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_visit_profile"]},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type"],"additionalProperties":false,"title":"linkedin_visit_profile"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_like_last_post"]},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false},"reactionType":{"type":"string","minLength":1}},"required":["type"],"additionalProperties":false,"title":"linkedin_like_last_post"},{"type":"object","properties":{"type":{"type":"string","enum":["condition"]},"condition":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["has_linkedin_profile"],"description":"Lead has a LinkedIn profile."}},"required":["type"],"additionalProperties":false,"title":"has_linkedin_profile"},{"type":"object","properties":{"type":{"type":"string","enum":["has_professional_email"],"description":"Lead has a professional email."}},"required":["type"],"additionalProperties":false,"title":"has_professional_email"},{"type":"object","properties":{"type":{"type":"string","enum":["is_already_connected"],"description":"Lead is already a LinkedIn connection."}},"required":["type"],"additionalProperties":false,"title":"is_already_connected"},{"type":"object","properties":{"type":{"type":"string","enum":["has_been_contacted"],"description":"Lead has already been contacted."}},"required":["type"],"additionalProperties":false,"title":"has_been_contacted"}],"description":"Condition evaluated at this point in the sequence. Supported `condition.type` values are `has_linkedin_profile`, `has_professional_email`, `is_already_connected`, and `has_been_contacted`."},"onTrue":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Steps to run when the condition matches. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."},"onFalse":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Steps to run when the condition does not match. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."}},"required":["type","condition"],"additionalProperties":false,"title":"condition"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_connection"]},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false},"content":{"type":"string","minLength":1},"waitForAcceptance":{"type":"object","properties":{"value":{"type":"integer","minimum":1,"description":"whole number of days to wait. Minimum 1 day."},"unit":{"type":"string","enum":["days"],"description":"Connection wait unit. Must be `days`."}},"required":["value","unit"],"additionalProperties":false},"onAccepted":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Accepted branch steps. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."},"onNotAccepted":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Not-accepted branch steps. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."}},"required":["type","waitForAcceptance"],"additionalProperties":false,"title":"linkedin_connection"},{"type":"object","properties":{"type":{"type":"string","enum":["task"]},"taskType":{"type":"string","minLength":1},"title":{"type":"string","minLength":1,"description":"Required task title shown in the UI."},"note":{"type":"string","minLength":1,"description":"Optional task note shown in the UI."},"ownerId":{"type":["string","null"],"minLength":1,"description":"Required when `GET /v1/tasks/owners` returns one or more owners."},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","taskType","title"],"additionalProperties":false,"title":"task"},{"type":"object","properties":{"type":{"type":"string","enum":["end"]}},"required":["type"],"additionalProperties":false,"title":"end"}]},"minItems":1,"description":"Ordered campaign steps. Use branch arrays like `onTrue`, `onFalse`, `onAccepted`, and `onNotAccepted` for branching."}},"required":["name","steps"],"additionalProperties":false},"examples":{"conditionFirst":{"summary":"Start with a condition and run different work on each branch","value":{"name":"Email or fallback task","identityId":323,"steps":[{"type":"condition","condition":{"type":"has_professional_email"},"onTrue":[{"type":"email","subject":"Great to connect","content":"Sharing a quick overview."}],"onFalse":[{"type":"task","taskType":"TODO","title":"Find email first","ownerId":"owner-1"}]}]}},"linkedinAcceptance":{"summary":"Branch on LinkedIn connection acceptance and continue after the branch","value":{"name":"LinkedIn acceptance flow","identityId":323,"steps":[{"type":"linkedin_connection","delay":{"value":1,"unit":"days"},"waitForAcceptance":{"value":5,"unit":"days"},"onAccepted":[{"type":"linkedin_message","content":"Thanks for accepting.","delay":{"value":2,"unit":"hours"}}],"onNotAccepted":[{"type":"task","taskType":"TODO","title":"Review no-response path","ownerId":"owner-1"}]},{"type":"email","subject":"Following up","content":"Continuing after the LinkedIn decision.","delay":{"value":1,"unit":"days"}}]}},"taskRoutingFallbacks":{"summary":"Route multiple fallback branches into different task owners","value":{"name":"Task routing fallback flow","identityId":323,"steps":[{"type":"condition","condition":{"type":"has_professional_email"},"onTrue":[{"type":"email","subject":"Initial outreach","content":"Opening with email when contact data is ready."},{"type":"linkedin_connection","waitForAcceptance":{"value":4,"unit":"days"},"onAccepted":[{"type":"task","taskType":"CALL","title":"Call after positive signal","note":"They accepted the connection and saw the first email.","ownerId":"owner-1","delay":{"value":1,"unit":"days"}}],"onNotAccepted":[{"type":"task","taskType":"TODO","title":"Review cold branch manually","ownerId":"owner-2"}]}],"onFalse":[{"type":"task","taskType":"TODO","title":"Find email before launching sequence","ownerId":"owner-3"}]}]}}}}}},"responses":{"201":{"description":"Campaign created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Created campaign ID."},"name":{"type":"string","description":"Created campaign name."},"status":{"type":"string","enum":["DRAFT","PENDING","ACTIVE","COMPLETED","DELETED"],"description":"Created campaign status."},"identityId":{"type":["number","null"],"description":"Assigned sender identity ID."},"warnings":{"type":"array","items":{"type":"string"},"description":"Non-blocking sequence warnings returned by shared campaign validation."}},"required":["id","name","status","identityId","warnings"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - referenced identity is invalid"},"422":{"description":"Unprocessable entity - the campaign steps are invalid"}}},"get":{"summary":"Get campaigns","description":"Retrieve a paginated list of campaigns.\n\n    > **Required scope:** `CAMPAIGNS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","default":"1","description":"Page number for pagination. Minimum value is 1. Defaults to 1."},"required":false,"description":"Page number for pagination. Minimum value is 1. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"string","default":"25","description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25."},"required":false,"description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25.","name":"pageSize","in":"query"},{"schema":{"type":"string","description":"Search term to filter campaigns by name (case-insensitive)."},"required":false,"description":"Search term to filter campaigns by name (case-insensitive).","name":"search","in":"query"},{"schema":{"type":"string","description":"Filter campaigns by sender identity ID."},"required":false,"description":"Filter campaigns by sender identity ID.","name":"identitySenderId","in":"query"},{"schema":{"type":"string","enum":["ACTIVE","PENDING","DRAFT","COMPLETED"],"description":"Filter campaigns by status."},"required":false,"description":"Filter campaigns by status.","name":"status","in":"query"}],"responses":{"200":{"description":"Successful response with paginated campaigns","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the campaign"},"name":{"type":"string","description":"Name of the campaign"},"description":{"type":["string","null"],"description":"Description of the campaign"},"status":{"type":"string","enum":["DRAFT","PENDING","ACTIVE","COMPLETED","DELETED"],"description":"Status of the campaign"},"createdBy":{"type":"object","properties":{"id":{"type":"number","description":"ID of the user who created the campaign"},"name":{"type":["string","null"],"description":"Name of the user who created the campaign"}},"required":["id","name"],"description":"User who created the campaign"},"crmOwnerId":{"type":["string","null"],"description":"CRM owner associated with the campaign"},"senderIdentity":{"type":["object","null"],"properties":{"id":{"type":"number","description":"ID of the sender identity"},"name":{"type":["string","null"],"description":"Name of the sender identity"}},"required":["id","name"],"description":"Identity being used to send from"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the campaign was created"}},"required":["id","name","description","status","createdBy","crmOwnerId","senderIdentity","createdAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}}},"/v1/campaigns/validate":{"post":{"summary":"Validate campaign","description":"Validate a simplified campaign payload without creating a campaign.\n\nCreate a draft campaign from the public `steps` format.\n\nHow to structure the request:\n- Start `steps` with the first action that should happen.\n- Keep adding the next action in the order it should run.\n- Use `condition` when you want to branch on lead data.\n- Use `linkedin_connection` when you want to branch on connection acceptance after sending a connection request.\n- Put shared follow-up work after the branching step instead of duplicating the same steps inside both branches.\n\nBefore you send a request:\n- Send an ordered `steps` array that describes the campaign flow from first action to last action.\n- Use branch arrays on `condition` and `linkedin_connection` steps to describe branch-specific work.\n- Place shared follow-up steps after a branching step when both live branches should continue together.\n- `waitForAcceptance.unit` must be `days` and `waitForAcceptance.value` must be an integer greater than or equal to `1`.\n- Use `GET /v1/tasks/owners` first when your campaign includes `task` steps. If owners are returned, every `task` step must include `ownerId`.\n- Validation errors use full paths like `steps[0].onTrue[1].subject` so nested input issues are easy to fix.\n- Personalization placeholders use Enginy single-brace syntax such as `{firstName}`, `{company}`, and `{identity.name}`. Do not send Handlebars-style placeholders like `{{firstName}}`.\n\nSupported `condition.type` values:\n- `has_linkedin_profile`: `onTrue` runs when the lead has a LinkedIn profile.\n- `has_professional_email`: `onTrue` runs when the lead has a professional email.\n- `is_already_connected`: `onTrue` runs when the lead is already a LinkedIn connection.\n- `has_been_contacted`: `onTrue` runs when the lead has already been contacted.\n\nBranch fields:\n- `condition` uses `onTrue` and `onFalse`.\n- `linkedin_connection` uses `onAccepted` and `onNotAccepted`.\n- Use `[{ \"type\": \"end\" }]` when a branch should stop explicitly.\n\nFor examples and a full step-by-step guide, see `/api-reference/campaigns-guide` in the docs site..\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Campaign name."},"description":{"type":["string","null"],"description":"Optional campaign description."},"identityId":{"type":["integer","null"],"exclusiveMinimum":0},"shouldAutomaticallySend":{"type":"boolean"},"shouldSendTrackingPixel":{"type":"boolean"},"shouldTrackEmailLinks":{"type":"boolean"},"excludeContactedLeads":{"type":"boolean"},"allowedEmails":{"type":"array","items":{"type":"string","format":"email"}},"steps":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"subject":{"type":"string","minLength":1},"content":{"type":"string","minLength":1},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","subject","content"],"additionalProperties":false,"title":"email"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_message"]},"content":{"type":"string","minLength":1},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","content"],"additionalProperties":false,"title":"linkedin_message"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_inmail"]},"subject":{"type":"string","minLength":1},"content":{"type":"string","minLength":1},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","subject","content"],"additionalProperties":false,"title":"linkedin_inmail"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_visit_profile"]},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type"],"additionalProperties":false,"title":"linkedin_visit_profile"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_like_last_post"]},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false},"reactionType":{"type":"string","minLength":1}},"required":["type"],"additionalProperties":false,"title":"linkedin_like_last_post"},{"type":"object","properties":{"type":{"type":"string","enum":["condition"]},"condition":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["has_linkedin_profile"],"description":"Lead has a LinkedIn profile."}},"required":["type"],"additionalProperties":false,"title":"has_linkedin_profile"},{"type":"object","properties":{"type":{"type":"string","enum":["has_professional_email"],"description":"Lead has a professional email."}},"required":["type"],"additionalProperties":false,"title":"has_professional_email"},{"type":"object","properties":{"type":{"type":"string","enum":["is_already_connected"],"description":"Lead is already a LinkedIn connection."}},"required":["type"],"additionalProperties":false,"title":"is_already_connected"},{"type":"object","properties":{"type":{"type":"string","enum":["has_been_contacted"],"description":"Lead has already been contacted."}},"required":["type"],"additionalProperties":false,"title":"has_been_contacted"}],"description":"Condition evaluated at this point in the sequence. Supported `condition.type` values are `has_linkedin_profile`, `has_professional_email`, `is_already_connected`, and `has_been_contacted`."},"onTrue":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Steps to run when the condition matches. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."},"onFalse":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Steps to run when the condition does not match. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."}},"required":["type","condition"],"additionalProperties":false,"title":"condition"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_connection"]},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false},"content":{"type":"string","minLength":1},"waitForAcceptance":{"type":"object","properties":{"value":{"type":"integer","minimum":1,"description":"whole number of days to wait. Minimum 1 day."},"unit":{"type":"string","enum":["days"],"description":"Connection wait unit. Must be `days`."}},"required":["value","unit"],"additionalProperties":false},"onAccepted":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Accepted branch steps. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."},"onNotAccepted":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Not-accepted branch steps. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."}},"required":["type","waitForAcceptance"],"additionalProperties":false,"title":"linkedin_connection"},{"type":"object","properties":{"type":{"type":"string","enum":["task"]},"taskType":{"type":"string","minLength":1},"title":{"type":"string","minLength":1,"description":"Required task title shown in the UI."},"note":{"type":"string","minLength":1,"description":"Optional task note shown in the UI."},"ownerId":{"type":["string","null"],"minLength":1,"description":"Required when `GET /v1/tasks/owners` returns one or more owners."},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","taskType","title"],"additionalProperties":false,"title":"task"},{"type":"object","properties":{"type":{"type":"string","enum":["end"]}},"required":["type"],"additionalProperties":false,"title":"end"}]},"minItems":1,"description":"Ordered campaign steps. Use branch arrays like `onTrue`, `onFalse`, `onAccepted`, and `onNotAccepted` for branching."}},"required":["name","steps"],"additionalProperties":false},"examples":{"conditionFirst":{"summary":"Start with a condition and run different work on each branch","value":{"name":"Email or fallback task","identityId":323,"steps":[{"type":"condition","condition":{"type":"has_professional_email"},"onTrue":[{"type":"email","subject":"Great to connect","content":"Sharing a quick overview."}],"onFalse":[{"type":"task","taskType":"TODO","title":"Find email first","ownerId":"owner-1"}]}]}},"linkedinAcceptance":{"summary":"Branch on LinkedIn connection acceptance and continue after the branch","value":{"name":"LinkedIn acceptance flow","identityId":323,"steps":[{"type":"linkedin_connection","delay":{"value":1,"unit":"days"},"waitForAcceptance":{"value":5,"unit":"days"},"onAccepted":[{"type":"linkedin_message","content":"Thanks for accepting.","delay":{"value":2,"unit":"hours"}}],"onNotAccepted":[{"type":"task","taskType":"TODO","title":"Review no-response path","ownerId":"owner-1"}]},{"type":"email","subject":"Following up","content":"Continuing after the LinkedIn decision.","delay":{"value":1,"unit":"days"}}]}},"taskRoutingFallbacks":{"summary":"Route multiple fallback branches into different task owners","value":{"name":"Task routing fallback flow","identityId":323,"steps":[{"type":"condition","condition":{"type":"has_professional_email"},"onTrue":[{"type":"email","subject":"Initial outreach","content":"Opening with email when contact data is ready."},{"type":"linkedin_connection","waitForAcceptance":{"value":4,"unit":"days"},"onAccepted":[{"type":"task","taskType":"CALL","title":"Call after positive signal","note":"They accepted the connection and saw the first email.","ownerId":"owner-1","delay":{"value":1,"unit":"days"}}],"onNotAccepted":[{"type":"task","taskType":"TODO","title":"Review cold branch manually","ownerId":"owner-2"}]}],"onFalse":[{"type":"task","taskType":"TODO","title":"Find email before launching sequence","ownerId":"owner-3"}]}]}}}}}},"responses":{"200":{"description":"Campaign payload is valid","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"isValid":{"type":"boolean","enum":[true],"description":"Always true for successful validation responses."},"warnings":{"type":"array","items":{"type":"string"},"description":"Non-blocking sequence warnings returned by shared campaign validation."}},"required":["isValid","warnings"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - referenced identity is invalid"},"422":{"description":"Unprocessable entity - the campaign steps are invalid"}}}},"/v1/campaign/{campaignId}":{"get":{"summary":"Get a single campaign","description":"Retrieve a specific campaign with its simplified sequence and campaign settings.\n\n    > **Required scope:** `CAMPAIGNS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The campaign ID"},"required":true,"description":"The campaign ID","name":"campaignId","in":"path"}],"responses":{"200":{"description":"Campaign retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Campaign name."},"description":{"type":["string","null"],"description":"Optional campaign description."},"identityId":{"type":["integer","null"],"exclusiveMinimum":0},"shouldAutomaticallySend":{"type":"boolean"},"shouldSendTrackingPixel":{"type":"boolean"},"shouldTrackEmailLinks":{"type":"boolean"},"excludeContactedLeads":{"type":"boolean"},"allowedEmails":{"type":"array","items":{"type":"string","format":"email"}},"steps":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"subject":{"type":"string","minLength":1},"content":{"type":"string","minLength":1},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","subject","content"],"additionalProperties":false,"title":"email"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_message"]},"content":{"type":"string","minLength":1},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","content"],"additionalProperties":false,"title":"linkedin_message"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_inmail"]},"subject":{"type":"string","minLength":1},"content":{"type":"string","minLength":1},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","subject","content"],"additionalProperties":false,"title":"linkedin_inmail"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_visit_profile"]},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type"],"additionalProperties":false,"title":"linkedin_visit_profile"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_like_last_post"]},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false},"reactionType":{"type":"string","minLength":1}},"required":["type"],"additionalProperties":false,"title":"linkedin_like_last_post"},{"type":"object","properties":{"type":{"type":"string","enum":["condition"]},"condition":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["has_linkedin_profile"],"description":"Lead has a LinkedIn profile."}},"required":["type"],"additionalProperties":false,"title":"has_linkedin_profile"},{"type":"object","properties":{"type":{"type":"string","enum":["has_professional_email"],"description":"Lead has a professional email."}},"required":["type"],"additionalProperties":false,"title":"has_professional_email"},{"type":"object","properties":{"type":{"type":"string","enum":["is_already_connected"],"description":"Lead is already a LinkedIn connection."}},"required":["type"],"additionalProperties":false,"title":"is_already_connected"},{"type":"object","properties":{"type":{"type":"string","enum":["has_been_contacted"],"description":"Lead has already been contacted."}},"required":["type"],"additionalProperties":false,"title":"has_been_contacted"}],"description":"Condition evaluated at this point in the sequence. Supported `condition.type` values are `has_linkedin_profile`, `has_professional_email`, `is_already_connected`, and `has_been_contacted`."},"onTrue":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Steps to run when the condition matches. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."},"onFalse":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Steps to run when the condition does not match. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."}},"required":["type","condition"],"additionalProperties":false,"title":"condition"},{"type":"object","properties":{"type":{"type":"string","enum":["linkedin_connection"]},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false},"content":{"type":"string","minLength":1},"waitForAcceptance":{"type":"object","properties":{"value":{"type":"integer","minimum":1,"description":"whole number of days to wait. Minimum 1 day."},"unit":{"type":"string","enum":["days"],"description":"Connection wait unit. Must be `days`."}},"required":["value","unit"],"additionalProperties":false},"onAccepted":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Accepted branch steps. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."},"onNotAccepted":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Nested branch step type."}},"required":["type"],"additionalProperties":{},"description":"Nested branch step. Use the same step payload shape as top-level `steps` items."},"minItems":1,"description":"Not-accepted branch steps. If provided, it must contain at least one step. Use `{ \"type\": \"end\" }` to stop that branch explicitly."}},"required":["type","waitForAcceptance"],"additionalProperties":false,"title":"linkedin_connection"},{"type":"object","properties":{"type":{"type":"string","enum":["task"]},"taskType":{"type":"string","minLength":1},"title":{"type":"string","minLength":1,"description":"Required task title shown in the UI."},"note":{"type":"string","minLength":1,"description":"Optional task note shown in the UI."},"ownerId":{"type":["string","null"],"minLength":1,"description":"Required when `GET /v1/tasks/owners` returns one or more owners."},"delay":{"type":"object","properties":{"value":{"type":"number","minimum":0,"description":"Delay amount."},"unit":{"type":"string","enum":["seconds","minutes","hours","days"],"description":"Delay unit."}},"required":["value","unit"],"additionalProperties":false}},"required":["type","taskType","title"],"additionalProperties":false,"title":"task"},{"type":"object","properties":{"type":{"type":"string","enum":["end"]}},"required":["type"],"additionalProperties":false,"title":"end"}]},"minItems":1,"description":"Ordered campaign steps. Use branch arrays like `onTrue`, `onFalse`, `onAccepted`, and `onNotAccepted` for branching."},"id":{"type":"number","description":"Unique identifier for the campaign"},"status":{"type":"string","enum":["DRAFT","PENDING","ACTIVE","COMPLETED","DELETED"],"description":"Status of the campaign"},"createdBy":{"type":"object","properties":{"id":{"type":"number","description":"ID of the user who created the campaign"},"name":{"type":["string","null"],"description":"Name of the user who created the campaign"}},"required":["id","name"]},"crmOwnerId":{"type":["string","null"],"description":"CRM owner associated with the campaign"},"senderIdentity":{"type":["object","null"],"properties":{"id":{"type":"number","description":"ID of the sender identity"},"name":{"type":"string","description":"Name of the sender identity"}},"required":["id","name"],"description":"Sender identity associated with the campaign"},"folderId":{"type":["number","null"],"description":"Folder ID containing the campaign, when assigned"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the campaign was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the campaign was last updated"}},"required":["name","steps","id","status","createdBy","crmOwnerId","senderIdentity","folderId","createdAt","updatedAt"],"additionalProperties":false}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid campaign ID"},"404":{"description":"Campaign not found"},"422":{"description":"Campaign sequence cannot be represented in the simplified format"}}}},"/v1/tasks/owners":{"get":{"summary":"Get task owners","description":"Retrieve CRM owners for task assignment in campaign task steps.\n\nUse this before creating `task` steps. If this endpoint returns one or more owners, `ownerId` becomes required on every task step in `POST /v1/campaigns`..\n\n    > **Required scope:** `OWNERS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Task owners retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"crmPlatform":{"type":["string","null"],"enum":["HUBSPOT","SALESFORCE","PIPEDRIVE","ZOHO","DYNAMICS","TRIBECRM","CUSTOM_CRM","ATTIO",null],"description":"Connected CRM platform, or `null` when no CRM is connected."},"ownerSelectionRequired":{"type":"boolean","description":"When `true`, every `task` step in `POST /v1/campaigns` must include `ownerId`."},"owners":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"CRM owner ID to send back as `ownerId` in task steps."},"name":{"type":"string","description":"CRM owner display name."},"email":{"type":"string","description":"CRM owner email when the CRM exposes it."}},"required":["id","name"]},"description":"Available CRM owners for task assignment."}},"required":["crmPlatform","ownerSelectionRequired","owners"]}},"required":["status","message","data"]}}}},"400":{"description":"CRM authentication expired or CRM owners could not be fetched"}}}},"/v1/tasks":{"get":{"summary":"Get tasks","description":"Retrieve a paginated list of tasks.\n\nUse comma-separated values for `taskIds`, `campaignIds`, and `companyIds` when passing multiple IDs..\n\n    > **Required scope:** `TASKS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"required":false,"name":"pageSize","in":"query"},{"schema":{"type":"string","enum":["due","skipped","pending","upcoming","completed"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string"},"required":false,"name":"ownerId","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0},"required":false,"name":"assignedId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"crmId","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"integer","exclusiveMinimum":0}},"required":false,"name":"campaignIds","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"integer","exclusiveMinimum":0}},"required":false,"name":"companyIds","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"integer","exclusiveMinimum":0}},"required":false,"name":"taskIds","in":"query"},{"schema":{"type":"string","enum":["email","linkedin","call","other"]},"required":false,"name":"taskType","in":"query"},{"schema":{"type":"string"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string"},"required":false,"name":"dateFrom","in":"query"},{"schema":{"type":"string"},"required":false,"name":"dateTo","in":"query"},{"schema":{"type":"string"},"required":false,"name":"statusEndOfDay","in":"query"},{"schema":{"type":"string","enum":["createdAt","completedAt","dueDate"]},"required":false,"name":"sortBy","in":"query"},{"schema":{"type":"string","enum":["asc","desc"]},"required":false,"name":"sortOrder","in":"query"}],"responses":{"200":{"description":"Tasks retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"type":{"type":"string"},"subject":{"type":"string"},"description":{"type":["string","null"]},"CRMId":{"type":["string","null"]},"completedAt":{"type":["string","null"],"format":"date-time"},"dueDate":{"type":["string","null"],"format":"date-time"},"notes":{"type":["string","null"]},"priority":{"type":["string","null"],"enum":["LOW","MEDIUM","HIGH",null]},"contact":{"type":["object","null"],"properties":{"id":{"type":"number"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"imageUrl":{"type":["string","null"]},"mobilePhone":{"type":["string","null"]},"jobTitle":{"type":["string","null"]},"enrichments":{"type":"array","items":{"type":"object","properties":{"type":{"type":["string","null"]},"phones":{"type":"array","items":{"type":"string"}}},"required":["type","phones"]}}},"required":["id","firstName","lastName","imageUrl","mobilePhone","jobTitle","enrichments"]},"company":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":["string","null"]},"domain":{"type":["string","null"]}},"required":["id","name","domain"]},"campaign":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"leadId":{"type":["number","null"]},"companyId":{"type":["number","null"]},"ownerId":{"type":["string","null"]},"assignedId":{"type":["number","null"]},"assignedTo":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"skippedAt":{"type":["string","null"],"format":"date-time"},"parentTaskId":{"type":["number","null"]}},"required":["id","createdAt","updatedAt","type","subject","description","CRMId","completedAt","dueDate","notes","priority","contact","company","campaign","leadId","companyId","ownerId","assignedId","assignedTo","skippedAt","parentTaskId"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}},"post":{"summary":"Create task","description":"Create a new task for a contact or company.\n\n    > **Required scope:** `TASKS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","minLength":1},"subject":{"type":"string","minLength":1},"description":{"type":"string"},"notes":{"type":"string"},"assignedId":{"type":"integer","exclusiveMinimum":0},"ownerId":{"type":"string"},"syncWithCRM":{"type":"boolean"},"dueDate":{"type":"string"},"leadId":{"type":"integer","exclusiveMinimum":0},"companyId":{"type":"integer","exclusiveMinimum":0},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"parentTaskId":{"type":"integer","exclusiveMinimum":0}},"required":["type","subject"]}}}},"responses":{"201":{"description":"Task created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"taskId":{"type":"number"}},"required":["taskId"]}},"required":["status","message","data"]}}}}}},"delete":{"summary":"Delete tasks","description":"Delete tasks in bulk.\n\n    > **Required scope:** `TASKS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"maxItems":100}},"required":["ids"]}}}},"responses":{"200":{"description":"Tasks deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"removed":{"type":"number"},"failed":{"type":"number"}},"required":["removed","failed"]}},"required":["status","message","data"]}}}}}}},"/v1/tasks/ids":{"get":{"summary":"Get task IDs","description":"Retrieve task IDs that match the provided filters.\n\n    > **Required scope:** `TASKS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["due","skipped","pending","upcoming","completed"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string"},"required":false,"name":"ownerId","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0},"required":false,"name":"assignedId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"crmId","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"integer","exclusiveMinimum":0}},"required":false,"name":"campaignIds","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"integer","exclusiveMinimum":0}},"required":false,"name":"companyIds","in":"query"},{"schema":{"type":"string","enum":["email","linkedin","call","other"]},"required":false,"name":"taskType","in":"query"},{"schema":{"type":"string"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string"},"required":false,"name":"dateFrom","in":"query"},{"schema":{"type":"string"},"required":false,"name":"dateTo","in":"query"},{"schema":{"type":"string"},"required":false,"name":"statusEndOfDay","in":"query"},{"schema":{"type":"string","enum":["createdAt","completedAt","dueDate"]},"required":false,"name":"sortBy","in":"query"},{"schema":{"type":"string","enum":["asc","desc"]},"required":false,"name":"sortOrder","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1000},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Task IDs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"number"}},"total":{"type":"number"}},"required":["ids","total"]}},"required":["status","message","data"]}}}}}}},"/v1/tasks/status-counts":{"get":{"summary":"Get task status counts","description":"Retrieve counts for key task status buckets.\n\nReturns counts for the `due`, `skipped`, and `upcoming` buckets..\n\n    > **Required scope:** `TASKS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"ownerId","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0},"required":false,"name":"assignedId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"crmId","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"integer","exclusiveMinimum":0}},"required":false,"name":"campaignIds","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"integer","exclusiveMinimum":0}},"required":false,"name":"companyIds","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"integer","exclusiveMinimum":0}},"required":false,"name":"taskIds","in":"query"},{"schema":{"type":"string","enum":["email","linkedin","call","other"]},"required":false,"name":"taskType","in":"query"},{"schema":{"type":"string"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string"},"required":false,"name":"dateFrom","in":"query"},{"schema":{"type":"string"},"required":false,"name":"dateTo","in":"query"},{"schema":{"type":"string"},"required":false,"name":"statusEndOfDay","in":"query"},{"schema":{"type":"string","enum":["createdAt","completedAt","dueDate"]},"required":false,"name":"sortBy","in":"query"},{"schema":{"type":"string","enum":["asc","desc"]},"required":false,"name":"sortOrder","in":"query"}],"responses":{"200":{"description":"Task status counts retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"due":{"type":"number"},"skipped":{"type":"number"},"upcoming":{"type":"number"}},"required":["due","skipped","upcoming"]}},"required":["status","message","data"]}}}}}}},"/v1/tasks/pending-count":{"get":{"summary":"Get task pending count","description":"Retrieve the current pending task count.\n\n    > **Required scope:** `TASKS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"ownerId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"clientDate","in":"query"}],"responses":{"200":{"description":"Task pending count retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"count":{"type":"number"}},"required":["count"]}},"required":["status","message","data"]}}}}}}},"/v1/tasks/{taskId}":{"patch":{"summary":"Update task","description":"Update an existing task.\n\n    > **Required scope:** `TASKS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","pattern":"^\\d+$"},"required":true,"name":"taskId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"subject":{"type":"string"},"description":{"type":["string","null"]},"assignedId":{"type":["integer","null"],"exclusiveMinimum":0},"notes":{"type":["string","null"]},"ownerId":{"type":["string","null"]},"dueDate":{"type":"string"},"priority":{"type":["string","null"],"enum":["LOW","MEDIUM","HIGH",null]}}}}}},"responses":{"200":{"description":"Task updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}},"required":["status","message","data"]}}}}}}},"/v1/tasks/{taskId}/complete":{"post":{"summary":"Complete task","description":"Mark a task as completed.\n\n    > **Required scope:** `TASKS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","pattern":"^\\d+$"},"required":true,"name":"taskId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"pauseConversation":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Task completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}},"required":["status","message","data"]}}}}}}},"/v1/tasks/complete-batch":{"post":{"summary":"Complete tasks batch","description":"Mark multiple tasks as completed.\n\n    > **Required scope:** `TASKS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"maxItems":100},"pauseConversation":{"type":"boolean","default":false}},"required":["ids"]}}}},"responses":{"200":{"description":"Tasks completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"completed":{"type":"number"},"failed":{"type":"number"}},"required":["completed","failed"]}},"required":["status","message","data"]}}}}}}},"/v1/tasks/skipped":{"post":{"summary":"Set skipped tasks","description":"Set or clear the skipped state for tasks.\n\n    > **Required scope:** `TASKS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Tasks"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"maxItems":100},"skipped":{"type":"boolean"}},"required":["ids","skipped"]}}}},"responses":{"200":{"description":"Task skipped state updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}},"required":["status","message","data"]}}}}}}},"/v1/folders":{"get":{"summary":"List folders","description":"Retrieve a paginated list of list folders across both contacts and companies. This preserves the legacy contract and adds campaign-specific folder endpoints separately..\n\n    > **Required scope:** `LISTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","default":"1","description":"Page number for pagination. Minimum value is 1. Defaults to 1."},"required":false,"description":"Page number for pagination. Minimum value is 1. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"string","default":"25","description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25."},"required":false,"description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25.","name":"pageSize","in":"query"},{"schema":{"type":"string","description":"Search term to filter folders by name (case-insensitive)."},"required":false,"description":"Search term to filter folders by name (case-insensitive).","name":"search","in":"query"},{"schema":{"type":"string","enum":["CONTACTS","COMPANIES"],"description":"Filter folders by type (`CONTACTS` or `COMPANIES`)."},"required":false,"description":"Filter folders by type (`CONTACTS` or `COMPANIES`).","name":"type","in":"query"}],"responses":{"200":{"description":"Successful response with paginated folders","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"type":{"type":"string","enum":["CONTACTS","COMPANIES"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","type","createdAt","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}}},"/v1/folders/contacts":{"get":{"summary":"List contact list folders","description":"List contact list folders. By default this returns only root folders. Use `includeChildren=true` to return nested folders too..\n\n    > **Required scope:** `LISTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes nested folders instead of only root folders."},"required":false,"description":"When `true`, includes nested folders instead of only root folders.","name":"includeChildren","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes recursive subfolder and list counts."},"required":false,"description":"When `true`, includes recursive subfolder and list counts.","name":"includeRecursiveCounts","in":"query"}],"responses":{"200":{"description":"Folders retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"type":{"type":"string","enum":["CONTACTS","COMPANIES"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"listsCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalListsCount":{"type":"number"}},"required":["id","name","parentId","type","createdAt","updatedAt","listsCount","subfoldersCount"]}}},"required":["status","message","data"]}}}}}},"post":{"summary":"Create contact list folder","description":"Create a contact list folder. Folder names must be unique within the same parent folder..\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Optional parent folder ID."}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Folder created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"type":{"type":"string","enum":["CONTACTS","COMPANIES"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","type","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}}},"/v1/folders/contacts/{folderId}":{"get":{"summary":"Get contact list folder","description":"Get a contact list folder with its child folders, lists, and breadcrumb ancestors..\n\n    > **Required scope:** `LISTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Folder ID"},"required":true,"description":"Folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Folder retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"type":{"type":"string","enum":["CONTACTS","COMPANIES"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"listsCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalListsCount":{"type":"number"},"children":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"_count":{"type":"object","properties":{"leadsGroup":{"type":"number"},"companyGroup":{"type":"number"},"children":{"type":"number"}},"required":["children"]}},"required":["id","name","_count"]}},"parent":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"leadsGroup":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"description":{"type":["string","null"]},"folderId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"_count":{"type":"object","properties":{"leadsGroupLeads":{"type":"number"}},"required":["leadsGroupLeads"]}},"required":["id","name","description","folderId","createdAt","updatedAt","createdBy","_count"]}},"companyGroup":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"description":{"type":["string","null"]},"folderId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"_count":{"type":"object","properties":{"companyGroupCompany":{"type":"number"}},"required":["companyGroupCompany"]}},"required":["id","name","description","folderId","createdAt","updatedAt","createdBy","_count"]}},"ancestors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]}},"required":["id","name","parentId"]}}},"required":["id","name","parentId","type","createdAt","updatedAt","listsCount","subfoldersCount","children","parent","ancestors"]}},"required":["status","message","data"]}}}},"404":{"description":"Folder not found"}}},"patch":{"summary":"Update contact list folder","description":"Update a contact list folder name or parent. Moving a folder into one of its descendants is not allowed..\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Folder ID"},"required":true,"description":"Folder ID","name":"folderId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Updated folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Updated parent folder ID or `null` to move to root."}},"additionalProperties":false}}}},"responses":{"200":{"description":"Folder updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"type":{"type":"string","enum":["CONTACTS","COMPANIES"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","type","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}},"delete":{"summary":"Delete contact list folder","description":"Delete a contact list folder. Descendant folders are deleted too. Lists inside the deleted folders are not deleted; they are unassigned from the folder hierarchy..\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Folder ID"},"required":true,"description":"Folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Folder deleted successfully"}}}},"/v1/folders/companies":{"get":{"summary":"List company list folders","description":"List company list folders. By default this returns only root folders. Use `includeChildren=true` to return nested folders too..\n\n    > **Required scope:** `LISTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes nested folders instead of only root folders."},"required":false,"description":"When `true`, includes nested folders instead of only root folders.","name":"includeChildren","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"When `true`, includes recursive subfolder and list counts."},"required":false,"description":"When `true`, includes recursive subfolder and list counts.","name":"includeRecursiveCounts","in":"query"}],"responses":{"200":{"description":"Folders retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"type":{"type":"string","enum":["CONTACTS","COMPANIES"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"listsCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalListsCount":{"type":"number"}},"required":["id","name","parentId","type","createdAt","updatedAt","listsCount","subfoldersCount"]}}},"required":["status","message","data"]}}}}}},"post":{"summary":"Create company list folder","description":"Create a company list folder. Folder names must be unique within the same parent folder..\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Optional parent folder ID."}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Folder created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"type":{"type":"string","enum":["CONTACTS","COMPANIES"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","type","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}}},"/v1/folders/companies/{folderId}":{"get":{"summary":"Get company list folder","description":"Get a company list folder with its child folders, lists, and breadcrumb ancestors..\n\n    > **Required scope:** `LISTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Folder ID"},"required":true,"description":"Folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Folder retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"type":{"type":"string","enum":["CONTACTS","COMPANIES"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"listsCount":{"type":"number"},"subfoldersCount":{"type":"number"},"totalSubfoldersCount":{"type":"number"},"totalListsCount":{"type":"number"},"children":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"_count":{"type":"object","properties":{"leadsGroup":{"type":"number"},"companyGroup":{"type":"number"},"children":{"type":"number"}},"required":["children"]}},"required":["id","name","_count"]}},"parent":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"leadsGroup":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"description":{"type":["string","null"]},"folderId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"_count":{"type":"object","properties":{"leadsGroupLeads":{"type":"number"}},"required":["leadsGroupLeads"]}},"required":["id","name","description","folderId","createdAt","updatedAt","createdBy","_count"]}},"companyGroup":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"description":{"type":["string","null"]},"folderId":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":["object","null"],"properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"_count":{"type":"object","properties":{"companyGroupCompany":{"type":"number"}},"required":["companyGroupCompany"]}},"required":["id","name","description","folderId","createdAt","updatedAt","createdBy","_count"]}},"ancestors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]}},"required":["id","name","parentId"]}}},"required":["id","name","parentId","type","createdAt","updatedAt","listsCount","subfoldersCount","children","parent","ancestors"]}},"required":["status","message","data"]}}}},"404":{"description":"Folder not found"}}},"patch":{"summary":"Update company list folder","description":"Update a company list folder name or parent. Moving a folder into one of its descendants is not allowed..\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Folder ID"},"required":true,"description":"Folder ID","name":"folderId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Updated folder name."},"parentId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Updated parent folder ID or `null` to move to root."}},"additionalProperties":false}}}},"responses":{"200":{"description":"Folder updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"parentId":{"type":["number","null"]},"type":{"type":"string","enum":["CONTACTS","COMPANIES"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","parentId","type","createdAt","updatedAt"]}},"required":["status","message","data"]}}}}}},"delete":{"summary":"Delete company list folder","description":"Delete a company list folder. Descendant folders are deleted too. Lists inside the deleted folders are not deleted; they are unassigned from the folder hierarchy..\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Folder ID"},"required":true,"description":"Folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Folder deleted successfully"}}}},"/v1/lists":{"post":{"summary":"Create a list","description":"Create a new list for contacts or companies.\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["CONTACTS","COMPANIES"],"description":"Type of list to create (CONTACTS or COMPANIES)."},"name":{"type":"string","minLength":1,"description":"Name of the list"},"description":{"type":["string","null"],"description":"Description of the list"},"folderId":{"type":["integer","null"],"exclusiveMinimum":0,"description":"Folder ID to place the list in"}},"required":["type","name"]}}}},"responses":{"201":{"description":"List created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the list"},"name":{"type":"string","description":"Name of the list"},"description":{"type":["string","null"],"description":"Description of the list"},"type":{"type":"string","enum":["CONTACTS","COMPANIES"],"description":"Type of the list (CONTACTS or COMPANIES)"},"entitiesCount":{"type":"number","description":"Number of entities in the list"},"createdBy":{"type":"object","properties":{"id":{"type":"number","description":"ID of the user who created the list"},"name":{"type":["string","null"],"description":"Name of the user who created the list"}},"required":["id","name"],"description":"User who created the list"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the list was created"}},"required":["id","name","description","type","entitiesCount","createdBy","createdAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error or folder not found"}}},"get":{"summary":"Get lists","description":"Retrieve a paginated list of contact lists (both contacts and companies).\n\n    > **Required scope:** `LISTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","default":"1","description":"Page number for pagination. Minimum value is 1. Defaults to 1."},"required":false,"description":"Page number for pagination. Minimum value is 1. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"string","default":"25","description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25."},"required":false,"description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25.","name":"pageSize","in":"query"},{"schema":{"type":"string","description":"Search term to filter lists by name or description (case-insensitive)."},"required":false,"description":"Search term to filter lists by name or description (case-insensitive).","name":"search","in":"query"},{"schema":{"type":"string","enum":["CONTACTS","COMPANIES"],"description":"Filter lists by type (CONTACTS or COMPANIES)."},"required":false,"description":"Filter lists by type (CONTACTS or COMPANIES).","name":"type","in":"query"}],"responses":{"200":{"description":"Successful response with paginated lists","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the list"},"name":{"type":"string","description":"Name of the list"},"description":{"type":["string","null"],"description":"Description of the list"},"type":{"type":"string","enum":["CONTACTS","COMPANIES"],"description":"Type of the list (CONTACTS or COMPANIES)"},"entitiesCount":{"type":"number","description":"Number of entities in the list"},"createdBy":{"type":"object","properties":{"id":{"type":"number","description":"ID of the user who created the list"},"name":{"type":["string","null"],"description":"Name of the user who created the list"}},"required":["id","name"],"description":"User who created the list"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the list was created"}},"required":["id","name","description","type","entitiesCount","createdBy","createdAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}}},"/v1/ai-finder/import":{"post":{"summary":"Import a list from AI Finder","description":"Use AI Finder to generate a LinkedIn search, then import the results into a contact or company list. Returns an actions ID that can be monitored via GET /v1/actions/{actionsId}/status and queried via the existing contacts/companies endpoints using the actionsId filter..\n\n    > **Required scope:** `ACTIONS_WRITE`\n    >\n    > **Rate limit:** 10 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":500,"description":"Natural-language description of the people or companies you want AI Finder to locate."},"type":{"type":"string","enum":["contacts","companies"],"description":"Entity type to search and import. This determines whether listId refers to a contact list or a company list."},"maxCount":{"type":"integer","minimum":100,"maximum":2500,"description":"Maximum number of results to import. Must be between 100 and 2500, inclusive, in increments of 100."},"listId":{"type":"integer","exclusiveMinimum":0,"description":"Destination list ID. Must be a contact list for contacts or a company list for companies."}},"required":["text","type","maxCount","listId"]},"examples":{"contactsImport":{"summary":"Import contacts from AI Finder","value":{"listId":123,"maxCount":500,"text":"VP Finance at companies in California","type":"contacts"}}}}}},"responses":{"201":{"description":"AI Finder import started","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"actionsId":{"type":"number","description":"Unique identifier for the actions group created for this import"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the actions group was created"},"type":{"type":"string","enum":["CONTACTS","COMPANIES"],"description":"Entity type imported into the destination list"},"listId":{"type":"number","description":"Destination list ID"},"workflowId":{"type":"string","description":"Workflow ID that can be used with the public AI search status endpoint"}},"required":["actionsId","createdAt","type","listId","workflowId"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error"},"404":{"description":"Destination list not found"},"422":{"description":"AI Finder could not build a valid search or returned a different entity type"}}}},"/v1/lists/{listId}/contacts":{"post":{"summary":"Add contacts to a list","description":"Add contacts to a list.\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The list ID"},"required":true,"description":"The list ID","name":"listId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"contactIds":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"description":"Array of contact IDs to add/remove"}},"required":["contactIds"]}}}},"responses":{"200":{"description":"Contacts added to list","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"requestedCount":{"type":"number"},"addedCount":{"type":"number"},"skippedCount":{"type":"number"}},"required":["requestedCount","addedCount","skippedCount"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error or contacts not found"},"404":{"description":"List not found"}}},"delete":{"summary":"Remove contacts from a list","description":"Remove contacts from a list.\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The list ID"},"required":true,"description":"The list ID","name":"listId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"contactIds":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"description":"Array of contact IDs to add/remove"}},"required":["contactIds"]}}}},"responses":{"200":{"description":"Contacts removed from list","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"requestedCount":{"type":"number"},"removedCount":{"type":"number"},"notInListCount":{"type":"number"}},"required":["requestedCount","removedCount","notInListCount"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error"},"404":{"description":"List not found"}}}},"/v1/lists/{fromListId}/contacts/move":{"post":{"summary":"Move contacts between lists","description":"Move contacts between lists.\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The source list ID"},"required":true,"description":"The source list ID","name":"fromListId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"toListId":{"type":"integer","exclusiveMinimum":0,"description":"Destination list ID"},"contactIds":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"description":"Array of contact IDs to move"}},"required":["toListId","contactIds"]}}}},"responses":{"200":{"description":"Contacts moved between lists","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"requestedCount":{"type":"number"},"removedFromSourceCount":{"type":"number"},"addedToDestinationCount":{"type":"number"},"notInSourceCount":{"type":"number"},"alreadyInDestinationCount":{"type":"number"}},"required":["requestedCount","removedFromSourceCount","addedToDestinationCount","notInSourceCount","alreadyInDestinationCount"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error or contacts not found"},"404":{"description":"List not found"}}}},"/v1/lists/{listId}/companies":{"post":{"summary":"Add companies to a list","description":"Add companies to a list.\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The list ID"},"required":true,"description":"The list ID","name":"listId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"companyIds":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"description":"Array of company IDs to add/remove"}},"required":["companyIds"]}}}},"responses":{"200":{"description":"Companies added to list","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"requestedCount":{"type":"number"},"addedCount":{"type":"number"},"skippedCount":{"type":"number"}},"required":["requestedCount","addedCount","skippedCount"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error or companies not found"},"404":{"description":"List not found"}}},"delete":{"summary":"Remove companies from a list","description":"Remove companies from a list.\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The list ID"},"required":true,"description":"The list ID","name":"listId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"companyIds":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"description":"Array of company IDs to add/remove"}},"required":["companyIds"]}}}},"responses":{"200":{"description":"Companies removed from list","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"requestedCount":{"type":"number"},"removedCount":{"type":"number"},"notInListCount":{"type":"number"}},"required":["requestedCount","removedCount","notInListCount"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error"},"404":{"description":"List not found"}}}},"/v1/lists/{fromListId}/companies/move":{"post":{"summary":"Move companies between lists","description":"Move companies between lists.\n\n    > **Required scope:** `LISTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Lists"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The source list ID"},"required":true,"description":"The source list ID","name":"fromListId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"toListId":{"type":"integer","exclusiveMinimum":0,"description":"Destination list ID"},"companyIds":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"description":"Array of company IDs to move"}},"required":["toListId","companyIds"]}}}},"responses":{"200":{"description":"Companies moved between lists","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"requestedCount":{"type":"number"},"removedFromSourceCount":{"type":"number"},"addedToDestinationCount":{"type":"number"},"notInSourceCount":{"type":"number"},"alreadyInDestinationCount":{"type":"number"}},"required":["requestedCount","removedFromSourceCount","addedToDestinationCount","notInSourceCount","alreadyInDestinationCount"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error or companies not found"},"404":{"description":"List not found"}}}},"/v1/saved-filters":{"post":{"summary":"Create a saved filter","description":"Create a saved LinkedIn search filter for later reuse. Created filters can be referenced when running SEARCH_LEADS_FROM_LINKEDIN_COMPANY actions..\n\n    > **Required scope:** `ACTIONS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Saved Filters"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Name for the saved filter."},"filters":{"type":"object","additionalProperties":{},"description":"Primary LinkedIn search filters configuration to save."},"keywords":{"type":"array","items":{"type":"string","minLength":1},"description":"Optional keywords associated with this saved filter."},"searchFallbackFilters":{"type":"array","items":{"type":"object","properties":{"filters":{"type":"object","additionalProperties":{},"description":"LinkedIn search filters configuration for this step."},"keywords":{"type":"array","items":{"type":"string","minLength":1},"description":"Keywords associated with this fallback search step."}},"required":["filters","keywords"]},"description":"Optional ordered fallback searches to try after the primary filter."},"type":{"type":"string","enum":["LEAD","COMPANY"],"description":"Saved filter type (LEAD or COMPANY)."},"isShared":{"type":"boolean","default":false,"description":"Whether the saved filter is shared with the team."}},"required":["name","filters","type"]}}}},"responses":{"201":{"description":"Saved filter created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Created saved filter ID."}},"required":["id"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error"}}},"get":{"summary":"Get saved filters","description":"Retrieve a list of saved LinkedIn search filters. These filters can be used with the SEARCH_LEADS_FROM_LINKEDIN_COMPANY action to reuse predefined filter configurations..\n\n    > **Required scope:** `WORKSPACE_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Saved Filters"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","default":"1","description":"Page number for pagination. Minimum value is 1. Defaults to 1."},"required":false,"description":"Page number for pagination. Minimum value is 1. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"string","default":"25","description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25."},"required":false,"description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25.","name":"pageSize","in":"query"},{"schema":{"type":"string","description":"Search term to filter saved filters by name (case-insensitive)."},"required":false,"description":"Search term to filter saved filters by name (case-insensitive).","name":"search","in":"query"}],"responses":{"200":{"description":"Successful response with paginated saved filters","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the saved filter"},"name":{"type":"string","description":"Name of the saved filter"},"filters":{"type":"object","additionalProperties":{},"description":"LinkedIn search filters configuration"},"keywords":{"type":["array","null"],"items":{"type":"string"},"description":"Keywords associated with this filter"},"isShared":{"type":"boolean","description":"Whether this filter is shared with the team"},"createdBy":{"type":"object","properties":{"id":{"type":"number","description":"ID of the user who created the filter"},"name":{"type":["string","null"],"description":"Name of the user who created the filter"}},"required":["id","name"],"description":"User who created the saved filter"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the filter was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the filter was last updated"}},"required":["id","name","filters","keywords","isShared","createdBy","createdAt","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}}},"/v1/saved-views":{"get":{"summary":"Get saved views","description":"Retrieve a paginated list of saved table views (contacts and companies).\n\n    > **Required scope:** `WORKSPACE_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Saved Views"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","default":"1","description":"Page number for pagination. Minimum value is 1. Defaults to 1."},"required":false,"description":"Page number for pagination. Minimum value is 1. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"string","default":"25","description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25."},"required":false,"description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25.","name":"pageSize","in":"query"},{"schema":{"type":"string","enum":["LEAD","COMPANY"],"description":"Filter saved views by type (LEAD or COMPANY)."},"required":false,"description":"Filter saved views by type (LEAD or COMPANY).","name":"type","in":"query"}],"responses":{"200":{"description":"Successful response with paginated saved views","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the saved view"},"name":{"type":"string","description":"Name of the saved view"},"type":{"type":"string","enum":["LEAD","COMPANY"],"description":"View type (LEAD or COMPANY)"},"view":{"type":"array","items":{"type":"string"},"description":"Saved view configuration (column keys)"},"createdBy":{"type":"object","properties":{"id":{"type":"number","description":"ID of the user who created the view"},"name":{"type":["string","null"],"description":"Name of the user who created the view"}},"required":["id","name"]},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the view was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the view was last updated"}},"required":["id","name","type","view","createdBy","createdAt","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}}},"/v1/saved-views/{savedViewId}":{"get":{"summary":"Get saved view","description":"Retrieve a single saved view by ID.\n\n    > **Required scope:** `WORKSPACE_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Saved Views"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The saved view ID"},"required":true,"description":"The saved view ID","name":"savedViewId","in":"path"}],"responses":{"200":{"description":"Successful response with saved view","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the saved view"},"name":{"type":"string","description":"Name of the saved view"},"type":{"type":"string","enum":["LEAD","COMPANY"],"description":"View type (LEAD or COMPANY)"},"view":{"type":"array","items":{"type":"string"},"description":"Saved view configuration (column keys)"},"createdBy":{"type":"object","properties":{"id":{"type":"number","description":"ID of the user who created the view"},"name":{"type":["string","null"],"description":"Name of the user who created the view"}},"required":["id","name"]},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the view was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the view was last updated"}},"required":["id","name","type","view","createdBy","createdAt","updatedAt"]}},"required":["status","message","data"]}}}},"404":{"description":"Saved view not found"}}}},"/v1/credits":{"get":{"summary":"Get credit balance","description":"Retrieve current credit balance and plan information.\n\n    > **Required scope:** `WORKSPACE_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Credits"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Credits information retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"balance":{"type":"number","description":"Current credit balance"},"nextRenewalDate":{"type":"string","format":"date-time","description":"Date when credits will renew for the next billing cycle"},"monthlyPlanCredits":{"type":"number","description":"Number of credits included in the monthly plan"},"monthlyAddonCredits":{"type":"number","description":"Number of additional credits purchased as monthly addons"}},"required":["balance","nextRenewalDate","monthlyPlanCredits","monthlyAddonCredits"]}},"required":["status","message","data"]}}}},"404":{"description":"Client not found"}}}},"/v1/credits/pricing":{"get":{"summary":"Get credit pricing","description":"Retrieve credit costs for all available actions.\n\n    > **Required scope:** `WORKSPACE_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Credits"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Pricing information retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"actions":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string","description":"Action identifier"},"name":{"type":"string","description":"Action name"},"cost":{"type":"number","description":"Credit cost for this action"},"description":{"type":["string","null"],"description":"Description of the action"}},"required":["action","name","cost","description"]},"description":"List of all available actions with their credit costs"}},"required":["actions"]}},"required":["status","message","data"]}}}}}}},"/v1/campaign/{campaignId}/analytics":{"get":{"summary":"Get campaign analytics","description":"Retrieve overall and daily analytics for a specific campaign.\n\n    > **Required scope:** `ANALYTICS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The campaign ID to retrieve analytics for."},"required":true,"description":"The campaign ID to retrieve analytics for.","name":"campaignId","in":"path"},{"schema":{"type":"string","description":"Optional start date in ISO 8601 format. Defaults to the last 30 days."},"required":false,"description":"Optional start date in ISO 8601 format. Defaults to the last 30 days.","name":"startDate","in":"query"},{"schema":{"type":"string","description":"Optional end date in ISO 8601 format. Defaults to now."},"required":false,"description":"Optional end date in ISO 8601 format. Defaults to now.","name":"endDate","in":"query"}],"responses":{"200":{"description":"Campaign analytics retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"campaignId":{"type":"number","description":"Unique identifier for the campaign."},"campaignName":{"type":"string","description":"Name of the campaign."},"status":{"type":"string","enum":["DRAFT","PAUSED","ACTIVE","FREEZED","COMPLETED","SCHEDULED"],"description":"Current user-facing campaign status."},"isActive":{"type":"boolean","description":"Whether the campaign is currently active."},"isPaused":{"type":"boolean","description":"Whether the campaign is currently paused."},"isArchived":{"type":"boolean","description":"Whether the campaign is archived."},"overview":{"type":"object","properties":{"totalContacts":{"type":"number","description":"Total contacts included in the campaign analytics view."},"started":{"type":"number","description":"Number of contacts that started the campaign."},"contacted":{"type":"number","description":"Number of contacts that received at least one outbound message."},"replied":{"type":"number","description":"Number of contacted contacts that replied."},"positive":{"type":"number","description":"Number of replied contacts with a positive conversation tag."}},"required":["totalContacts","started","contacted","replied","positive"],"description":"Overview counters aligned with the campaign analytics view."},"progressByChannelList":{"type":"object","properties":{"all":{"type":"object","properties":{"totalLeads":{"type":"number","description":"Total contacts in the campaign."},"started":{"type":"number","description":"Started contacts."},"contacted":{"type":"number","description":"Contacted contacts."},"replied":{"type":"number","description":"Contacts who replied."},"tagged":{"type":"number","description":"Contacts with at least one conversation tag."},"positive":{"type":"number","description":"Positive contacts."}},"required":["totalLeads","started","contacted","replied","tagged","positive"],"description":"Overview metrics across all campaign channels."},"linkedin":{"type":["object","null"],"properties":{"totalLeads":{"type":"number","description":"Total contacts in the LinkedIn campaign."},"engaged":{"type":"number","description":"Engaged contacts."},"invited":{"type":"number","description":"Invited contacts."},"sentConnections":{"type":"number","description":"Contacts invited through campaign-owned connection requests."},"alreadySentConnections":{"type":"number","description":"Contacts invited through already-existing connection requests attributed to the sender."},"accepted":{"type":"number","description":"Accepted invitations."},"acceptedConnections":{"type":"number","description":"Accepted invitations."},"contacted":{"type":"number","description":"Contacts who received at least one LinkedIn message."},"viewed":{"type":"number","description":"Contacts who viewed at least one outbound LinkedIn message."},"followed":{"type":"number","description":"Contacts followed by the campaign."},"replied":{"type":"number","description":"Contacts who replied on LinkedIn."},"tagged":{"type":"number","description":"LinkedIn contacts with at least one conversation tag."},"positive":{"type":"number","description":"Positive LinkedIn contacts."}},"required":["totalLeads","engaged","invited","sentConnections","alreadySentConnections","accepted","acceptedConnections","contacted","viewed","followed","replied","tagged","positive"],"description":"LinkedIn campaign metrics aligned with the overview page."},"email":{"type":["object","null"],"properties":{"totalLeads":{"type":"number","description":"Total contacts in the email campaign."},"sent":{"type":"number","description":"Contacts who received at least one email."},"viewed":{"type":["number","null"],"description":"Contacts who viewed at least one email when tracking is enabled."},"clicked":{"type":["number","null"],"description":"Contacts who clicked at least one email link when tracking is enabled."},"replied":{"type":"number","description":"Contacts who replied by email."},"bounced":{"type":"number","description":"Contacts with at least one bounced email."},"tagged":{"type":"number","description":"Email contacts with at least one conversation tag."},"positive":{"type":"number","description":"Positive email contacts."}},"required":["totalLeads","sent","viewed","clicked","replied","bounced","tagged","positive"],"description":"Email campaign metrics aligned with the overview page."},"whatsapp":{"type":["object","null"],"properties":{"totalLeads":{"type":"number","description":"Total contacts in the WhatsApp campaign."},"sent":{"type":"number","description":"Contacts who received at least one WhatsApp message."},"replied":{"type":"number","description":"Contacts who replied on WhatsApp."},"tagged":{"type":"number","description":"WhatsApp contacts with at least one conversation tag."}},"required":["totalLeads","sent","replied","tagged"],"description":"WhatsApp campaign metrics aligned with the overview page."},"tasks":{"type":["object","null"],"properties":{"pending":{"type":"number","description":"Pending tasks."},"completed":{"type":"number","description":"Completed tasks."}},"required":["pending","completed"],"description":"Task metrics aligned with the overview page."}},"required":["all","linkedin","email","whatsapp","tasks"],"description":"Per-channel campaign metrics aligned with the platform overview page."},"totalContacts":{"type":"number","description":"Total number of contacts currently in the campaign."},"contactRate":{"type":"number","description":"Percentage of campaign contacts that have received at least one outbound message."},"replyRate":{"type":"number","description":"Percentage of contacted campaign contacts that replied, excluding out-of-office replies."},"daily":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date-time","description":"UTC day bucket for the analytics row."},"contactsAdded":{"type":"number","description":"Number of contacts added to the campaign on that day."},"connectionRequestsSent":{"type":"number","description":"Number of connection requests or invitations sent on that day."},"newMessagesSent":{"type":"number","description":"Number of new outbound messages sent on that day."},"queuedMessagesDueToLimit":{"type":"number","description":"Number of outbound messages queued on that day because send limits were hit."}},"required":["date","contactsAdded","connectionRequestsSent","newMessagesSent","queuedMessagesDueToLimit"]},"description":"Daily analytics for the selected date range."}},"required":["campaignId","campaignName","status","isActive","isPaused","isArchived","overview","progressByChannelList","totalContacts","contactRate","replyRate","daily"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid campaign ID or date range"},"404":{"description":"Campaign not found"}}}},"/v1/campaign/{campaignId}/clone":{"post":{"summary":"Clone a campaign","description":"Clone a campaign with a new identity, preserving workflow, messages, tasks, tags, and folder..\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The campaign ID to clone"},"required":true,"description":"The campaign ID to clone","name":"campaignId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"identityId":{"type":"integer","exclusiveMinimum":0,"description":"Identity ID for the cloned campaign"},"name":{"type":"string","maxLength":255,"description":"Optional name. Defaults to \"Copy of {original}\""}},"required":["identityId"]}}}},"responses":{"201":{"description":"Campaign cloned successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"ID of the new campaign"},"name":{"type":"string","description":"Name of the new campaign"},"status":{"type":"string","description":"Status of the new campaign (DRAFT)"}},"required":["id","name","status"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error"},"404":{"description":"Campaign or identity not found"}}}},"/v1/campaign/{campaignId}/status":{"patch":{"summary":"Update campaign status","description":"Update campaign status (activate, complete, pause, or delete a campaign)..\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The campaign ID to update"},"required":true,"description":"The campaign ID to update","name":"campaignId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["DRAFT","PENDING","ACTIVE","COMPLETED","DELETED"],"description":"Target campaign status"}},"required":["status"]}}}},"responses":{"200":{"description":"Campaign status updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number"},"status":{"type":"string"}},"required":["id","status"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error or invalid status transition"},"404":{"description":"Campaign not found"}}}},"/v1/add-contact-to-campaign":{"post":{"summary":"Add a contact to a campaign","description":"Creates a new conversation by adding a contact to a campaign.\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"campaignId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the campaign to add the contact to"},"contactId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the contact to add to the campaign"}},"required":["campaignId","contactId"]}}}},"responses":{"200":{"description":"Contact successfully added to campaign","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"conversationId":{"type":"number","description":"ID of the created conversation"},"conversationStatus":{"type":"string","description":"Status of the conversation"},"campaignStatus":{"type":"string","description":"Status of the campaign"}},"required":["conversationId","conversationStatus","campaignStatus"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error"},"404":{"description":"Campaign not found"}}}},"/v1/add-contact-group-to-campaign":{"post":{"summary":"Add a contact group to a campaign","description":"Creates new conversations by adding every contact in a contact group to a campaign.\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"campaignId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the campaign to add the contact group to"},"contactGroupId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the contact group to add to the campaign"}},"required":["campaignId","contactGroupId"]}}}},"responses":{"200":{"description":"Contact group processed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"requestedCount":{"type":"number","description":"Number of contacts found in the contact group"},"addedCount":{"type":"number","description":"Number of new conversations created"},"reactivatedCount":{"type":"number","description":"Number of paused conversations reactivated"},"alreadyInCampaignCount":{"type":"number","description":"Number of contacts already present in the campaign"},"skippedDeletedConversationCount":{"type":"number","description":"Number of contacts skipped because their conversation is deleted"},"skippedContactIds":{"type":"array","items":{"type":"number"},"description":"Contact IDs skipped because their campaign conversation is deleted"},"campaignStatus":{"type":"string","description":"Status of the campaign"}},"required":["requestedCount","addedCount","reactivatedCount","alreadyInCampaignCount","skippedDeletedConversationCount","skippedContactIds","campaignStatus"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error"},"404":{"description":"Campaign or contact group not found"}}}},"/v1/pause-contact-in-campaign":{"post":{"summary":"Pause a contact in a campaign","description":"Pauses an active conversation in a campaign.\n\n    > **Required scope:** `CAMPAIGNS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"campaignId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the campaign"},"contactId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the contact in the campaign"}},"required":["campaignId","contactId"]},{"type":"object","properties":{"conversationId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the conversation to pause"}},"required":["conversationId"]}]}}}},"responses":{"200":{"description":"Conversation successfully paused","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"conversationId":{"type":"number","description":"ID of the paused conversation"}},"required":["conversationId"]}},"required":["status","message","data"]}}}},"404":{"description":"Conversation not found"}}}},"/v1/contacts":{"get":{"summary":"Get contacts","description":"Retrieve a paginated list of contacts.\n\n    > **Required scope:** `CONTACTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Contacts"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","default":"1","description":"Page number for pagination. Minimum value is 1. Defaults to 1."},"required":false,"description":"Page number for pagination. Minimum value is 1. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"string","default":"25","description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25."},"required":false,"description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25.","name":"pageSize","in":"query"},{"schema":{"type":"string","description":"Search term to filter contacts by first name, last name, or email (case-insensitive)."},"required":false,"description":"Search term to filter contacts by first name, last name, or email (case-insensitive).","name":"search","in":"query"},{"schema":{"type":"string","description":"Filter contacts by company ID."},"required":false,"description":"Filter contacts by company ID.","name":"companyId","in":"query"},{"schema":{"type":"string","description":"Filter contacts by list ID."},"required":false,"description":"Filter contacts by list ID.","name":"listId","in":"query"},{"schema":{"type":"string","description":"Filter contacts updated on or after this date (ISO 8601 format)."},"required":false,"description":"Filter contacts updated on or after this date (ISO 8601 format).","name":"updatedAtFrom","in":"query"},{"schema":{"type":"string","description":"Filter contacts updated on or before this date (ISO 8601 format)."},"required":false,"description":"Filter contacts updated on or before this date (ISO 8601 format).","name":"updatedAtTo","in":"query"},{"schema":{"type":"string","description":"Filter contacts by a specific actions run ID. Returns only contacts that were created or processed as part of this actions run (e.g., from \"Search contacts from company\" action)."},"required":false,"description":"Filter contacts by a specific actions run ID. Returns only contacts that were created or processed as part of this actions run (e.g., from \"Search contacts from company\" action).","name":"actionsId","in":"query"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Specific contact fields to include in the response (comma-separated or array). Use `GET /v1/contacts/fields` to discover valid contact field names."},"required":false,"description":"Specific contact fields to include in the response (comma-separated or array). Use `GET /v1/contacts/fields` to discover valid contact field names.","name":"fields","in":"query"}],"responses":{"200":{"description":"Successful response with paginated contacts","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the contact"},"firstName":{"type":["string","null"],"description":"First name of the contact"},"lastName":{"type":["string","null"],"description":"Last name of the contact"},"jobTitle":{"type":["string","null"],"description":"Job title of the contact"},"linkedInProfileUrl":{"type":["string","null"],"description":"LinkedIn profile URL of the contact"},"professionalEmail":{"type":["string","null"],"description":"Professional email address of the contact"},"personalEmails":{"type":["string","null"],"description":"Personal email addresses (comma-separated)"},"mobilePhone":{"type":["string","null"],"description":"Mobile phone number of the contact"},"phones":{"type":["string","null"],"description":"Other phone numbers (comma-separated)"},"imageUrl":{"type":["string","null"],"description":"Profile image URL"},"companyId":{"type":["number","null"],"description":"ID of the company associated with the contact"},"company":{"type":["object","null"],"properties":{"id":{"type":"number","description":"Company ID"},"name":{"type":["string","null"],"description":"Company name"},"domain":{"type":["string","null"],"description":"Company website domain"},"companyLinkedInUrl":{"type":["string","null"],"description":"Company LinkedIn URL"}},"required":["id","name","domain","companyLinkedInUrl"],"description":"Company details"},"emailVerificationStatus":{"type":"string","description":"Email verification status"},"contactCountry":{"type":["string","null"],"description":"Country of the contact"},"linkedInHeadline":{"type":["string","null"],"description":"LinkedIn headline"},"numberOfConnections":{"type":["number","null"],"description":"Number of LinkedIn connections"},"contactCRMId":{"type":["string","null"],"description":"CRM contact ID"},"leadCRMId":{"type":["string","null"],"description":"CRM lead ID"},"isInCRM":{"type":"boolean","description":"Whether the contact is synced with CRM"},"smartFieldExplanations":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of smart field names to their explanation (returned when smart fields are requested)."},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the contact was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the contact was last updated"}},"required":["id","firstName","lastName","jobTitle","linkedInProfileUrl","professionalEmail","personalEmails","mobilePhone","phones","imageUrl","companyId","company","emailVerificationStatus","contactCountry","linkedInHeadline","numberOfConnections","contactCRMId","leadCRMId","isInCRM","createdAt","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}},"404":{"description":"Actions run not found (when filtering by actionsId)"}}}},"/v1/contacts/search":{"post":{"summary":"Search contacts with advanced filters","description":"Search contacts with advanced filtering options.\n\n    > **Required scope:** `CONTACTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Contacts"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"default":1,"description":"Page number for pagination. Minimum value is 1."},"pageSize":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Number of items per page. Minimum is 1, maximum is 100."},"search":{"type":"string","description":"Search term for full-text search across contact fields."},"include":{"type":"object","additionalProperties":{},"default":{},"description":"Filter conditions to include. Supports special filters like `id`, `campaigns`, `leadsGroup`, `companyGroup`, `isInCRM`, `enrichments`, and any contact/company field ID returned by the fields endpoints. Filter values should match the field data type returned by `GET /v1/contacts/fields`: text/select fields use arrays of exact values, numeric fields use two-item range arrays like `[\"10\",\"100\"]`, boolean fields use one-item arrays like `[true]`, and timestamp fields use `{ \"startDate\": \"...\", \"endDate\": \"...\" }`. Start with `id`, `leadsGroup` (contact list IDs), `companyGroup` (company list IDs), `campaigns`, `isInCRM`, and any workspace scoring fields such as `icpScore` or `scoreBand` when those field IDs appear in the fields response. Use `GET /v1/contacts/fields` to discover valid contact field names for `fields`, `include`, `exclude`, and update payloads. Company-backed filters can use use `get /v1/companies/fields` to discover valid company field names."},"exclude":{"type":"object","additionalProperties":{},"default":{},"description":"Filter conditions to exclude. Same structure as include. Filter values should match the field data type returned by `GET /v1/contacts/fields`: text/select fields use arrays of exact values, numeric fields use two-item range arrays like `[\"10\",\"100\"]`, boolean fields use one-item arrays like `[true]`, and timestamp fields use `{ \"startDate\": \"...\", \"endDate\": \"...\" }`. Start with `id`, `leadsGroup` (contact list IDs), `companyGroup` (company list IDs), `campaigns`, `isInCRM`, and any workspace scoring fields such as `icpScore` or `scoreBand` when those field IDs appear in the fields response. Use `GET /v1/contacts/fields` to discover valid contact field names for `fields`, `include`, `exclude`, and update payloads."},"actionsId":{"type":"integer","description":"Filter contacts by a specific actions run ID. Returns only contacts that were created or processed as part of this actions run (e.g., from \"Search contacts from company\" action)."},"fields":{"type":"array","items":{"type":"string"},"default":[],"description":"Specific contact fields to include in the response. Use `GET /v1/contacts/fields` to discover valid contact field names."}}},"examples":{"byListIdAndCrmPresence":{"summary":"Filter contacts by contact list ID and CRM presence","value":{"page":1,"pageSize":25,"search":"growth","fields":["firstName","lastName","jobTitle","companyName","professionalEmail"],"include":{"leadsGroup":[123],"isInCRM":[true]}}},"byIdsAndCompanyFields":{"summary":"Filter contacts by contact IDs and company-backed fields","value":{"page":1,"pageSize":25,"include":{"id":[101,205],"companyName":["Stripe","HubSpot"],"industry":["Software"],"numberOfEmployees":["50","500"]},"exclude":{"campaigns":[77]}}},"scoringFieldExample":{"summary":"Filter contacts by a workspace-specific scoring field from the fields endpoint","value":{"page":1,"pageSize":25,"include":{"leadsGroup":[123],"icpScore":["80","100"]}}}}}}},"responses":{"200":{"description":"Successful response with paginated contacts","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the contact"},"firstName":{"type":["string","null"],"description":"First name of the contact"},"lastName":{"type":["string","null"],"description":"Last name of the contact"},"jobTitle":{"type":["string","null"],"description":"Job title of the contact"},"linkedInProfileUrl":{"type":["string","null"],"description":"LinkedIn profile URL of the contact"},"professionalEmail":{"type":["string","null"],"description":"Professional email address of the contact"},"personalEmails":{"type":["string","null"],"description":"Personal email addresses (comma-separated)"},"mobilePhone":{"type":["string","null"],"description":"Mobile phone number of the contact"},"phones":{"type":["string","null"],"description":"Other phone numbers (comma-separated)"},"imageUrl":{"type":["string","null"],"description":"Profile image URL"},"companyId":{"type":["number","null"],"description":"ID of the company associated with the contact"},"company":{"type":["object","null"],"properties":{"id":{"type":"number","description":"Company ID"},"name":{"type":["string","null"],"description":"Company name"},"domain":{"type":["string","null"],"description":"Company website domain"},"companyLinkedInUrl":{"type":["string","null"],"description":"Company LinkedIn URL"}},"required":["id","name","domain","companyLinkedInUrl"],"description":"Company details"},"emailVerificationStatus":{"type":"string","description":"Email verification status"},"contactCountry":{"type":["string","null"],"description":"Country of the contact"},"linkedInHeadline":{"type":["string","null"],"description":"LinkedIn headline"},"numberOfConnections":{"type":["number","null"],"description":"Number of LinkedIn connections"},"contactCRMId":{"type":["string","null"],"description":"CRM contact ID"},"leadCRMId":{"type":["string","null"],"description":"CRM lead ID"},"isInCRM":{"type":"boolean","description":"Whether the contact is synced with CRM"},"smartFieldExplanations":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of smart field names to their explanation (returned when smart fields are requested)."},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the contact was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the contact was last updated"}},"required":["id","firstName","lastName","jobTitle","linkedInProfileUrl","professionalEmail","personalEmails","mobilePhone","phones","imageUrl","companyId","company","emailVerificationStatus","contactCountry","linkedInHeadline","numberOfConnections","contactCRMId","leadCRMId","isInCRM","createdAt","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}},"404":{"description":"Actions run not found (when filtering by actionsId)"}}}},"/v1/contact/{contactId}":{"get":{"summary":"Get a single contact","description":"Retrieve a single contact by ID.\n\n    > **Required scope:** `CONTACTS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Contacts"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The contact ID"},"required":true,"description":"The contact ID","name":"contactId","in":"path"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Specific contact fields to include in the response (comma-separated or array). Use `GET /v1/contacts/fields` to discover valid contact field names."},"required":false,"description":"Specific contact fields to include in the response (comma-separated or array). Use `GET /v1/contacts/fields` to discover valid contact field names.","name":"fields","in":"query"}],"responses":{"200":{"description":"Successful response with contact details","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the contact"},"firstName":{"type":["string","null"],"description":"First name of the contact"},"lastName":{"type":["string","null"],"description":"Last name of the contact"},"jobTitle":{"type":["string","null"],"description":"Job title of the contact"},"linkedInProfileUrl":{"type":["string","null"],"description":"LinkedIn profile URL of the contact"},"professionalEmail":{"type":["string","null"],"description":"Professional email address of the contact"},"personalEmails":{"type":["string","null"],"description":"Personal email addresses (comma-separated)"},"mobilePhone":{"type":["string","null"],"description":"Mobile phone number of the contact"},"phones":{"type":["string","null"],"description":"Other phone numbers (comma-separated)"},"imageUrl":{"type":["string","null"],"description":"Profile image URL"},"companyId":{"type":["number","null"],"description":"ID of the company associated with the contact"},"company":{"type":["object","null"],"properties":{"id":{"type":"number","description":"Company ID"},"name":{"type":["string","null"],"description":"Company name"},"domain":{"type":["string","null"],"description":"Company website domain"},"companyLinkedInUrl":{"type":["string","null"],"description":"Company LinkedIn URL"}},"required":["id","name","domain","companyLinkedInUrl"],"description":"Company details"},"emailVerificationStatus":{"type":"string","description":"Email verification status"},"contactCountry":{"type":["string","null"],"description":"Country of the contact"},"linkedInHeadline":{"type":["string","null"],"description":"LinkedIn headline"},"numberOfConnections":{"type":["number","null"],"description":"Number of LinkedIn connections"},"contactCRMId":{"type":["string","null"],"description":"CRM contact ID"},"leadCRMId":{"type":["string","null"],"description":"CRM lead ID"},"isInCRM":{"type":"boolean","description":"Whether the contact is synced with CRM"},"smartFieldExplanations":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of smart field names to their explanation (returned when smart fields are requested)."},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the contact was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the contact was last updated"}},"required":["id","firstName","lastName","jobTitle","linkedInProfileUrl","professionalEmail","personalEmails","mobilePhone","phones","imageUrl","companyId","company","emailVerificationStatus","contactCountry","linkedInHeadline","numberOfConnections","contactCRMId","leadCRMId","isInCRM","createdAt","updatedAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid contact ID"},"404":{"description":"Contact not found"}}},"patch":{"summary":"Update contact fields","description":"Update contact fields (standard and custom/AI fields by name). You can also set `companyId` to associate the contact with an existing company, or `null` to clear the current association..\n\n    > **Required scope:** `CONTACTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute\n\nAccepted standard fields (auto-updated):\n- linkedInProfileId\n- firstName\n- jobTitle\n- lastName\n- linkedinProfileUrl\n- personalEmails\n- phones\n- professionalEmail\n- mobilePhone\n- geoRegion\n- leadCountry\n- profileBio\n- yearsInCompany\n- yearsInRole\n- lastLinkedInPost\n- jobChange\n- mentionedInNews\n- promotion\n- leadCRMId\n- previousPositions\n- languages\n- linkedInHeadline\n- companyId (special association field; use an existing company ID or null)\n\nCustom/AI fields are also allowed by name and are client-specific.","tags":["Contacts"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The contact ID"},"required":true,"description":"The contact ID","name":"contactId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{},"description":"Fields to update on the contact. Supports standard and custom/AI fields by name. Use `GET /v1/contacts/fields` to discover valid contact field names for `fields`, `include`, `exclude`, and update payloads."},"examples":{"basic":{"summary":"Update standard contact fields","value":{"firstName":"Ada","lastName":"Lovelace","jobTitle":"CTO","linkedInProfileUrl":"https://www.linkedin.com/in/adalovelace","contactCountry":"United States"}},"updateAssociation":{"summary":"Associate the contact with an existing company","value":{"companyId":12345}},"withCustomFields":{"summary":"Update custom/AI fields by name","value":{"customFieldName":"Value from API","contactAiVariable":"Generated summary"}},"clearField":{"summary":"Clear a field using null","value":{"mobilePhone":null}}}}}},"responses":{"200":{"description":"Contact updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the contact"},"firstName":{"type":["string","null"],"description":"First name of the contact"},"lastName":{"type":["string","null"],"description":"Last name of the contact"},"jobTitle":{"type":["string","null"],"description":"Job title of the contact"},"linkedInProfileUrl":{"type":["string","null"],"description":"LinkedIn profile URL of the contact"},"professionalEmail":{"type":["string","null"],"description":"Professional email address of the contact"},"personalEmails":{"type":["string","null"],"description":"Personal email addresses (comma-separated)"},"mobilePhone":{"type":["string","null"],"description":"Mobile phone number of the contact"},"phones":{"type":["string","null"],"description":"Other phone numbers (comma-separated)"},"imageUrl":{"type":["string","null"],"description":"Profile image URL"},"companyId":{"type":["number","null"],"description":"ID of the company associated with the contact"},"company":{"type":["object","null"],"properties":{"id":{"type":"number","description":"Company ID"},"name":{"type":["string","null"],"description":"Company name"},"domain":{"type":["string","null"],"description":"Company website domain"},"companyLinkedInUrl":{"type":["string","null"],"description":"Company LinkedIn URL"}},"required":["id","name","domain","companyLinkedInUrl"],"description":"Company details"},"emailVerificationStatus":{"type":"string","description":"Email verification status"},"contactCountry":{"type":["string","null"],"description":"Country of the contact"},"linkedInHeadline":{"type":["string","null"],"description":"LinkedIn headline"},"numberOfConnections":{"type":["number","null"],"description":"Number of LinkedIn connections"},"contactCRMId":{"type":["string","null"],"description":"CRM contact ID"},"leadCRMId":{"type":["string","null"],"description":"CRM lead ID"},"isInCRM":{"type":"boolean","description":"Whether the contact is synced with CRM"},"smartFieldExplanations":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of smart field names to their explanation (returned when smart fields are requested)."},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the contact was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the contact was last updated"}},"required":["id","firstName","lastName","jobTitle","linkedInProfileUrl","professionalEmail","personalEmails","mobilePhone","phones","imageUrl","companyId","company","emailVerificationStatus","contactCountry","linkedInHeadline","numberOfConnections","contactCRMId","leadCRMId","isInCRM","createdAt","updatedAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid fields or values"},"404":{"description":"Contact not found"}}},"delete":{"summary":"Delete a contact","description":"Soft delete a contact by ID and remove it from contact lists..\n\n    > **Required scope:** `CONTACTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Contacts"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The contact ID"},"required":true,"description":"The contact ID","name":"contactId","in":"path"}],"responses":{"200":{"description":"Contact deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"ID of the deleted contact"},"deleted":{"type":"boolean","enum":[true],"description":"Whether the contact was deleted"}},"required":["id","deleted"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid contact ID"},"404":{"description":"Contact not found"}}}},"/v1/contact":{"post":{"summary":"Create a new contact","description":"Create a new contact. If `mergeWithExisting` is true (default), the contact will merge into an existing record matched by normalized LinkedIn profile URL, or by exact first name + last name + company name. If the provided company already exists, the contact will also be associated with a company matched by normalized LinkedIn URL, domain, website, or exact name, and that company will be updated with the provided data. Set `mergeWithExisting` to false to always create a new contact and company..\n\n    > **Required scope:** `CONTACTS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Contacts"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string","description":"First name of the contact"},"lastName":{"type":"string","description":"Last name of the contact"},"professionalEmail":{"type":"string","format":"email","description":"Professional email address of the contact"},"jobTitle":{"type":"string","description":"Job title of the contact"},"linkedInProfileUrl":{"type":"string","format":"uri","description":"LinkedIn profile URL of the contact"},"mobilePhone":{"type":"string","description":"Mobile phone number of the contact"},"phones":{"type":"string","description":"Other phone numbers (comma-separated)"},"linkedInHeadline":{"type":"string","description":"LinkedIn headline"},"contactCountry":{"type":"string","description":"Country of the contact"},"company":{"type":"object","properties":{"name":{"type":"string","description":"Company name"},"domain":{"type":"string","description":"Company website domain"},"companyLinkedInUrl":{"type":"string","format":"uri","description":"Company LinkedIn URL"},"industry":{"type":"string","description":"Industry sector"},"website":{"type":"string","format":"uri","description":"Company website URL"}},"additionalProperties":{},"description":"Company information to associate with the contact"},"companyName":{"type":"string","description":"Alias for `company.name` when creating or matching the associated company"},"companyDomain":{"type":"string","description":"Alias for `company.domain` when creating or matching the associated company"},"companyLinkedInUrl":{"type":"string","format":"uri","description":"Alias for `company.companyLinkedInUrl` when creating or matching the associated company"},"companyIndustry":{"type":"string","description":"Alias for `company.industry`"},"companyWebsite":{"type":"string","format":"uri","description":"Alias for `company.website`"},"listId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the list to add the contact to"},"mergeWithExisting":{"type":"boolean","default":true,"description":"Whether to merge with an existing contact or company. Contact matches use normalized LinkedIn profile URL, or exact first name + last name + company name. Company matches use normalized LinkedIn URL, domain, website, or exact name. Defaults to true."}},"additionalProperties":{}},"examples":{"nestedCompany":{"summary":"Create a contact with nested company data","value":{"firstName":"Ada","lastName":"Lovelace","company":{"name":"Analytical Engines","domain":"analytical-engines.com"},"mergeWithExisting":true}},"companyAliases":{"summary":"Create a contact using top-level company aliases","value":{"firstName":"Ada","lastName":"Lovelace","companyName":"Analytical Engines","companyDomain":"analytical-engines.com","mergeWithExisting":true}}}}}},"responses":{"201":{"description":"Contact created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"ID of the created or updated contact"},"firstName":{"type":["string","null"],"description":"First name of the contact"},"lastName":{"type":["string","null"],"description":"Last name of the contact"},"professionalEmail":{"type":["string","null"],"description":"Professional email address"},"linkedinProfileUrl":{"type":["string","null"],"description":"LinkedIn profile URL"},"companyId":{"type":["number","null"],"description":"ID of the associated company"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the contact was created"},"contactOutcome":{"type":"string","enum":["CREATED","MERGED_UPDATED","MERGED_NOOP"],"description":"Whether the contact was newly created or merged"},"contactMatchedBy":{"type":"string","enum":["LINKEDIN_URL","NAME_COMPANY"],"description":"How an existing contact was matched when mergeWithExisting reused a record"},"companyOutcome":{"type":"string","enum":["NONE","CREATED","MERGED_UPDATED","MERGED_NOOP"],"description":"Whether the associated company was created, merged, or left unchanged"},"companyMatchedBy":{"type":"string","enum":["LINKEDIN_URL","DOMAIN","WEBSITE","NAME"],"description":"How an existing company was matched when mergeWithExisting reused a record"},"warnings":{"type":"array","items":{"type":"string"},"description":"Non-fatal warnings describing merge or no-op behavior"}},"required":["id","firstName","lastName","professionalEmail","linkedinProfileUrl","companyId","createdAt","contactOutcome","companyOutcome","warnings"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error or list not found"},"500":{"description":"Internal server error"}}}},"/v1/company":{"post":{"summary":"Create a new company","description":"Create a new company. If `mergeWithExisting` is true (default), the company will merge into an existing record matched by normalized LinkedIn URL, domain, website, or exact name. Set `mergeWithExisting` to false to always create a new company..\n\n    > **Required scope:** `COMPANIES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Companies"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Company name"},"domain":{"type":"string","description":"Company website domain"},"website":{"type":"string","format":"uri","description":"Company website URL"},"companyLinkedInUrl":{"type":"string","format":"uri","description":"Company LinkedIn URL"},"listId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the list to add the company to"},"mergeWithExisting":{"type":"boolean","default":true,"description":"Whether to merge with an existing company matched by normalized LinkedIn URL, domain, website, or exact name. Defaults to true."}},"additionalProperties":{}}}}},"responses":{"201":{"description":"Company created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"ID of the created or updated company"},"name":{"type":["string","null"],"description":"Company name"},"domain":{"type":["string","null"],"description":"Company website domain"},"companyLinkedInUrl":{"type":["string","null"],"description":"Company LinkedIn URL"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the company was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the company was last updated"},"outcome":{"type":"string","enum":["CREATED","MERGED_UPDATED","MERGED_NOOP"],"description":"Whether the company was newly created or merged"},"matchedBy":{"type":"string","enum":["LINKEDIN_URL","DOMAIN","WEBSITE","NAME"],"description":"How an existing company was matched when mergeWithExisting reused a record"},"warnings":{"type":"array","items":{"type":"string"},"description":"Non-fatal warnings describing merge or no-op behavior"}},"required":["id","name","domain","companyLinkedInUrl","createdAt","updatedAt","outcome","warnings"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error or list not found"},"500":{"description":"Internal server error"}}}},"/v1/companies":{"get":{"summary":"Get companies","description":"Retrieve a paginated list of companies.\n\n    > **Required scope:** `COMPANIES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Companies"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","default":"1","description":"Page number for pagination. Minimum value is 1. Defaults to 1."},"required":false,"description":"Page number for pagination. Minimum value is 1. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"string","default":"25","description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25."},"required":false,"description":"Number of items per page. Minimum is 1, maximum is 100. Defaults to 25.","name":"pageSize","in":"query"},{"schema":{"type":"string","description":"Search term to filter companies by name or domain (case-insensitive)."},"required":false,"description":"Search term to filter companies by name or domain (case-insensitive).","name":"search","in":"query"},{"schema":{"type":"string","description":"Filter companies by list ID."},"required":false,"description":"Filter companies by list ID.","name":"listId","in":"query"},{"schema":{"type":"string","description":"Filter companies updated on or after this date (ISO 8601 format)."},"required":false,"description":"Filter companies updated on or after this date (ISO 8601 format).","name":"updatedAtFrom","in":"query"},{"schema":{"type":"string","description":"Filter companies updated on or before this date (ISO 8601 format)."},"required":false,"description":"Filter companies updated on or before this date (ISO 8601 format).","name":"updatedAtTo","in":"query"},{"schema":{"type":"string","description":"Filter companies by a specific actions run ID. Returns only companies that were created or processed as part of this actions run (e.g., from \"Search companies\" action)."},"required":false,"description":"Filter companies by a specific actions run ID. Returns only companies that were created or processed as part of this actions run (e.g., from \"Search companies\" action).","name":"actionsId","in":"query"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Specific company fields to include in the response (comma-separated or array). Use `GET /v1/companies/fields` to discover valid company field names."},"required":false,"description":"Specific company fields to include in the response (comma-separated or array). Use `GET /v1/companies/fields` to discover valid company field names.","name":"fields","in":"query"}],"responses":{"200":{"description":"Successful response with paginated companies","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the company"},"name":{"type":["string","null"],"description":"Company name"},"domain":{"type":["string","null"],"description":"Company website domain"},"website":{"type":["string","null"],"description":"Company website URL"},"companyLinkedInUrl":{"type":["string","null"],"description":"Company LinkedIn URL"},"industry":{"type":["string","null"],"description":"Industry sector"},"rangeOfEmployees":{"type":["string","null"],"description":"Range of employees (e.g., \"11-50\")"},"numberOfEmployees":{"type":["number","null"],"description":"Exact number of employees"},"yearfounded":{"type":["string","null"],"description":"Year the company was founded"},"description":{"type":["string","null"],"description":"Company description"},"country":{"type":["string","null"],"description":"Company country"},"city":{"type":["string","null"],"description":"Company city"},"streetAddress":{"type":["string","null"],"description":"Company street address"},"phoneNumber":{"type":["string","null"],"description":"Company phone number"},"companyEmail":{"type":["string","null"],"description":"Company email address"},"revenueRange":{"type":["string","null"],"description":"Company revenue range"},"hiringOnLinkedIn":{"type":"boolean","description":"Whether the company is actively hiring on LinkedIn"},"openJobPositions":{"type":["number","null"],"description":"Number of open job positions"},"companyCRMId":{"type":["string","null"],"description":"CRM company ID"},"isCompanyInCRM":{"type":"boolean","description":"Whether the company is synced with CRM"},"smartFieldExplanations":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of smart field names to their explanation (returned when smart fields are requested)."},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the company was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the company was last updated"}},"required":["id","name","domain","website","companyLinkedInUrl","industry","rangeOfEmployees","numberOfEmployees","yearfounded","description","country","city","streetAddress","phoneNumber","companyEmail","revenueRange","hiringOnLinkedIn","openJobPositions","companyCRMId","isCompanyInCRM","createdAt","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}}},"/v1/companies/search":{"post":{"summary":"Search companies with advanced filters","description":"Search companies with advanced filtering options.\n\n    > **Required scope:** `COMPANIES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Companies"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"default":1,"description":"Page number for pagination. Minimum value is 1."},"pageSize":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Number of items per page. Minimum is 1, maximum is 100."},"search":{"type":"string","description":"Search term for full-text search across company fields."},"include":{"type":"object","additionalProperties":{},"default":{},"description":"Filter conditions to include. Supports special filters like `id`, `companyGroup`, `campaigns`, `leadsCount`, `isCompanyInCRM`, and any company field ID returned by the fields endpoint. Filter values should match the field data type returned by `GET /v1/companies/fields`: text/select fields use arrays of exact values, numeric fields use two-item range arrays like `[\"10\",\"100\"]`, boolean fields use one-item arrays like `[true]`, and timestamp fields use `{ \"startDate\": \"...\", \"endDate\": \"...\" }`. Start with `id`, `companyGroup` (company list IDs), `campaigns`, `leadsCount`, `isCompanyInCRM`, and any workspace scoring fields such as `icpScore` or `scoreBand` when those field IDs appear in the fields response. Use `GET /v1/companies/fields` to discover valid company field names for `fields`, `include`, `exclude`, and update payloads."},"exclude":{"type":"object","additionalProperties":{},"default":{},"description":"Filter conditions to exclude. Same structure as include. Filter values should match the field data type returned by `GET /v1/companies/fields`: text/select fields use arrays of exact values, numeric fields use two-item range arrays like `[\"10\",\"100\"]`, boolean fields use one-item arrays like `[true]`, and timestamp fields use `{ \"startDate\": \"...\", \"endDate\": \"...\" }`. Start with `id`, `companyGroup` (company list IDs), `campaigns`, `leadsCount`, `isCompanyInCRM`, and any workspace scoring fields such as `icpScore` or `scoreBand` when those field IDs appear in the fields response. Use `GET /v1/companies/fields` to discover valid company field names for `fields`, `include`, `exclude`, and update payloads."}}},"examples":{"byListIdAndSize":{"summary":"Filter companies by company list ID and employee range","value":{"page":1,"pageSize":25,"search":"analytics","include":{"companyGroup":[42],"industry":["Software"],"numberOfEmployees":["50","500"]}}},"byIdsAndLeadCount":{"summary":"Filter companies by company IDs, lead count, and CRM presence","value":{"page":1,"pageSize":25,"include":{"id":[101,205],"leadsCount":["5","50"],"isCompanyInCRM":[true]},"exclude":{"campaigns":[88]}}},"scoringFieldExample":{"summary":"Filter companies by a workspace-specific scoring field from the fields endpoint","value":{"page":1,"pageSize":25,"include":{"companyGroup":[42],"scoreBand":["A"]}}}}}}},"responses":{"200":{"description":"Successful response with paginated companies","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the company"},"name":{"type":["string","null"],"description":"Company name"},"domain":{"type":["string","null"],"description":"Company website domain"},"website":{"type":["string","null"],"description":"Company website URL"},"companyLinkedInUrl":{"type":["string","null"],"description":"Company LinkedIn URL"},"industry":{"type":["string","null"],"description":"Industry sector"},"rangeOfEmployees":{"type":["string","null"],"description":"Range of employees (e.g., \"11-50\")"},"numberOfEmployees":{"type":["number","null"],"description":"Exact number of employees"},"yearfounded":{"type":["string","null"],"description":"Year the company was founded"},"description":{"type":["string","null"],"description":"Company description"},"country":{"type":["string","null"],"description":"Company country"},"city":{"type":["string","null"],"description":"Company city"},"streetAddress":{"type":["string","null"],"description":"Company street address"},"phoneNumber":{"type":["string","null"],"description":"Company phone number"},"companyEmail":{"type":["string","null"],"description":"Company email address"},"revenueRange":{"type":["string","null"],"description":"Company revenue range"},"hiringOnLinkedIn":{"type":"boolean","description":"Whether the company is actively hiring on LinkedIn"},"openJobPositions":{"type":["number","null"],"description":"Number of open job positions"},"companyCRMId":{"type":["string","null"],"description":"CRM company ID"},"isCompanyInCRM":{"type":"boolean","description":"Whether the company is synced with CRM"},"smartFieldExplanations":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of smart field names to their explanation (returned when smart fields are requested)."},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the company was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the company was last updated"}},"required":["id","name","domain","website","companyLinkedInUrl","industry","rangeOfEmployees","numberOfEmployees","yearfounded","description","country","city","streetAddress","phoneNumber","companyEmail","revenueRange","hiringOnLinkedIn","openJobPositions","companyCRMId","isCompanyInCRM","createdAt","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}}},"/v1/company/{companyId}":{"get":{"summary":"Get a single company","description":"Retrieve a single company by ID.\n\n    > **Required scope:** `COMPANIES_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Companies"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The company ID"},"required":true,"description":"The company ID","name":"companyId","in":"path"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Specific company fields to include in the response (comma-separated or array). Use `GET /v1/companies/fields` to discover valid company field names."},"required":false,"description":"Specific company fields to include in the response (comma-separated or array). Use `GET /v1/companies/fields` to discover valid company field names.","name":"fields","in":"query"}],"responses":{"200":{"description":"Successful response with company details","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the company"},"name":{"type":["string","null"],"description":"Company name"},"domain":{"type":["string","null"],"description":"Company website domain"},"website":{"type":["string","null"],"description":"Company website URL"},"companyLinkedInUrl":{"type":["string","null"],"description":"Company LinkedIn URL"},"industry":{"type":["string","null"],"description":"Industry sector"},"rangeOfEmployees":{"type":["string","null"],"description":"Range of employees (e.g., \"11-50\")"},"numberOfEmployees":{"type":["number","null"],"description":"Exact number of employees"},"yearfounded":{"type":["string","null"],"description":"Year the company was founded"},"description":{"type":["string","null"],"description":"Company description"},"country":{"type":["string","null"],"description":"Company country"},"city":{"type":["string","null"],"description":"Company city"},"streetAddress":{"type":["string","null"],"description":"Company street address"},"phoneNumber":{"type":["string","null"],"description":"Company phone number"},"companyEmail":{"type":["string","null"],"description":"Company email address"},"revenueRange":{"type":["string","null"],"description":"Company revenue range"},"hiringOnLinkedIn":{"type":"boolean","description":"Whether the company is actively hiring on LinkedIn"},"openJobPositions":{"type":["number","null"],"description":"Number of open job positions"},"companyCRMId":{"type":["string","null"],"description":"CRM company ID"},"isCompanyInCRM":{"type":"boolean","description":"Whether the company is synced with CRM"},"smartFieldExplanations":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of smart field names to their explanation (returned when smart fields are requested)."},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the company was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the company was last updated"}},"required":["id","name","domain","website","companyLinkedInUrl","industry","rangeOfEmployees","numberOfEmployees","yearfounded","description","country","city","streetAddress","phoneNumber","companyEmail","revenueRange","hiringOnLinkedIn","openJobPositions","companyCRMId","isCompanyInCRM","createdAt","updatedAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid company ID"},"404":{"description":"Company not found"}}},"patch":{"summary":"Update company fields","description":"Update company fields (standard and custom/AI fields by name).\n\n    > **Required scope:** `COMPANIES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute\n\nAccepted standard fields (auto-updated):\n- name\n- companyUrn\n- companyLinkedInUrl\n- website\n- domain\n- industry\n- rangeOfEmployees\n- numberOfEmployees\n- yearfounded\n- description\n- country\n- city\n- streetAddress\n- hiringOnLinkedIn\n- phoneNumber\n- companyEmail\n- openJobPositions\n- revenueRange\n- sixMonthsHeadcountGrowth\n- twoYearsHeadcountGrowth\n- yearlyHeadcountGrowth\n- legalCode\n- legalName\n- globalUltimateCode\n- lastLinkedInPost\n- googleMapsOpeningHours\n- taxId\n\nCustom/AI fields are also allowed by name and are client-specific.","tags":["Companies"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The company ID"},"required":true,"description":"The company ID","name":"companyId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{},"description":"Fields to update on the company. Supports standard and custom/AI fields by name. Use `GET /v1/companies/fields` to discover valid company field names for `fields`, `include`, `exclude`, and update payloads."},"examples":{"basic":{"summary":"Update standard company fields","value":{"name":"Acme Inc.","website":"https://acme.com","industry":"Software","numberOfEmployees":120}},"withCustomFields":{"summary":"Update custom/AI fields by name","value":{"companyAiVariable":"Key market insight","customCompanyField":"Value from API"}},"clearField":{"summary":"Clear a field using null","value":{"phoneNumber":null}}}}}},"responses":{"200":{"description":"Company updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the company"},"name":{"type":["string","null"],"description":"Company name"},"domain":{"type":["string","null"],"description":"Company website domain"},"website":{"type":["string","null"],"description":"Company website URL"},"companyLinkedInUrl":{"type":["string","null"],"description":"Company LinkedIn URL"},"industry":{"type":["string","null"],"description":"Industry sector"},"rangeOfEmployees":{"type":["string","null"],"description":"Range of employees (e.g., \"11-50\")"},"numberOfEmployees":{"type":["number","null"],"description":"Exact number of employees"},"yearfounded":{"type":["string","null"],"description":"Year the company was founded"},"description":{"type":["string","null"],"description":"Company description"},"country":{"type":["string","null"],"description":"Company country"},"city":{"type":["string","null"],"description":"Company city"},"streetAddress":{"type":["string","null"],"description":"Company street address"},"phoneNumber":{"type":["string","null"],"description":"Company phone number"},"companyEmail":{"type":["string","null"],"description":"Company email address"},"revenueRange":{"type":["string","null"],"description":"Company revenue range"},"hiringOnLinkedIn":{"type":"boolean","description":"Whether the company is actively hiring on LinkedIn"},"openJobPositions":{"type":["number","null"],"description":"Number of open job positions"},"companyCRMId":{"type":["string","null"],"description":"CRM company ID"},"isCompanyInCRM":{"type":"boolean","description":"Whether the company is synced with CRM"},"smartFieldExplanations":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of smart field names to their explanation (returned when smart fields are requested)."},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the company was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the company was last updated"}},"required":["id","name","domain","website","companyLinkedInUrl","industry","rangeOfEmployees","numberOfEmployees","yearfounded","description","country","city","streetAddress","phoneNumber","companyEmail","revenueRange","hiringOnLinkedIn","openJobPositions","companyCRMId","isCompanyInCRM","createdAt","updatedAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid fields or values"},"404":{"description":"Company not found"}}},"delete":{"summary":"Delete a company","description":"Soft delete a company by ID and remove it from company lists..\n\n    > **Required scope:** `COMPANIES_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Companies"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The company ID"},"required":true,"description":"The company ID","name":"companyId","in":"path"}],"responses":{"200":{"description":"Company deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"ID of the deleted company"},"deleted":{"type":"boolean","enum":[true],"description":"Whether the company was deleted"}},"required":["id","deleted"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid company ID"},"404":{"description":"Company not found"}}}},"/v1/analytics/conversations":{"get":{"summary":"Get conversations analytics","description":"Retrieve row conversation analytics data with contact and campaign information.\n\n    > **Required scope:** `ANALYTICS_READ`\n    >\n    > **Rate limit:** 10 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Filter by user IDs who created the campaigns (comma-separated or array)."},"required":false,"description":"Filter by user IDs who created the campaigns (comma-separated or array).","name":"createdByIds","in":"query"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Filter by sender identity IDs (comma-separated or array)."},"required":false,"description":"Filter by sender identity IDs (comma-separated or array).","name":"identityIds","in":"query"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Filter by campaign IDs (comma-separated or array)."},"required":false,"description":"Filter by campaign IDs (comma-separated or array).","name":"campaignIds","in":"query"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Filter by campaign tag IDs (comma-separated or array)."},"required":false,"description":"Filter by campaign tag IDs (comma-separated or array).","name":"campaignTags","in":"query"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Filter by conversation tag IDs (comma-separated or array)."},"required":false,"description":"Filter by conversation tag IDs (comma-separated or array).","name":"conversationTags","in":"query"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Date range filter as [startDate, endDate] in ISO format. Defaults to last 30 days."},"required":false,"description":"Date range filter as [startDate, endDate] in ISO format. Defaults to last 30 days.","name":"dateRange","in":"query"},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Specific contact fields to include in the response (comma-separated or array). Use `GET /v1/contacts/fields` to discover valid contact field names."},"required":false,"description":"Specific contact fields to include in the response (comma-separated or array). Use `GET /v1/contacts/fields` to discover valid contact field names.","name":"fields","in":"query"},{"schema":{"type":"string","enum":["CONTACT","USER"],"description":"Filter by who sent the last message: CONTACT (contact sent last message) or USER (sender sent last message)."},"required":false,"description":"Filter by who sent the last message: CONTACT (contact sent last message) or USER (sender sent last message).","name":"lastMessageSentBy","in":"query"}],"responses":{"200":{"description":"Successful response with row conversation analytics","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"conversationId":{"type":"number","description":"Unique identifier for the conversation"},"firstMessageAt":{"type":"string","description":"Timestamp when the first message was sent"},"contactId":{"type":"number","description":"Contact ID"},"campaignId":{"type":"number","description":"Campaign ID"},"linkedinSent":{"type":"number","description":"Number of LinkedIn messages sent"},"linkedinReplied":{"type":"number","description":"Number of LinkedIn replies received"},"emailSent":{"type":"number","description":"Number of emails sent"},"emailOpened":{"type":"number","description":"Number of email opens"},"emailClicked":{"type":"number","description":"Number of email clicks"},"emailReplied":{"type":"number","description":"Number of email replies received"},"conversationTags":{"type":["string","null"],"description":"Comma-separated list of conversation tags"},"campaignName":{"type":"string","description":"Name of the campaign"},"campaignStatus":{"type":"string","description":"Status of the campaign"},"identityName":{"type":"string","description":"Name of the sender identity"},"companyId":{"type":["number","null"],"description":"Company ID associated with the contact"},"isArchived":{"type":"boolean","description":"Whether the conversation contact has been archived"},"lastMessageSentBy":{"type":["string","null"],"enum":["CONTACT","USER",null],"description":"Who sent the last message: CONTACT or USER"}},"required":["conversationId","firstMessageAt","contactId","campaignId","linkedinSent","linkedinReplied","emailSent","emailOpened","emailClicked","emailReplied","conversationTags","campaignName","campaignStatus","identityName","companyId","isArchived","lastMessageSentBy"]}}}}}}}},"/v1/actions":{"post":{"summary":"Start an actions run","description":"Creates an actions run to execute one or more workflow actions on contacts, companies, or lists. Supports optional webhook notifications when actions complete. See the \"Actions Completed Webhook\" in the Webhooks section for the webhook payload structure and implementation details.\n\nAction reference:\n- `VERIFY_LEAD_EMAIL`: Verify the deliverability and validity of an email address Targets: Contacts only. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_EMAIL` for the current workspace credit cost.\n- `VERIFY_LEAD_PHONE`: Verify the validity and type of a phone number Targets: Contacts only. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_PHONE` for the current workspace credit cost.\n- `SCRAPE_LEAD_FROM_LINKEDIN`: Extract contact information from their LinkedIn profile Targets: Contacts only. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost.\n- `LINKEDIN_FROM_NAME_LASTNAME_COMPANY`: Find LinkedIn profile URL using first name, last name and company name Targets: Contacts only. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost.\n- `SCRAPE_COMPANY_FROM_LINKEDIN`: Extract company information from their LinkedIn profile Targets: Companies only. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost.\n- `COMPANY_LINKEDIN_FROM_NAME`: Find company LinkedIn profile URL using company name Targets: Companies only. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost.\n- `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN`: Extract AI-powered insights about a company from LinkedIn Targets: Companies only. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN` for the current workspace credit cost.\n- `ENRICH_WITH_EMAIL`: Find and enrich contact with professional email addresses Targets: Contacts only. Pricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_EMAIL` for the current workspace credit cost.\n- `ENRICH_WITH_PHONE`: Find and enrich contact with phone numbers Targets: Contacts only. Pricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_PHONE` for the current workspace credit cost.\n- `FILL_LEAD_WITH_SMART_FIELDS`: Generate AI variable values for selected contact fields Targets: Contacts only. Pricing: call `GET /v1/credits/pricing` and look up action `FILL_LEAD_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost.\n- `FILL_COMPANY_WITH_SMART_FIELDS`: Generate AI variable values for selected company fields Targets: Companies only. Pricing: call `GET /v1/credits/pricing` and look up action `FILL_COMPANY_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost.\n- `SEARCH_LEADS_FROM_LINKEDIN_COMPANY`: Search and import contacts working at a specific company from LinkedIn Targets: Companies only. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost.\n- `EXPORT_TO_CRM`: Export contacts or companies to your connected CRM system Targets: Contacts or companies, depending on the IDs you provide. Pricing: this action does not expose a credit-mapped entry in `GET /v1/credits/pricing`.\n\nNotes:\n- Provide exactly one target selector: `contactIds`, `companyIds`, `contactGroupIds`, or `companyGroupIds`.\n- Per-action option fields are documented on each item in the `actions` array.\n- Credit costs are workspace-specific; call `GET /v1/credits/pricing` before starting a run if you need the current cost table.\n\n    > **Required scope:** `ACTIONS_WRITE`\n    >\n    > **Rate limit:** 10 requests per minute","tags":["Actions"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["VERIFY_LEAD_EMAIL"],"description":"Verify email. Verify the deliverability and validity of an email address\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with at least one email already stored in Enginy.\n\nBehavior:\n- Verifies the stored email address and writes the verification result back to the contact.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `VERIFY_EMAIL` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Verify email. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_EMAIL` for the current workspace credit cost."}},"required":["type"],"title":"Verify email"},{"type":"object","properties":{"type":{"type":"string","enum":["VERIFY_LEAD_PHONE"],"description":"Verify phone. Verify the validity and type of a phone number\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with at least one phone number already stored in Enginy.\n\nBehavior:\n- Verifies the stored phone number and writes the verification result back to the contact.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `VERIFY_PHONE` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Verify phone. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_PHONE` for the current workspace credit cost."}},"required":["type"],"title":"Verify phone"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_LEAD_FROM_LINKEDIN"],"description":"Scrape contact from LinkedIn. Extract contact information from their LinkedIn profile\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with a LinkedIn profile URL in Enginy.\n\nBehavior:\n- Scrapes the LinkedIn profile, refreshes contact fields, and can optionally skip the follow-up company scrape.\n\nAccepted options:\n- `skipContactMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy contact.\n- `skipCompanyScrape` (boolean): update the contact only and skip the associated company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipContactMerge":{"type":"boolean","default":true,"description":"Whether to skip contact merge if a duplicate is found in Enginy"},"skipCompanyScrape":{"type":"boolean","description":"Whether to skip company scrape"}},"description":"Options for Scrape contact from LinkedIn:\n- `skipContactMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy contact.\n- `skipCompanyScrape` (boolean): update the contact only and skip the associated company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape contact from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["LINKEDIN_FROM_NAME_LASTNAME_COMPANY"],"description":"Find LinkedIn URL by name. Find LinkedIn profile URL using first name, last name and company name\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with first name, last name, and company name.\n\nBehavior:\n- Searches for the contact LinkedIn profile URL and stores it on the contact record.\n\nAccepted options:\n- `skipCompanyScrape` (boolean): once the profile is found, skip the follow-up company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipCompanyScrape":{"type":"boolean","description":"Whether to skip company scrape"}},"description":"Options for Find LinkedIn URL by name:\n- `skipCompanyScrape` (boolean): once the profile is found, skip the follow-up company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Find LinkedIn URL by name"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_COMPANY_FROM_LINKEDIN"],"description":"Scrape company from LinkedIn. Extract company information from their LinkedIn profile\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL in Enginy.\n\nBehavior:\n- Scrapes the LinkedIn company page and refreshes company fields in Enginy.\n\nAccepted options:\n- `skipCompanyMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy company.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipCompanyMerge":{"type":"boolean","default":true,"description":"Whether to skip company merge if a duplicate is found in Enginy"}},"description":"Options for Scrape company from LinkedIn:\n- `skipCompanyMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy company.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape company from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["COMPANY_LINKEDIN_FROM_NAME"],"description":"Find company LinkedIn URL by name. Find company LinkedIn profile URL using company name\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a company name.\n\nBehavior:\n- Searches for the company LinkedIn URL and stores it on the company record.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Find company LinkedIn URL by name. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Find company LinkedIn URL by name"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN"],"description":"Scrape company Account IQ from LinkedIn. Extract AI-powered insights about a company from LinkedIn\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL in Enginy.\n\nBehavior:\n- Runs the Account IQ LinkedIn workflow to extract AI-generated company insights from LinkedIn.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Scrape company Account IQ from LinkedIn. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape company Account IQ from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["ENRICH_WITH_EMAIL"],"description":"Enrich with email. Find and enrich contact with professional email addresses\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with enough identifying data for enrichment, such as name and company or a LinkedIn URL.\n\nBehavior:\n- Runs the configured enrichment providers until an email is found or the selected stop condition is reached.\n\nAccepted options:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_EMAIL` for the current workspace credit cost."},"options":{"type":"object","properties":{"sortedApis":{"type":"array","items":{"type":"string"},"description":"Ordered list of enrichment APIs to use (e.g., [\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]). Will try each API in order until an email is found. If not provided, default APIs will be used."},"stopType":{"type":"string","enum":["NONE","VERIFIED_EMAIL","PHONE"],"description":"When to stop enrichment: NONE (try all APIs), VERIFIED_EMAIL (stop when verified email found), PHONE (stop when phone found)"},"speed":{"type":"string","enum":["SLOW","FAST"],"description":"Enrichment speed: SLOW for more thorough results, FAST for quicker processing"},"maxTimeToWait":{"type":"number","description":"Maximum time to wait for enrichment in milliseconds"}},"description":"Options for Enrich with email:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_EMAIL` for the current workspace credit cost."}},"required":["type"],"title":"Enrich with email"},{"type":"object","properties":{"type":{"type":"string","enum":["ENRICH_WITH_PHONE"],"description":"Enrich with phone. Find and enrich contact with phone numbers\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with enough identifying data for enrichment, such as name and company or a LinkedIn URL.\n\nBehavior:\n- Runs the configured enrichment providers until a phone number is found or the selected stop condition is reached.\n\nAccepted options:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_PHONE` for the current workspace credit cost."},"options":{"type":"object","properties":{"sortedApis":{"type":"array","items":{"type":"string"},"description":"Ordered list of enrichment APIs to use (e.g., [\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]). Will try each API in order until a phone is found. If not provided, default APIs will be used."},"stopType":{"type":"string","enum":["NONE","VERIFIED_EMAIL","PHONE"],"description":"When to stop enrichment: NONE (try all APIs), VERIFIED_EMAIL (stop when verified email found), PHONE (stop when phone found)"},"speed":{"type":"string","enum":["SLOW","FAST"],"description":"Enrichment speed: SLOW for more thorough results, FAST for quicker processing"},"maxTimeToWait":{"type":"number","description":"Maximum time to wait for enrichment in milliseconds"}},"description":"Options for Enrich with phone:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_PHONE` for the current workspace credit cost."}},"required":["type"],"title":"Enrich with phone"},{"type":"object","properties":{"type":{"type":"string","enum":["FILL_LEAD_WITH_SMART_FIELDS"],"description":"Run contact AI variables. Generate AI variable values for selected contact fields\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact plus one or more existing contact AI variable names.\n\nBehavior:\n- Runs the selected contact AI variables and writes the generated values back to the contact.\n\nAccepted options:\n- `fields` (string[]): required list of contact AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_LEAD_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."},"options":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"Array of contact AI variable names to run"}},"required":["fields"],"description":"Options for Run contact AI variables:\n- `fields` (string[]): required list of contact AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_LEAD_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."}},"required":["type","options"],"title":"Run contact AI variables"},{"type":"object","properties":{"type":{"type":"string","enum":["FILL_COMPANY_WITH_SMART_FIELDS"],"description":"Run company AI variables. Generate AI variable values for selected company fields\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company plus one or more existing company AI variable names.\n\nBehavior:\n- Runs the selected company AI variables and writes the generated values back to the company.\n\nAccepted options:\n- `fields` (string[]): required list of company AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_COMPANY_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."},"options":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"Array of company AI variable names to run"}},"required":["fields"],"description":"Options for Run company AI variables:\n- `fields` (string[]): required list of company AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_COMPANY_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."}},"required":["type","options"],"title":"Run company AI variables"},{"type":"object","properties":{"type":{"type":"string","enum":["SEARCH_LEADS_FROM_LINKEDIN_COMPANY"],"description":"Search contacts from company. Search and import contacts working at a specific company from LinkedIn\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL or company identity that can be resolved to the target LinkedIn company.\n\nBehavior:\n- Searches LinkedIn for people at the target company and imports the discovered contacts into Enginy.\n\nAccepted options:\n- `maxLeadsToImport` (number): maximum contacts to import from this company, default 5 and max 10.\n- `keyword` (string | string[]): search terms such as titles, roles, or seniority hints.\n- `filters` (record): raw LinkedIn filter payload for the search. Prefer `savedFilterId` when possible.\n- `destinationContactGroupId` (number): add newly discovered contacts to this contact list.\n- `savedFilterId` (number): reuse a saved LinkedIn filter from `GET /v1/saved-filters`; request-level `filters` and `keyword` override the saved values.\n- `onlyIncludeIfCompanyUrnMatch` (boolean): keep results only when LinkedIn resolves them to the exact target company URN.\n- `importOnlyNewContacts` (boolean): skip contacts already present in Enginy.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"maxLeadsToImport":{"type":"number","exclusiveMinimum":0,"maximum":10,"default":5,"description":"Maximum number of contacts to import from the company (default: 5, max: 10)"},"keyword":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Keyword or array of keywords to filter contacts (e.g., job titles, roles)"},"filters":{"type":"object","additionalProperties":{},"description":"LinkedIn search filters to apply when searching for contacts"},"destinationContactGroupId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the contact list to add newly discovered contacts to"},"savedFilterId":{"type":"integer","exclusiveMinimum":0,"description":"ID of a saved filter to use. Retrieve available filters via GET /v1/saved-filters. When provided, the saved filter settings (filters and keywords) will be used. Any filters or keywords provided in this request will override the saved filter values."},"onlyIncludeIfCompanyUrnMatch":{"type":"boolean","description":"Only include contacts if their company URN exactly matches the target company"},"importOnlyNewContacts":{"type":"boolean","description":"Only import contacts that are not already in your database"}},"description":"Options for Search contacts from company:\n- `maxLeadsToImport` (number): maximum contacts to import from this company, default 5 and max 10.\n- `keyword` (string | string[]): search terms such as titles, roles, or seniority hints.\n- `filters` (record): raw LinkedIn filter payload for the search. Prefer `savedFilterId` when possible.\n- `destinationContactGroupId` (number): add newly discovered contacts to this contact list.\n- `savedFilterId` (number): reuse a saved LinkedIn filter from `GET /v1/saved-filters`; request-level `filters` and `keyword` override the saved values.\n- `onlyIncludeIfCompanyUrnMatch` (boolean): keep results only when LinkedIn resolves them to the exact target company URN.\n- `importOnlyNewContacts` (boolean): skip contacts already present in Enginy.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Search contacts from company"},{"type":"object","properties":{"type":{"type":"string","enum":["EXPORT_TO_CRM"],"description":"Export to CRM. Export contacts or companies to your connected CRM system\n\nTargets:\n- Contacts or companies, depending on the IDs you provide.\n\nRequired data:\n- Records that can be exported through an already connected CRM integration for the workspace.\n\nBehavior:\n- Exports Enginy records into the connected CRM, optionally mapping and overriding fields.\n\nAccepted options:\n- `CRMOwnerId`: set the target CRM owner and whether to override an existing owner.\n- `promptLeadFieldsCRMMapping`: map Enginy contact fields into CRM fields with per-field override control.\n- `promptCompanyFieldsCRMMapping`: map Enginy company fields into CRM fields with per-field override control.\n- `overwriteFields` (record): explicit field overwrite switches keyed by CRM field name.\n- `associationType` (string): CRM-specific association type to create.\n- `exportAssociatedObject` (boolean): also export related objects, such as the company when exporting a contact.\n\nPricing: this action does not expose a credit-mapped entry in `GET /v1/credits/pricing`."},"options":{"type":"object","properties":{"CRMOwnerId":{"type":"object","properties":{"value":{"type":"string","description":"CRM owner/user ID"},"override":{"type":"boolean","description":"Whether to override existing owner"}},"required":["value","override"],"description":"CRM owner configuration"},"promptLeadFieldsCRMMapping":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string","description":"Field value"},"override":{"type":"boolean","description":"Whether to override existing value"}},"required":["value","override"]},"description":"Custom field mappings for contact/lead fields"},"promptCompanyFieldsCRMMapping":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string","description":"Field value"},"override":{"type":"boolean","description":"Whether to override existing value"}},"required":["value","override"]},"description":"Custom field mappings for company/organization fields"},"overwriteFields":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Fields to overwrite in CRM (field name as key, boolean as value)"},"associationType":{"type":"string","description":"Type of association to create in CRM"},"exportAssociatedObject":{"type":"boolean","description":"Whether to also export associated objects (e.g., company when exporting contact)"}},"description":"Options for Export to CRM:\n- `CRMOwnerId`: set the target CRM owner and whether to override an existing owner.\n- `promptLeadFieldsCRMMapping`: map Enginy contact fields into CRM fields with per-field override control.\n- `promptCompanyFieldsCRMMapping`: map Enginy company fields into CRM fields with per-field override control.\n- `overwriteFields` (record): explicit field overwrite switches keyed by CRM field name.\n- `associationType` (string): CRM-specific association type to create.\n- `exportAssociatedObject` (boolean): also export related objects, such as the company when exporting a contact.\n\nPricing: this action does not expose a credit-mapped entry in `GET /v1/credits/pricing`."}},"required":["type"],"title":"Export to CRM"}]},"minItems":1,"description":"Array of actions to execute. Each action type documents its required data, behavior, accepted options, and how to look up credit pricing."},"contactIds":{"type":"array","items":{"type":"number"},"minItems":1,"description":"Array of contact IDs to run actions on"},"webhookUrl":{"type":"string","format":"uri","description":"Optional webhook URL to receive notification when actions complete. Must be HTTPS in production."}},"required":["actions","contactIds"],"additionalProperties":false,"description":"Run actions on specific contacts"},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["VERIFY_LEAD_EMAIL"],"description":"Verify email. Verify the deliverability and validity of an email address\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with at least one email already stored in Enginy.\n\nBehavior:\n- Verifies the stored email address and writes the verification result back to the contact.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `VERIFY_EMAIL` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Verify email. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_EMAIL` for the current workspace credit cost."}},"required":["type"],"title":"Verify email"},{"type":"object","properties":{"type":{"type":"string","enum":["VERIFY_LEAD_PHONE"],"description":"Verify phone. Verify the validity and type of a phone number\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with at least one phone number already stored in Enginy.\n\nBehavior:\n- Verifies the stored phone number and writes the verification result back to the contact.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `VERIFY_PHONE` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Verify phone. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_PHONE` for the current workspace credit cost."}},"required":["type"],"title":"Verify phone"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_LEAD_FROM_LINKEDIN"],"description":"Scrape contact from LinkedIn. Extract contact information from their LinkedIn profile\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with a LinkedIn profile URL in Enginy.\n\nBehavior:\n- Scrapes the LinkedIn profile, refreshes contact fields, and can optionally skip the follow-up company scrape.\n\nAccepted options:\n- `skipContactMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy contact.\n- `skipCompanyScrape` (boolean): update the contact only and skip the associated company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipContactMerge":{"type":"boolean","default":true,"description":"Whether to skip contact merge if a duplicate is found in Enginy"},"skipCompanyScrape":{"type":"boolean","description":"Whether to skip company scrape"}},"description":"Options for Scrape contact from LinkedIn:\n- `skipContactMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy contact.\n- `skipCompanyScrape` (boolean): update the contact only and skip the associated company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape contact from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["LINKEDIN_FROM_NAME_LASTNAME_COMPANY"],"description":"Find LinkedIn URL by name. Find LinkedIn profile URL using first name, last name and company name\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with first name, last name, and company name.\n\nBehavior:\n- Searches for the contact LinkedIn profile URL and stores it on the contact record.\n\nAccepted options:\n- `skipCompanyScrape` (boolean): once the profile is found, skip the follow-up company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipCompanyScrape":{"type":"boolean","description":"Whether to skip company scrape"}},"description":"Options for Find LinkedIn URL by name:\n- `skipCompanyScrape` (boolean): once the profile is found, skip the follow-up company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Find LinkedIn URL by name"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_COMPANY_FROM_LINKEDIN"],"description":"Scrape company from LinkedIn. Extract company information from their LinkedIn profile\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL in Enginy.\n\nBehavior:\n- Scrapes the LinkedIn company page and refreshes company fields in Enginy.\n\nAccepted options:\n- `skipCompanyMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy company.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipCompanyMerge":{"type":"boolean","default":true,"description":"Whether to skip company merge if a duplicate is found in Enginy"}},"description":"Options for Scrape company from LinkedIn:\n- `skipCompanyMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy company.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape company from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["COMPANY_LINKEDIN_FROM_NAME"],"description":"Find company LinkedIn URL by name. Find company LinkedIn profile URL using company name\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a company name.\n\nBehavior:\n- Searches for the company LinkedIn URL and stores it on the company record.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Find company LinkedIn URL by name. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Find company LinkedIn URL by name"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN"],"description":"Scrape company Account IQ from LinkedIn. Extract AI-powered insights about a company from LinkedIn\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL in Enginy.\n\nBehavior:\n- Runs the Account IQ LinkedIn workflow to extract AI-generated company insights from LinkedIn.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Scrape company Account IQ from LinkedIn. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape company Account IQ from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["ENRICH_WITH_EMAIL"],"description":"Enrich with email. Find and enrich contact with professional email addresses\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with enough identifying data for enrichment, such as name and company or a LinkedIn URL.\n\nBehavior:\n- Runs the configured enrichment providers until an email is found or the selected stop condition is reached.\n\nAccepted options:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_EMAIL` for the current workspace credit cost."},"options":{"type":"object","properties":{"sortedApis":{"type":"array","items":{"type":"string"},"description":"Ordered list of enrichment APIs to use (e.g., [\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]). Will try each API in order until an email is found. If not provided, default APIs will be used."},"stopType":{"type":"string","enum":["NONE","VERIFIED_EMAIL","PHONE"],"description":"When to stop enrichment: NONE (try all APIs), VERIFIED_EMAIL (stop when verified email found), PHONE (stop when phone found)"},"speed":{"type":"string","enum":["SLOW","FAST"],"description":"Enrichment speed: SLOW for more thorough results, FAST for quicker processing"},"maxTimeToWait":{"type":"number","description":"Maximum time to wait for enrichment in milliseconds"}},"description":"Options for Enrich with email:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_EMAIL` for the current workspace credit cost."}},"required":["type"],"title":"Enrich with email"},{"type":"object","properties":{"type":{"type":"string","enum":["ENRICH_WITH_PHONE"],"description":"Enrich with phone. Find and enrich contact with phone numbers\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with enough identifying data for enrichment, such as name and company or a LinkedIn URL.\n\nBehavior:\n- Runs the configured enrichment providers until a phone number is found or the selected stop condition is reached.\n\nAccepted options:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_PHONE` for the current workspace credit cost."},"options":{"type":"object","properties":{"sortedApis":{"type":"array","items":{"type":"string"},"description":"Ordered list of enrichment APIs to use (e.g., [\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]). Will try each API in order until a phone is found. If not provided, default APIs will be used."},"stopType":{"type":"string","enum":["NONE","VERIFIED_EMAIL","PHONE"],"description":"When to stop enrichment: NONE (try all APIs), VERIFIED_EMAIL (stop when verified email found), PHONE (stop when phone found)"},"speed":{"type":"string","enum":["SLOW","FAST"],"description":"Enrichment speed: SLOW for more thorough results, FAST for quicker processing"},"maxTimeToWait":{"type":"number","description":"Maximum time to wait for enrichment in milliseconds"}},"description":"Options for Enrich with phone:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_PHONE` for the current workspace credit cost."}},"required":["type"],"title":"Enrich with phone"},{"type":"object","properties":{"type":{"type":"string","enum":["FILL_LEAD_WITH_SMART_FIELDS"],"description":"Run contact AI variables. Generate AI variable values for selected contact fields\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact plus one or more existing contact AI variable names.\n\nBehavior:\n- Runs the selected contact AI variables and writes the generated values back to the contact.\n\nAccepted options:\n- `fields` (string[]): required list of contact AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_LEAD_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."},"options":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"Array of contact AI variable names to run"}},"required":["fields"],"description":"Options for Run contact AI variables:\n- `fields` (string[]): required list of contact AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_LEAD_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."}},"required":["type","options"],"title":"Run contact AI variables"},{"type":"object","properties":{"type":{"type":"string","enum":["FILL_COMPANY_WITH_SMART_FIELDS"],"description":"Run company AI variables. Generate AI variable values for selected company fields\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company plus one or more existing company AI variable names.\n\nBehavior:\n- Runs the selected company AI variables and writes the generated values back to the company.\n\nAccepted options:\n- `fields` (string[]): required list of company AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_COMPANY_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."},"options":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"Array of company AI variable names to run"}},"required":["fields"],"description":"Options for Run company AI variables:\n- `fields` (string[]): required list of company AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_COMPANY_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."}},"required":["type","options"],"title":"Run company AI variables"},{"type":"object","properties":{"type":{"type":"string","enum":["SEARCH_LEADS_FROM_LINKEDIN_COMPANY"],"description":"Search contacts from company. Search and import contacts working at a specific company from LinkedIn\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL or company identity that can be resolved to the target LinkedIn company.\n\nBehavior:\n- Searches LinkedIn for people at the target company and imports the discovered contacts into Enginy.\n\nAccepted options:\n- `maxLeadsToImport` (number): maximum contacts to import from this company, default 5 and max 10.\n- `keyword` (string | string[]): search terms such as titles, roles, or seniority hints.\n- `filters` (record): raw LinkedIn filter payload for the search. Prefer `savedFilterId` when possible.\n- `destinationContactGroupId` (number): add newly discovered contacts to this contact list.\n- `savedFilterId` (number): reuse a saved LinkedIn filter from `GET /v1/saved-filters`; request-level `filters` and `keyword` override the saved values.\n- `onlyIncludeIfCompanyUrnMatch` (boolean): keep results only when LinkedIn resolves them to the exact target company URN.\n- `importOnlyNewContacts` (boolean): skip contacts already present in Enginy.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"maxLeadsToImport":{"type":"number","exclusiveMinimum":0,"maximum":10,"default":5,"description":"Maximum number of contacts to import from the company (default: 5, max: 10)"},"keyword":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Keyword or array of keywords to filter contacts (e.g., job titles, roles)"},"filters":{"type":"object","additionalProperties":{},"description":"LinkedIn search filters to apply when searching for contacts"},"destinationContactGroupId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the contact list to add newly discovered contacts to"},"savedFilterId":{"type":"integer","exclusiveMinimum":0,"description":"ID of a saved filter to use. Retrieve available filters via GET /v1/saved-filters. When provided, the saved filter settings (filters and keywords) will be used. Any filters or keywords provided in this request will override the saved filter values."},"onlyIncludeIfCompanyUrnMatch":{"type":"boolean","description":"Only include contacts if their company URN exactly matches the target company"},"importOnlyNewContacts":{"type":"boolean","description":"Only import contacts that are not already in your database"}},"description":"Options for Search contacts from company:\n- `maxLeadsToImport` (number): maximum contacts to import from this company, default 5 and max 10.\n- `keyword` (string | string[]): search terms such as titles, roles, or seniority hints.\n- `filters` (record): raw LinkedIn filter payload for the search. Prefer `savedFilterId` when possible.\n- `destinationContactGroupId` (number): add newly discovered contacts to this contact list.\n- `savedFilterId` (number): reuse a saved LinkedIn filter from `GET /v1/saved-filters`; request-level `filters` and `keyword` override the saved values.\n- `onlyIncludeIfCompanyUrnMatch` (boolean): keep results only when LinkedIn resolves them to the exact target company URN.\n- `importOnlyNewContacts` (boolean): skip contacts already present in Enginy.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Search contacts from company"},{"type":"object","properties":{"type":{"type":"string","enum":["EXPORT_TO_CRM"],"description":"Export to CRM. Export contacts or companies to your connected CRM system\n\nTargets:\n- Contacts or companies, depending on the IDs you provide.\n\nRequired data:\n- Records that can be exported through an already connected CRM integration for the workspace.\n\nBehavior:\n- Exports Enginy records into the connected CRM, optionally mapping and overriding fields.\n\nAccepted options:\n- `CRMOwnerId`: set the target CRM owner and whether to override an existing owner.\n- `promptLeadFieldsCRMMapping`: map Enginy contact fields into CRM fields with per-field override control.\n- `promptCompanyFieldsCRMMapping`: map Enginy company fields into CRM fields with per-field override control.\n- `overwriteFields` (record): explicit field overwrite switches keyed by CRM field name.\n- `associationType` (string): CRM-specific association type to create.\n- `exportAssociatedObject` (boolean): also export related objects, such as the company when exporting a contact.\n\nPricing: this action does not expose a credit-mapped entry in `GET /v1/credits/pricing`."},"options":{"type":"object","properties":{"CRMOwnerId":{"type":"object","properties":{"value":{"type":"string","description":"CRM owner/user ID"},"override":{"type":"boolean","description":"Whether to override existing owner"}},"required":["value","override"],"description":"CRM owner configuration"},"promptLeadFieldsCRMMapping":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string","description":"Field value"},"override":{"type":"boolean","description":"Whether to override existing value"}},"required":["value","override"]},"description":"Custom field mappings for contact/lead fields"},"promptCompanyFieldsCRMMapping":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string","description":"Field value"},"override":{"type":"boolean","description":"Whether to override existing value"}},"required":["value","override"]},"description":"Custom field mappings for company/organization fields"},"overwriteFields":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Fields to overwrite in CRM (field name as key, boolean as value)"},"associationType":{"type":"string","description":"Type of association to create in CRM"},"exportAssociatedObject":{"type":"boolean","description":"Whether to also export associated objects (e.g., company when exporting contact)"}},"description":"Options for Export to CRM:\n- `CRMOwnerId`: set the target CRM owner and whether to override an existing owner.\n- `promptLeadFieldsCRMMapping`: map Enginy contact fields into CRM fields with per-field override control.\n- `promptCompanyFieldsCRMMapping`: map Enginy company fields into CRM fields with per-field override control.\n- `overwriteFields` (record): explicit field overwrite switches keyed by CRM field name.\n- `associationType` (string): CRM-specific association type to create.\n- `exportAssociatedObject` (boolean): also export related objects, such as the company when exporting a contact.\n\nPricing: this action does not expose a credit-mapped entry in `GET /v1/credits/pricing`."}},"required":["type"],"title":"Export to CRM"}]},"minItems":1,"description":"Array of actions to execute. Each action type documents its required data, behavior, accepted options, and how to look up credit pricing."},"companyIds":{"type":"array","items":{"type":"number"},"minItems":1,"description":"Array of company IDs to run actions on"},"webhookUrl":{"type":"string","format":"uri","description":"Optional webhook URL to receive notification when actions complete. Must be HTTPS in production."}},"required":["actions","companyIds"],"additionalProperties":false,"description":"Run actions on specific companies"},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["VERIFY_LEAD_EMAIL"],"description":"Verify email. Verify the deliverability and validity of an email address\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with at least one email already stored in Enginy.\n\nBehavior:\n- Verifies the stored email address and writes the verification result back to the contact.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `VERIFY_EMAIL` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Verify email. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_EMAIL` for the current workspace credit cost."}},"required":["type"],"title":"Verify email"},{"type":"object","properties":{"type":{"type":"string","enum":["VERIFY_LEAD_PHONE"],"description":"Verify phone. Verify the validity and type of a phone number\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with at least one phone number already stored in Enginy.\n\nBehavior:\n- Verifies the stored phone number and writes the verification result back to the contact.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `VERIFY_PHONE` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Verify phone. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_PHONE` for the current workspace credit cost."}},"required":["type"],"title":"Verify phone"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_LEAD_FROM_LINKEDIN"],"description":"Scrape contact from LinkedIn. Extract contact information from their LinkedIn profile\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with a LinkedIn profile URL in Enginy.\n\nBehavior:\n- Scrapes the LinkedIn profile, refreshes contact fields, and can optionally skip the follow-up company scrape.\n\nAccepted options:\n- `skipContactMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy contact.\n- `skipCompanyScrape` (boolean): update the contact only and skip the associated company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipContactMerge":{"type":"boolean","default":true,"description":"Whether to skip contact merge if a duplicate is found in Enginy"},"skipCompanyScrape":{"type":"boolean","description":"Whether to skip company scrape"}},"description":"Options for Scrape contact from LinkedIn:\n- `skipContactMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy contact.\n- `skipCompanyScrape` (boolean): update the contact only and skip the associated company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape contact from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["LINKEDIN_FROM_NAME_LASTNAME_COMPANY"],"description":"Find LinkedIn URL by name. Find LinkedIn profile URL using first name, last name and company name\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with first name, last name, and company name.\n\nBehavior:\n- Searches for the contact LinkedIn profile URL and stores it on the contact record.\n\nAccepted options:\n- `skipCompanyScrape` (boolean): once the profile is found, skip the follow-up company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipCompanyScrape":{"type":"boolean","description":"Whether to skip company scrape"}},"description":"Options for Find LinkedIn URL by name:\n- `skipCompanyScrape` (boolean): once the profile is found, skip the follow-up company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Find LinkedIn URL by name"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_COMPANY_FROM_LINKEDIN"],"description":"Scrape company from LinkedIn. Extract company information from their LinkedIn profile\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL in Enginy.\n\nBehavior:\n- Scrapes the LinkedIn company page and refreshes company fields in Enginy.\n\nAccepted options:\n- `skipCompanyMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy company.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipCompanyMerge":{"type":"boolean","default":true,"description":"Whether to skip company merge if a duplicate is found in Enginy"}},"description":"Options for Scrape company from LinkedIn:\n- `skipCompanyMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy company.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape company from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["COMPANY_LINKEDIN_FROM_NAME"],"description":"Find company LinkedIn URL by name. Find company LinkedIn profile URL using company name\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a company name.\n\nBehavior:\n- Searches for the company LinkedIn URL and stores it on the company record.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Find company LinkedIn URL by name. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Find company LinkedIn URL by name"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN"],"description":"Scrape company Account IQ from LinkedIn. Extract AI-powered insights about a company from LinkedIn\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL in Enginy.\n\nBehavior:\n- Runs the Account IQ LinkedIn workflow to extract AI-generated company insights from LinkedIn.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Scrape company Account IQ from LinkedIn. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape company Account IQ from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["ENRICH_WITH_EMAIL"],"description":"Enrich with email. Find and enrich contact with professional email addresses\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with enough identifying data for enrichment, such as name and company or a LinkedIn URL.\n\nBehavior:\n- Runs the configured enrichment providers until an email is found or the selected stop condition is reached.\n\nAccepted options:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_EMAIL` for the current workspace credit cost."},"options":{"type":"object","properties":{"sortedApis":{"type":"array","items":{"type":"string"},"description":"Ordered list of enrichment APIs to use (e.g., [\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]). Will try each API in order until an email is found. If not provided, default APIs will be used."},"stopType":{"type":"string","enum":["NONE","VERIFIED_EMAIL","PHONE"],"description":"When to stop enrichment: NONE (try all APIs), VERIFIED_EMAIL (stop when verified email found), PHONE (stop when phone found)"},"speed":{"type":"string","enum":["SLOW","FAST"],"description":"Enrichment speed: SLOW for more thorough results, FAST for quicker processing"},"maxTimeToWait":{"type":"number","description":"Maximum time to wait for enrichment in milliseconds"}},"description":"Options for Enrich with email:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_EMAIL` for the current workspace credit cost."}},"required":["type"],"title":"Enrich with email"},{"type":"object","properties":{"type":{"type":"string","enum":["ENRICH_WITH_PHONE"],"description":"Enrich with phone. Find and enrich contact with phone numbers\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with enough identifying data for enrichment, such as name and company or a LinkedIn URL.\n\nBehavior:\n- Runs the configured enrichment providers until a phone number is found or the selected stop condition is reached.\n\nAccepted options:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_PHONE` for the current workspace credit cost."},"options":{"type":"object","properties":{"sortedApis":{"type":"array","items":{"type":"string"},"description":"Ordered list of enrichment APIs to use (e.g., [\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]). Will try each API in order until a phone is found. If not provided, default APIs will be used."},"stopType":{"type":"string","enum":["NONE","VERIFIED_EMAIL","PHONE"],"description":"When to stop enrichment: NONE (try all APIs), VERIFIED_EMAIL (stop when verified email found), PHONE (stop when phone found)"},"speed":{"type":"string","enum":["SLOW","FAST"],"description":"Enrichment speed: SLOW for more thorough results, FAST for quicker processing"},"maxTimeToWait":{"type":"number","description":"Maximum time to wait for enrichment in milliseconds"}},"description":"Options for Enrich with phone:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_PHONE` for the current workspace credit cost."}},"required":["type"],"title":"Enrich with phone"},{"type":"object","properties":{"type":{"type":"string","enum":["FILL_LEAD_WITH_SMART_FIELDS"],"description":"Run contact AI variables. Generate AI variable values for selected contact fields\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact plus one or more existing contact AI variable names.\n\nBehavior:\n- Runs the selected contact AI variables and writes the generated values back to the contact.\n\nAccepted options:\n- `fields` (string[]): required list of contact AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_LEAD_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."},"options":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"Array of contact AI variable names to run"}},"required":["fields"],"description":"Options for Run contact AI variables:\n- `fields` (string[]): required list of contact AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_LEAD_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."}},"required":["type","options"],"title":"Run contact AI variables"},{"type":"object","properties":{"type":{"type":"string","enum":["FILL_COMPANY_WITH_SMART_FIELDS"],"description":"Run company AI variables. Generate AI variable values for selected company fields\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company plus one or more existing company AI variable names.\n\nBehavior:\n- Runs the selected company AI variables and writes the generated values back to the company.\n\nAccepted options:\n- `fields` (string[]): required list of company AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_COMPANY_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."},"options":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"Array of company AI variable names to run"}},"required":["fields"],"description":"Options for Run company AI variables:\n- `fields` (string[]): required list of company AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_COMPANY_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."}},"required":["type","options"],"title":"Run company AI variables"},{"type":"object","properties":{"type":{"type":"string","enum":["SEARCH_LEADS_FROM_LINKEDIN_COMPANY"],"description":"Search contacts from company. Search and import contacts working at a specific company from LinkedIn\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL or company identity that can be resolved to the target LinkedIn company.\n\nBehavior:\n- Searches LinkedIn for people at the target company and imports the discovered contacts into Enginy.\n\nAccepted options:\n- `maxLeadsToImport` (number): maximum contacts to import from this company, default 5 and max 10.\n- `keyword` (string | string[]): search terms such as titles, roles, or seniority hints.\n- `filters` (record): raw LinkedIn filter payload for the search. Prefer `savedFilterId` when possible.\n- `destinationContactGroupId` (number): add newly discovered contacts to this contact list.\n- `savedFilterId` (number): reuse a saved LinkedIn filter from `GET /v1/saved-filters`; request-level `filters` and `keyword` override the saved values.\n- `onlyIncludeIfCompanyUrnMatch` (boolean): keep results only when LinkedIn resolves them to the exact target company URN.\n- `importOnlyNewContacts` (boolean): skip contacts already present in Enginy.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"maxLeadsToImport":{"type":"number","exclusiveMinimum":0,"maximum":10,"default":5,"description":"Maximum number of contacts to import from the company (default: 5, max: 10)"},"keyword":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Keyword or array of keywords to filter contacts (e.g., job titles, roles)"},"filters":{"type":"object","additionalProperties":{},"description":"LinkedIn search filters to apply when searching for contacts"},"destinationContactGroupId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the contact list to add newly discovered contacts to"},"savedFilterId":{"type":"integer","exclusiveMinimum":0,"description":"ID of a saved filter to use. Retrieve available filters via GET /v1/saved-filters. When provided, the saved filter settings (filters and keywords) will be used. Any filters or keywords provided in this request will override the saved filter values."},"onlyIncludeIfCompanyUrnMatch":{"type":"boolean","description":"Only include contacts if their company URN exactly matches the target company"},"importOnlyNewContacts":{"type":"boolean","description":"Only import contacts that are not already in your database"}},"description":"Options for Search contacts from company:\n- `maxLeadsToImport` (number): maximum contacts to import from this company, default 5 and max 10.\n- `keyword` (string | string[]): search terms such as titles, roles, or seniority hints.\n- `filters` (record): raw LinkedIn filter payload for the search. Prefer `savedFilterId` when possible.\n- `destinationContactGroupId` (number): add newly discovered contacts to this contact list.\n- `savedFilterId` (number): reuse a saved LinkedIn filter from `GET /v1/saved-filters`; request-level `filters` and `keyword` override the saved values.\n- `onlyIncludeIfCompanyUrnMatch` (boolean): keep results only when LinkedIn resolves them to the exact target company URN.\n- `importOnlyNewContacts` (boolean): skip contacts already present in Enginy.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Search contacts from company"},{"type":"object","properties":{"type":{"type":"string","enum":["EXPORT_TO_CRM"],"description":"Export to CRM. Export contacts or companies to your connected CRM system\n\nTargets:\n- Contacts or companies, depending on the IDs you provide.\n\nRequired data:\n- Records that can be exported through an already connected CRM integration for the workspace.\n\nBehavior:\n- Exports Enginy records into the connected CRM, optionally mapping and overriding fields.\n\nAccepted options:\n- `CRMOwnerId`: set the target CRM owner and whether to override an existing owner.\n- `promptLeadFieldsCRMMapping`: map Enginy contact fields into CRM fields with per-field override control.\n- `promptCompanyFieldsCRMMapping`: map Enginy company fields into CRM fields with per-field override control.\n- `overwriteFields` (record): explicit field overwrite switches keyed by CRM field name.\n- `associationType` (string): CRM-specific association type to create.\n- `exportAssociatedObject` (boolean): also export related objects, such as the company when exporting a contact.\n\nPricing: this action does not expose a credit-mapped entry in `GET /v1/credits/pricing`."},"options":{"type":"object","properties":{"CRMOwnerId":{"type":"object","properties":{"value":{"type":"string","description":"CRM owner/user ID"},"override":{"type":"boolean","description":"Whether to override existing owner"}},"required":["value","override"],"description":"CRM owner configuration"},"promptLeadFieldsCRMMapping":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string","description":"Field value"},"override":{"type":"boolean","description":"Whether to override existing value"}},"required":["value","override"]},"description":"Custom field mappings for contact/lead fields"},"promptCompanyFieldsCRMMapping":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string","description":"Field value"},"override":{"type":"boolean","description":"Whether to override existing value"}},"required":["value","override"]},"description":"Custom field mappings for company/organization fields"},"overwriteFields":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Fields to overwrite in CRM (field name as key, boolean as value)"},"associationType":{"type":"string","description":"Type of association to create in CRM"},"exportAssociatedObject":{"type":"boolean","description":"Whether to also export associated objects (e.g., company when exporting contact)"}},"description":"Options for Export to CRM:\n- `CRMOwnerId`: set the target CRM owner and whether to override an existing owner.\n- `promptLeadFieldsCRMMapping`: map Enginy contact fields into CRM fields with per-field override control.\n- `promptCompanyFieldsCRMMapping`: map Enginy company fields into CRM fields with per-field override control.\n- `overwriteFields` (record): explicit field overwrite switches keyed by CRM field name.\n- `associationType` (string): CRM-specific association type to create.\n- `exportAssociatedObject` (boolean): also export related objects, such as the company when exporting a contact.\n\nPricing: this action does not expose a credit-mapped entry in `GET /v1/credits/pricing`."}},"required":["type"],"title":"Export to CRM"}]},"minItems":1,"description":"Array of actions to execute. Each action type documents its required data, behavior, accepted options, and how to look up credit pricing."},"contactGroupIds":{"type":"array","items":{"type":"number"},"minItems":1,"description":"Array of contact list IDs to run actions on"},"webhookUrl":{"type":"string","format":"uri","description":"Optional webhook URL to receive notification when actions complete. Must be HTTPS in production."}},"required":["actions","contactGroupIds"],"additionalProperties":false,"description":"Run actions on contact lists"},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["VERIFY_LEAD_EMAIL"],"description":"Verify email. Verify the deliverability and validity of an email address\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with at least one email already stored in Enginy.\n\nBehavior:\n- Verifies the stored email address and writes the verification result back to the contact.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `VERIFY_EMAIL` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Verify email. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_EMAIL` for the current workspace credit cost."}},"required":["type"],"title":"Verify email"},{"type":"object","properties":{"type":{"type":"string","enum":["VERIFY_LEAD_PHONE"],"description":"Verify phone. Verify the validity and type of a phone number\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with at least one phone number already stored in Enginy.\n\nBehavior:\n- Verifies the stored phone number and writes the verification result back to the contact.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `VERIFY_PHONE` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Verify phone. Pricing: call `GET /v1/credits/pricing` and look up action `VERIFY_PHONE` for the current workspace credit cost."}},"required":["type"],"title":"Verify phone"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_LEAD_FROM_LINKEDIN"],"description":"Scrape contact from LinkedIn. Extract contact information from their LinkedIn profile\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with a LinkedIn profile URL in Enginy.\n\nBehavior:\n- Scrapes the LinkedIn profile, refreshes contact fields, and can optionally skip the follow-up company scrape.\n\nAccepted options:\n- `skipContactMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy contact.\n- `skipCompanyScrape` (boolean): update the contact only and skip the associated company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipContactMerge":{"type":"boolean","default":true,"description":"Whether to skip contact merge if a duplicate is found in Enginy"},"skipCompanyScrape":{"type":"boolean","description":"Whether to skip company scrape"}},"description":"Options for Scrape contact from LinkedIn:\n- `skipContactMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy contact.\n- `skipCompanyScrape` (boolean): update the contact only and skip the associated company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape contact from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["LINKEDIN_FROM_NAME_LASTNAME_COMPANY"],"description":"Find LinkedIn URL by name. Find LinkedIn profile URL using first name, last name and company name\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with first name, last name, and company name.\n\nBehavior:\n- Searches for the contact LinkedIn profile URL and stores it on the contact record.\n\nAccepted options:\n- `skipCompanyScrape` (boolean): once the profile is found, skip the follow-up company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipCompanyScrape":{"type":"boolean","description":"Whether to skip company scrape"}},"description":"Options for Find LinkedIn URL by name:\n- `skipCompanyScrape` (boolean): once the profile is found, skip the follow-up company scrape.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Find LinkedIn URL by name"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_COMPANY_FROM_LINKEDIN"],"description":"Scrape company from LinkedIn. Extract company information from their LinkedIn profile\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL in Enginy.\n\nBehavior:\n- Scrapes the LinkedIn company page and refreshes company fields in Enginy.\n\nAccepted options:\n- `skipCompanyMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy company.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"skipCompanyMerge":{"type":"boolean","default":true,"description":"Whether to skip company merge if a duplicate is found in Enginy"}},"description":"Options for Scrape company from LinkedIn:\n- `skipCompanyMerge` (boolean): keep duplicates separate instead of merging into an existing Enginy company.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape company from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["COMPANY_LINKEDIN_FROM_NAME"],"description":"Find company LinkedIn URL by name. Find company LinkedIn profile URL using company name\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a company name.\n\nBehavior:\n- Searches for the company LinkedIn URL and stores it on the company record.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Find company LinkedIn URL by name. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Find company LinkedIn URL by name"},{"type":"object","properties":{"type":{"type":"string","enum":["SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN"],"description":"Scrape company Account IQ from LinkedIn. Extract AI-powered insights about a company from LinkedIn\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL in Enginy.\n\nBehavior:\n- Runs the Account IQ LinkedIn workflow to extract AI-generated company insights from LinkedIn.\n\nAccepted options:\n- No options.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{},"description":"No options are required for Scrape company Account IQ from LinkedIn. Pricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_COMPANY_ACCOUNTIQ_FROM_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Scrape company Account IQ from LinkedIn"},{"type":"object","properties":{"type":{"type":"string","enum":["ENRICH_WITH_EMAIL"],"description":"Enrich with email. Find and enrich contact with professional email addresses\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with enough identifying data for enrichment, such as name and company or a LinkedIn URL.\n\nBehavior:\n- Runs the configured enrichment providers until an email is found or the selected stop condition is reached.\n\nAccepted options:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_EMAIL` for the current workspace credit cost."},"options":{"type":"object","properties":{"sortedApis":{"type":"array","items":{"type":"string"},"description":"Ordered list of enrichment APIs to use (e.g., [\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]). Will try each API in order until an email is found. If not provided, default APIs will be used."},"stopType":{"type":"string","enum":["NONE","VERIFIED_EMAIL","PHONE"],"description":"When to stop enrichment: NONE (try all APIs), VERIFIED_EMAIL (stop when verified email found), PHONE (stop when phone found)"},"speed":{"type":"string","enum":["SLOW","FAST"],"description":"Enrichment speed: SLOW for more thorough results, FAST for quicker processing"},"maxTimeToWait":{"type":"number","description":"Maximum time to wait for enrichment in milliseconds"}},"description":"Options for Enrich with email:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_EMAIL` for the current workspace credit cost."}},"required":["type"],"title":"Enrich with email"},{"type":"object","properties":{"type":{"type":"string","enum":["ENRICH_WITH_PHONE"],"description":"Enrich with phone. Find and enrich contact with phone numbers\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact with enough identifying data for enrichment, such as name and company or a LinkedIn URL.\n\nBehavior:\n- Runs the configured enrichment providers until a phone number is found or the selected stop condition is reached.\n\nAccepted options:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_PHONE` for the current workspace credit cost."},"options":{"type":"object","properties":{"sortedApis":{"type":"array","items":{"type":"string"},"description":"Ordered list of enrichment APIs to use (e.g., [\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]). Will try each API in order until a phone is found. If not provided, default APIs will be used."},"stopType":{"type":"string","enum":["NONE","VERIFIED_EMAIL","PHONE"],"description":"When to stop enrichment: NONE (try all APIs), VERIFIED_EMAIL (stop when verified email found), PHONE (stop when phone found)"},"speed":{"type":"string","enum":["SLOW","FAST"],"description":"Enrichment speed: SLOW for more thorough results, FAST for quicker processing"},"maxTimeToWait":{"type":"number","description":"Maximum time to wait for enrichment in milliseconds"}},"description":"Options for Enrich with phone:\n- `sortedApis` (string[]): ordered provider list to try, for example `[\"CREDITS\", \"APOLLO\", \"DROPCONTACT\"]`.\n- `stopType` (`NONE` | `VERIFIED_EMAIL` | `PHONE`): condition that stops the enrichment run early.\n- `speed` (`SLOW` | `FAST`): trade off between completeness and turnaround time.\n- `maxTimeToWait` (number): maximum wait time in milliseconds for the enrichment flow.\n\nPricing: call `GET /v1/credits/pricing` and look up action `ENRICH_LEAD_PHONE` for the current workspace credit cost."}},"required":["type"],"title":"Enrich with phone"},{"type":"object","properties":{"type":{"type":"string","enum":["FILL_LEAD_WITH_SMART_FIELDS"],"description":"Run contact AI variables. Generate AI variable values for selected contact fields\n\nTargets:\n- Contacts only.\n\nRequired data:\n- A contact plus one or more existing contact AI variable names.\n\nBehavior:\n- Runs the selected contact AI variables and writes the generated values back to the contact.\n\nAccepted options:\n- `fields` (string[]): required list of contact AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_LEAD_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."},"options":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"Array of contact AI variable names to run"}},"required":["fields"],"description":"Options for Run contact AI variables:\n- `fields` (string[]): required list of contact AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_LEAD_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."}},"required":["type","options"],"title":"Run contact AI variables"},{"type":"object","properties":{"type":{"type":"string","enum":["FILL_COMPANY_WITH_SMART_FIELDS"],"description":"Run company AI variables. Generate AI variable values for selected company fields\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company plus one or more existing company AI variable names.\n\nBehavior:\n- Runs the selected company AI variables and writes the generated values back to the company.\n\nAccepted options:\n- `fields` (string[]): required list of company AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_COMPANY_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."},"options":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"Array of company AI variable names to run"}},"required":["fields"],"description":"Options for Run company AI variables:\n- `fields` (string[]): required list of company AI variable names to generate.\n\nPricing: call `GET /v1/credits/pricing` and look up action `FILL_COMPANY_WITH_SMART_FIELDS_AVERAGE` for the current workspace credit cost."}},"required":["type","options"],"title":"Run company AI variables"},{"type":"object","properties":{"type":{"type":"string","enum":["SEARCH_LEADS_FROM_LINKEDIN_COMPANY"],"description":"Search contacts from company. Search and import contacts working at a specific company from LinkedIn\n\nTargets:\n- Companies only.\n\nRequired data:\n- A company with a LinkedIn company URL or company identity that can be resolved to the target LinkedIn company.\n\nBehavior:\n- Searches LinkedIn for people at the target company and imports the discovered contacts into Enginy.\n\nAccepted options:\n- `maxLeadsToImport` (number): maximum contacts to import from this company, default 5 and max 10.\n- `keyword` (string | string[]): search terms such as titles, roles, or seniority hints.\n- `filters` (record): raw LinkedIn filter payload for the search. Prefer `savedFilterId` when possible.\n- `destinationContactGroupId` (number): add newly discovered contacts to this contact list.\n- `savedFilterId` (number): reuse a saved LinkedIn filter from `GET /v1/saved-filters`; request-level `filters` and `keyword` override the saved values.\n- `onlyIncludeIfCompanyUrnMatch` (boolean): keep results only when LinkedIn resolves them to the exact target company URN.\n- `importOnlyNewContacts` (boolean): skip contacts already present in Enginy.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."},"options":{"type":"object","properties":{"maxLeadsToImport":{"type":"number","exclusiveMinimum":0,"maximum":10,"default":5,"description":"Maximum number of contacts to import from the company (default: 5, max: 10)"},"keyword":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Keyword or array of keywords to filter contacts (e.g., job titles, roles)"},"filters":{"type":"object","additionalProperties":{},"description":"LinkedIn search filters to apply when searching for contacts"},"destinationContactGroupId":{"type":"integer","exclusiveMinimum":0,"description":"ID of the contact list to add newly discovered contacts to"},"savedFilterId":{"type":"integer","exclusiveMinimum":0,"description":"ID of a saved filter to use. Retrieve available filters via GET /v1/saved-filters. When provided, the saved filter settings (filters and keywords) will be used. Any filters or keywords provided in this request will override the saved filter values."},"onlyIncludeIfCompanyUrnMatch":{"type":"boolean","description":"Only include contacts if their company URN exactly matches the target company"},"importOnlyNewContacts":{"type":"boolean","description":"Only import contacts that are not already in your database"}},"description":"Options for Search contacts from company:\n- `maxLeadsToImport` (number): maximum contacts to import from this company, default 5 and max 10.\n- `keyword` (string | string[]): search terms such as titles, roles, or seniority hints.\n- `filters` (record): raw LinkedIn filter payload for the search. Prefer `savedFilterId` when possible.\n- `destinationContactGroupId` (number): add newly discovered contacts to this contact list.\n- `savedFilterId` (number): reuse a saved LinkedIn filter from `GET /v1/saved-filters`; request-level `filters` and `keyword` override the saved values.\n- `onlyIncludeIfCompanyUrnMatch` (boolean): keep results only when LinkedIn resolves them to the exact target company URN.\n- `importOnlyNewContacts` (boolean): skip contacts already present in Enginy.\n\nPricing: call `GET /v1/credits/pricing` and look up action `SCRAPE_LEAD_LINKEDIN` for the current workspace credit cost."}},"required":["type"],"title":"Search contacts from company"},{"type":"object","properties":{"type":{"type":"string","enum":["EXPORT_TO_CRM"],"description":"Export to CRM. Export contacts or companies to your connected CRM system\n\nTargets:\n- Contacts or companies, depending on the IDs you provide.\n\nRequired data:\n- Records that can be exported through an already connected CRM integration for the workspace.\n\nBehavior:\n- Exports Enginy records into the connected CRM, optionally mapping and overriding fields.\n\nAccepted options:\n- `CRMOwnerId`: set the target CRM owner and whether to override an existing owner.\n- `promptLeadFieldsCRMMapping`: map Enginy contact fields into CRM fields with per-field override control.\n- `promptCompanyFieldsCRMMapping`: map Enginy company fields into CRM fields with per-field override control.\n- `overwriteFields` (record): explicit field overwrite switches keyed by CRM field name.\n- `associationType` (string): CRM-specific association type to create.\n- `exportAssociatedObject` (boolean): also export related objects, such as the company when exporting a contact.\n\nPricing: this action does not expose a credit-mapped entry in `GET /v1/credits/pricing`."},"options":{"type":"object","properties":{"CRMOwnerId":{"type":"object","properties":{"value":{"type":"string","description":"CRM owner/user ID"},"override":{"type":"boolean","description":"Whether to override existing owner"}},"required":["value","override"],"description":"CRM owner configuration"},"promptLeadFieldsCRMMapping":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string","description":"Field value"},"override":{"type":"boolean","description":"Whether to override existing value"}},"required":["value","override"]},"description":"Custom field mappings for contact/lead fields"},"promptCompanyFieldsCRMMapping":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string","description":"Field value"},"override":{"type":"boolean","description":"Whether to override existing value"}},"required":["value","override"]},"description":"Custom field mappings for company/organization fields"},"overwriteFields":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Fields to overwrite in CRM (field name as key, boolean as value)"},"associationType":{"type":"string","description":"Type of association to create in CRM"},"exportAssociatedObject":{"type":"boolean","description":"Whether to also export associated objects (e.g., company when exporting contact)"}},"description":"Options for Export to CRM:\n- `CRMOwnerId`: set the target CRM owner and whether to override an existing owner.\n- `promptLeadFieldsCRMMapping`: map Enginy contact fields into CRM fields with per-field override control.\n- `promptCompanyFieldsCRMMapping`: map Enginy company fields into CRM fields with per-field override control.\n- `overwriteFields` (record): explicit field overwrite switches keyed by CRM field name.\n- `associationType` (string): CRM-specific association type to create.\n- `exportAssociatedObject` (boolean): also export related objects, such as the company when exporting a contact.\n\nPricing: this action does not expose a credit-mapped entry in `GET /v1/credits/pricing`."}},"required":["type"],"title":"Export to CRM"}]},"minItems":1,"description":"Array of actions to execute. Each action type documents its required data, behavior, accepted options, and how to look up credit pricing."},"companyGroupIds":{"type":"array","items":{"type":"number"},"minItems":1,"description":"Array of company list IDs to run actions on"},"webhookUrl":{"type":"string","format":"uri","description":"Optional webhook URL to receive notification when actions complete. Must be HTTPS in production."}},"required":["actions","companyGroupIds"],"additionalProperties":false,"description":"Run actions on company lists"}],"description":"Provide exactly one of contactIds, companyIds, contactGroupIds, or companyGroupIds to choose the target set. Use GET /v1/credits/pricing to inspect the current workspace credit costs before running billable actions."},"examples":{"withWebhook":{"summary":"With webhook notification","value":{"actions":[{"type":"VERIFY_LEAD_EMAIL"}],"contactIds":[123,456],"webhookUrl":"https://your-domain.com/webhooks/enginy"}},"withoutWebhook":{"summary":"Without webhook (polling required)","value":{"actions":[{"type":"VERIFY_LEAD_EMAIL"}],"contactIds":[123,456]}}}}}},"responses":{"201":{"description":"Actions run started successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"actionsId":{"type":"number","description":"Unique identifier for the actions group"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the actions group was created"}},"required":["actionsId","createdAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error or no entities to process"},"500":{"description":"Internal server error"}}}},"/v1/actions/{actionsId}/status":{"get":{"summary":"Get actions run status","description":"Check the status of an actions run.\n\n    > **Required scope:** `ACTIONS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Actions"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"The actions ID returned from the run endpoint"},"required":true,"description":"The actions ID returned from the run endpoint","name":"actionsId","in":"path"}],"responses":{"200":{"description":"Actions group status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"actionsId":{"type":"number","description":"Unique identifier for the actions group"},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"The type of entity"},"overallStatus":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED","QUEUED","CANCELLED","PARTIAL"],"description":"Overall status of the actions group"},"totalActions":{"type":"number","description":"Total number of actions in the group"},"statusCounts":{"type":"object","properties":{"pending":{"type":"number","description":"Number of pending actions"},"processing":{"type":"number","description":"Number of processing actions"},"completed":{"type":"number","description":"Number of completed actions"},"failed":{"type":"number","description":"Number of failed actions"},"queued":{"type":"number","description":"Number of queued actions"},"cancelled":{"type":"number","description":"Number of cancelled actions"}},"required":["pending","processing","completed","failed","queued","cancelled"]},"progress":{"type":"number","minimum":0,"maximum":100,"description":"Completion percentage (0-100)"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the actions group was created"}},"required":["actionsId","entity","overallStatus","totalActions","statusCounts","progress","createdAt"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - invalid actionsId parameter"},"404":{"description":"Actions group not found"}}}},"/v1/conversation/:conversationId/messages":{"get":{"summary":"Get conversation messages","description":"Retrieve all messages for a specific conversation.\n\n    > **Required scope:** `MESSAGING_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Campaigns"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"ID of the conversation"},"required":true,"description":"ID of the conversation","name":"conversationId","in":"path"}],"responses":{"200":{"description":"Messages retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"conversationId":{"type":"number","description":"ID of the conversation"},"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the message"},"content":{"type":"string","description":"Content of the message"},"subject":{"type":["string","null"],"description":"Subject of the message (for emails)"},"type":{"type":"string","description":"Type of message (LINKEDIN, EMAIL, INMAIL, etc.)"},"isContactSender":{"type":"boolean","description":"Whether the message was sent by the contact (true) or by the identity (false)"},"isAutosent":{"type":"boolean","description":"Whether the message was sent automatically by Enginy"},"isAudio":{"type":["boolean","null"],"description":"Whether the message is an audio message"},"url":{"type":["string","null"],"description":"URL associated with the message"},"attachment":{"type":["string","null"],"description":"Attachment associated with the message"},"attachmentName":{"type":["string","null"],"description":"Name of the attachment"},"contentType":{"type":"string","description":"Content type of the message (TEXT, AUDIO, IMAGE, VIDEO, FILE)"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the message was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the message was last updated"},"viewCount":{"type":"number","description":"Number of times the message has been viewed"},"clickCount":{"type":"number","description":"Number of times links in the message have been clicked"}},"required":["id","content","subject","type","isContactSender","isAutosent","isAudio","url","attachment","attachmentName","contentType","createdAt","updatedAt","viewCount","clickCount"]},"description":"List of messages in the conversation"}},"required":["conversationId","messages"]}},"required":["status","message","data"]}}}},"400":{"description":"Invalid conversation ID"},"404":{"description":"Conversation not found"}}}},"/v1/inboxes":{"get":{"summary":"List inbox threads","description":"List inbox threads grouped by contact.\n\nRequired parameters:\n- None\n\nOptional query parameters:\n- page: 1-based page number. Defaults to 1.\n- pageSize: number of threads per page. Defaults to 25.\n- search: free-text search across contact name, company name, email, and recent message content.\n- senderIdentityId: scope the inbox to a single sender identity when the same contact appears in multiple sender mailboxes\n- archived: set to true to return archived threads instead of active ones. Defaults to false.\n\n    > **Required scope:** `MESSAGING_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"integer","exclusiveMinimum":0,"description":"1-based page number. Defaults to 1.","example":1},"required":false,"description":"1-based page number. Defaults to 1.","name":"page","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"description":"Number of threads per page. Defaults to 25. Maximum is 100.","example":25},"required":false,"description":"Number of threads per page. Defaults to 25. Maximum is 100.","name":"pageSize","in":"query"},{"schema":{"type":"string","description":"Free-text search across contact name, company name, email, and recent message content.","example":"pricing northstar"},"required":false,"description":"Free-text search across contact name, company name, email, and recent message content.","name":"search","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"description":"Scope the inbox to one sender identity when the same contact appears in multiple sender mailboxes.","example":14},"required":false,"description":"Scope the inbox to one sender identity when the same contact appears in multiple sender mailboxes.","name":"senderIdentityId","in":"query"},{"schema":{"type":"boolean","description":"Return archived threads instead of active ones. Defaults to false.","example":false},"required":false,"description":"Return archived threads instead of active ones. Defaults to false.","name":"archived","in":"query"}],"responses":{"200":{"description":"Successful response with paginated inbox threads","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"contactId":{"type":"number","description":"Contact ID for the inbox thread"},"latestConversationId":{"type":"number","description":"Latest visible conversation ID for the contact"},"firstName":{"type":["string","null"],"description":"Contact first name"},"lastName":{"type":["string","null"],"description":"Contact last name"},"fullName":{"type":"string","description":"Contact full name"},"email":{"type":["string","null"],"description":"Professional email for the contact"},"companyId":{"type":["number","null"],"description":"Company ID associated with the contact"},"companyName":{"type":["string","null"],"description":"Company name associated with the contact"},"companyDomain":{"type":["string","null"],"description":"Company domain associated with the contact"},"senderIdentityIds":{"type":"array","items":{"type":"number"},"description":"Sender identities that currently have visible conversations"},"channels":{"type":"array","items":{"type":"string","enum":["EMAIL","LINKEDIN"]},"description":"Channels that appear across the visible conversations for this contact"},"unreadMessagesCount":{"type":"number","description":"Unread inbound message count across the visible conversations"},"lastActivityAt":{"type":"string","format":"date-time","description":"Timestamp of the latest visible inbox activity"},"summary":{"type":"string","description":"Summary of the latest visible message"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Tag identifier"},"name":{"type":"string","description":"Tag name"},"color":{"type":"string","description":"Tag color"}},"required":["id","name","color"]},"description":"Distinct tags visible on the contact thread"}},"required":["contactId","latestConversationId","firstName","lastName","fullName","email","companyId","companyName","companyDomain","senderIdentityIds","channels","unreadMessagesCount","lastActivityAt","summary","tags"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]},"examples":{"default":{"summary":"One inbox thread with unread activity","value":{"data":[{"contactId":123,"latestConversationId":456,"firstName":"Alicia","lastName":"Stone","fullName":"Alicia Stone","email":"alicia@northstar.io","companyId":77,"companyName":"Northstar","companyDomain":"northstar.io","senderIdentityIds":[14],"channels":["EMAIL"],"unreadMessagesCount":2,"lastActivityAt":"2026-03-20T09:41:12.000Z","summary":"Thanks, this looks interesting. Can you send pricing?","tags":[{"id":5,"name":"Hot lead","color":"#F97316"}]}],"meta":{"page":1,"pageSize":25,"total":1}}}}}}},"404":{"description":"Sender identity not found"}}}},"/v1/inboxes/:contactId/messages":{"get":{"summary":"Get inbox contact messages","description":"Return the flattened inbox message history for a contact.\n\nRequired parameters:\n- contactId: contact ID path parameter for the thread you want to inspect.\n\nOptional query parameters:\n- senderIdentityId: limit the returned history to conversations owned by one sender identity\n- archived: set to true to read an archived thread instead of an active one. Defaults to false.\n\n    > **Required scope:** `MESSAGING_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Contact ID for the thread you want to inspect","example":"123"},"required":true,"description":"Contact ID for the thread you want to inspect","name":"contactId","in":"path"},{"schema":{"type":"integer","exclusiveMinimum":0,"description":"Return only the message history visible for one sender identity.","example":14},"required":false,"description":"Return only the message history visible for one sender identity.","name":"senderIdentityId","in":"query"},{"schema":{"type":"boolean","description":"Return archived threads instead of active ones. Defaults to false.","example":false},"required":false,"description":"Return archived threads instead of active ones. Defaults to false.","name":"archived","in":"query"}],"responses":{"200":{"description":"Inbox messages retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"contactId":{"type":"number","description":"Contact ID"},"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the message"},"content":{"type":"string","description":"Content of the message"},"subject":{"type":["string","null"],"description":"Subject of the message (for emails)"},"type":{"type":"string","description":"Type of message (LINKEDIN, EMAIL, INMAIL, etc.)"},"isContactSender":{"type":"boolean","description":"Whether the message was sent by the contact (true) or by the identity (false)"},"isAutosent":{"type":"boolean","description":"Whether the message was sent automatically by Enginy"},"isAudio":{"type":["boolean","null"],"description":"Whether the message is an audio message"},"url":{"type":["string","null"],"description":"URL associated with the message"},"attachment":{"type":["string","null"],"description":"Attachment associated with the message"},"attachmentName":{"type":["string","null"],"description":"Name of the attachment"},"contentType":{"type":"string","description":"Content type of the message (TEXT, AUDIO, IMAGE, VIDEO, FILE)"},"createdAt":{"type":"string","format":"date-time","description":"Date and time when the message was created"},"updatedAt":{"type":"string","format":"date-time","description":"Date and time when the message was last updated"},"viewCount":{"type":"number","description":"Number of times the message has been viewed"},"clickCount":{"type":"number","description":"Number of times links in the message have been clicked"},"conversationId":{"type":"number","description":"Conversation ID for the message"},"senderIdentityId":{"type":"number","description":"Sender identity ID associated with the conversation"}},"required":["id","content","subject","type","isContactSender","isAutosent","isAudio","url","attachment","attachmentName","contentType","createdAt","updatedAt","viewCount","clickCount","conversationId","senderIdentityId"]},"description":"Flattened messages across matching conversations"}},"required":["contactId","messages"]}},"required":["status","message","data"]},"examples":{"default":{"summary":"Full message history for one contact thread","value":{"status":"success","message":"Inbox messages retrieved successfully","data":{"contactId":123,"messages":[{"id":9001,"conversationId":456,"senderIdentityId":14,"content":"Thanks, this looks interesting. Can you send pricing?","subject":"Re: Intro from Enginy","type":"EMAIL","isContactSender":true,"isAutosent":false,"isAudio":false,"url":null,"attachment":null,"attachmentName":null,"contentType":"TEXT","createdAt":"2026-03-20T09:41:12.000Z","updatedAt":"2026-03-20T09:41:12.000Z","viewCount":0,"clickCount":0},{"id":9002,"conversationId":456,"senderIdentityId":14,"content":"Yes, let me know what team size you are targeting and I will tailor the pricing recommendation.","subject":"Re: Intro from Enginy","type":"EMAIL","isContactSender":false,"isAutosent":false,"isAudio":false,"url":null,"attachment":null,"attachmentName":null,"contentType":"TEXT","createdAt":"2026-03-20T10:03:40.000Z","updatedAt":"2026-03-20T10:03:40.000Z","viewCount":0,"clickCount":0}]}}}}}}},"400":{"description":"Invalid contact ID"},"404":{"description":"Contact or sender identity not found"}}}},"/v1/inbox/tags":{"get":{"summary":"List inbox tags","description":"List the tags that can be applied to inbox threads.\n\nRequired parameters:\n- None\n\nOptional query parameters:\n- senderIdentityId: scope tag counts to the threads visible for one sender identity\n- archived: set to true to count archived threads instead of active ones. Defaults to false.\n\n    > **Required scope:** `MESSAGING_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"integer","exclusiveMinimum":0,"description":"Scope tag counts to the threads visible for one sender identity.","example":14},"required":false,"description":"Scope tag counts to the threads visible for one sender identity.","name":"senderIdentityId","in":"query"},{"schema":{"type":"boolean","description":"Count archived threads instead of active ones. Defaults to false.","example":false},"required":false,"description":"Count archived threads instead of active ones. Defaults to false.","name":"archived","in":"query"}],"responses":{"200":{"description":"Inbox tags retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the inbox tag"},"name":{"type":"string","description":"Tag name"},"color":{"type":"string","description":"Tag color"},"count":{"type":"number","description":"Number of visible contact threads that currently have this tag"},"isPromptActive":{"type":"boolean","description":"Whether the tag is enabled for prompt-based auto-tagging"},"isEditable":{"type":"boolean","description":"Whether the tag can be edited manually"}},"required":["id","name","color","count","isPromptActive","isEditable"]}}},"required":["status","message","data"]},"examples":{"default":{"summary":"Available inbox tags with counts","value":{"status":"success","message":"Inbox tags retrieved successfully","data":[{"id":5,"name":"Hot lead","color":"#F97316","count":18,"isPromptActive":false,"isEditable":true},{"id":8,"name":"Needs follow-up","color":"#2563EB","count":41,"isPromptActive":false,"isEditable":true}]}}}}}},"404":{"description":"Sender identity not found"}}},"post":{"summary":"Create inbox tag","description":"Create a reusable inbox tag.\n\nRequired body fields:\n- name: human-readable tag name.\n- color: color token or hex value stored with the tag.\n\n    > **Required scope:** `MESSAGING_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":50,"description":"Name for the tag","example":"Hot lead"},"color":{"type":"string","minLength":1,"maxLength":50,"description":"Color token or hex value for the tag","example":"#F97316"}},"required":["name","color"]},"examples":{"default":{"summary":"Create a high-priority tag","value":{"name":"Hot lead","color":"#F97316"}}}}}},"responses":{"200":{"description":"Inbox tag already exists","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the inbox tag"},"name":{"type":"string","description":"Tag name"},"color":{"type":"string","description":"Tag color"},"count":{"type":"number","description":"Number of visible contact threads that currently have this tag"},"isPromptActive":{"type":"boolean","description":"Whether the tag is enabled for prompt-based auto-tagging"},"isEditable":{"type":"boolean","description":"Whether the tag can be edited manually"}},"required":["id","name","color","count","isPromptActive","isEditable"]}},"required":["status","message","data"]},"examples":{"existing":{"summary":"The same tag name already exists","value":{"status":"success","message":"Inbox tag already exists","data":{"id":5,"name":"Hot lead","color":"#F97316","count":18,"isPromptActive":false,"isEditable":true}}}}}}},"201":{"description":"Inbox tag created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the inbox tag"},"name":{"type":"string","description":"Tag name"},"color":{"type":"string","description":"Tag color"},"count":{"type":"number","description":"Number of visible contact threads that currently have this tag"},"isPromptActive":{"type":"boolean","description":"Whether the tag is enabled for prompt-based auto-tagging"},"isEditable":{"type":"boolean","description":"Whether the tag can be edited manually"}},"required":["id","name","color","count","isPromptActive","isEditable"]}},"required":["status","message","data"]},"examples":{"created":{"summary":"New inbox tag created","value":{"status":"success","message":"Inbox tag created successfully","data":{"id":5,"name":"Hot lead","color":"#F97316","count":18,"isPromptActive":false,"isEditable":true}}}}}}}}}},"/v1/inbox/tags/:tagId":{"get":{"summary":"Get inbox tag","description":"Retrieve one inbox tag by ID.\n\nRequired parameters:\n- tagId: tag ID path parameter.\n\nOptional query parameters:\n- senderIdentityId: scope the returned count to one sender identity\n- archived: set to true to count archived threads instead of active ones. Defaults to false.\n\n    > **Required scope:** `MESSAGING_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Inbox tag ID","example":"5"},"required":true,"description":"Inbox tag ID","name":"tagId","in":"path"},{"schema":{"type":"integer","exclusiveMinimum":0,"description":"Scope tag counts to the threads visible for one sender identity.","example":14},"required":false,"description":"Scope tag counts to the threads visible for one sender identity.","name":"senderIdentityId","in":"query"},{"schema":{"type":"boolean","description":"Count archived threads instead of active ones. Defaults to false.","example":false},"required":false,"description":"Count archived threads instead of active ones. Defaults to false.","name":"archived","in":"query"}],"responses":{"200":{"description":"Inbox tag retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier for the inbox tag"},"name":{"type":"string","description":"Tag name"},"color":{"type":"string","description":"Tag color"},"count":{"type":"number","description":"Number of visible contact threads that currently have this tag"},"isPromptActive":{"type":"boolean","description":"Whether the tag is enabled for prompt-based auto-tagging"},"isEditable":{"type":"boolean","description":"Whether the tag can be edited manually"}},"required":["id","name","color","count","isPromptActive","isEditable"]}},"required":["status","message","data"]},"examples":{"default":{"summary":"Single inbox tag","value":{"status":"success","message":"Inbox tag retrieved successfully","data":{"id":5,"name":"Hot lead","color":"#F97316","count":18,"isPromptActive":false,"isEditable":true}}}}}}},"400":{"description":"Invalid tag ID"},"404":{"description":"Inbox tag or sender identity not found"}}}},"/v1/inbox/contacts/:contactId/tags":{"post":{"summary":"Attach inbox tags to a contact thread","description":"Attach one or more tags to a contact thread.\n\nRequired parameters:\n- contactId: contact ID path parameter.\n- tagIds: array of tag IDs in the request body.\n\nOptional body fields:\n- senderIdentityId: target one sender-specific thread when the same contact appears under multiple sender identities.\n\n    > **Required scope:** `MESSAGING_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Contact ID for the thread you want to inspect","example":"123"},"required":true,"description":"Contact ID for the thread you want to inspect","name":"contactId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tagIds":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"description":"Tag IDs to attach or remove","example":[5,8]},"senderIdentityId":{"type":"integer","exclusiveMinimum":0,"description":"Optional sender identity ID to scope the contact thread before mutating tags","example":14}},"required":["tagIds"]},"examples":{"default":{"summary":"Attach two tags to one contact thread","value":{"tagIds":[5,8],"senderIdentityId":14}}}}}},"responses":{"200":{"description":"Inbox tags attached successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"contactId":{"type":"number","description":"Contact ID"},"tagIds":{"type":"array","items":{"type":"number"},"description":"Requested tag IDs"},"success":{"type":"boolean","description":"Whether all tag operations succeeded"}},"required":["contactId","tagIds","success"]}},"required":["status","message","data"]},"examples":{"default":{"summary":"Tags attached","value":{"status":"success","message":"Inbox tags attached successfully","data":{"contactId":123,"tagIds":[5,8],"success":true}}}}}}},"400":{"description":"Invalid contact ID"},"404":{"description":"Contact, thread, sender identity, or tags not found"}}},"delete":{"summary":"Remove inbox tags from a contact thread","description":"Remove one or more tags from a contact thread.\n\nRequired parameters:\n- contactId: contact ID path parameter.\n- tagIds: array of tag IDs in the request body.\n\nOptional body fields:\n- senderIdentityId: target one sender-specific thread when the same contact appears under multiple sender identities.\n\n    > **Required scope:** `MESSAGING_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Contact ID for the thread you want to inspect","example":"123"},"required":true,"description":"Contact ID for the thread you want to inspect","name":"contactId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tagIds":{"type":"array","items":{"type":"integer","exclusiveMinimum":0},"minItems":1,"description":"Tag IDs to attach or remove","example":[5,8]},"senderIdentityId":{"type":"integer","exclusiveMinimum":0,"description":"Optional sender identity ID to scope the contact thread before mutating tags","example":14}},"required":["tagIds"]},"examples":{"default":{"summary":"Remove one tag from a contact thread","value":{"tagIds":[8],"senderIdentityId":14}}}}}},"responses":{"200":{"description":"Inbox tags removed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"contactId":{"type":"number","description":"Contact ID"},"tagIds":{"type":"array","items":{"type":"number"},"description":"Requested tag IDs"},"success":{"type":"boolean","description":"Whether all tag operations succeeded"}},"required":["contactId","tagIds","success"]}},"required":["status","message","data"]},"examples":{"default":{"summary":"Tags removed","value":{"status":"success","message":"Inbox tags removed successfully","data":{"contactId":123,"tagIds":[8],"success":true}}}}}}},"400":{"description":"Invalid contact ID"},"404":{"description":"Contact, thread, sender identity, or tags not found"}}}},"/v1/inboxes/:contactId/archive":{"post":{"summary":"Archive inbox contact thread","description":"Archive one inbox contact thread.\n\nRequired parameters:\n- contactId: contact ID path parameter.\n\nNotes:\n- Archiving is lead-level, so all visible threads for that contact move into the archived inbox.\n- The endpoint is idempotent. If the contact is already archived it still returns success..\n\n    > **Required scope:** `MESSAGING_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Contact ID for the thread you want to inspect","example":"123"},"required":true,"description":"Contact ID for the thread you want to inspect","name":"contactId","in":"path"}],"responses":{"200":{"description":"Inbox thread archived successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"contactId":{"type":"number","description":"Contact ID"},"archived":{"type":"boolean","description":"Requested archive state after the operation"},"updatedCount":{"type":"number","description":"Number of archive rows changed. Zero means the contact was already in the requested state"},"success":{"type":"boolean","description":"Whether the archive mutation completed successfully"}},"required":["contactId","archived","updatedCount","success"]}},"required":["status","message","data"]},"examples":{"default":{"summary":"Archive one contact thread","value":{"status":"success","message":"Inbox thread archived successfully","data":{"contactId":123,"archived":true,"updatedCount":1,"success":true}}}}}}},"400":{"description":"Invalid contact ID"},"404":{"description":"Contact or inbox thread not found"}}}},"/v1/inboxes/:contactId/unarchive":{"post":{"summary":"Unarchive inbox contact thread","description":"Unarchive one inbox contact thread.\n\nRequired parameters:\n- contactId: contact ID path parameter.\n\nNotes:\n- Unarchiving is lead-level, so all visible threads for that contact move back into the active inbox.\n- The endpoint is idempotent. If the contact is already active it still returns success..\n\n    > **Required scope:** `MESSAGING_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Contact ID for the thread you want to inspect","example":"123"},"required":true,"description":"Contact ID for the thread you want to inspect","name":"contactId","in":"path"}],"responses":{"200":{"description":"Inbox thread unarchived successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"contactId":{"type":"number","description":"Contact ID"},"archived":{"type":"boolean","description":"Requested archive state after the operation"},"updatedCount":{"type":"number","description":"Number of archive rows changed. Zero means the contact was already in the requested state"},"success":{"type":"boolean","description":"Whether the archive mutation completed successfully"}},"required":["contactId","archived","updatedCount","success"]}},"required":["status","message","data"]},"examples":{"default":{"summary":"Unarchive one contact thread","value":{"status":"success","message":"Inbox thread unarchived successfully","data":{"contactId":123,"archived":false,"updatedCount":1,"success":true}}}}}}},"400":{"description":"Invalid contact ID"},"404":{"description":"Contact or inbox thread not found"}}}},"/v1/inbox/messages":{"post":{"summary":"Send inbox message","description":"Send a manual inbox reply through Enginy conversation routing.\n\nRequired body fields:\n- contactId: contact whose thread should receive the reply.\n- senderIdentityId: sender identity that owns the target thread.\n- message: plain-text body of the manual reply.\n\nOptional body fields:\n- type: channel used to select the matching conversation. Allowed values are EMAIL and LINKEDIN. If omitted, Enginy falls back to the latest replyable message channel on the matched thread.\n- attachment: one attachment with url, name, and MIME type.\n- requestId: idempotency suffix for safely retrying the same manual reply.\n\n    > **Required scope:** `MESSAGING_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Inbox"],"security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contactId":{"type":"integer","exclusiveMinimum":0,"description":"Contact ID to reply to","example":123},"senderIdentityId":{"type":"integer","exclusiveMinimum":0,"description":"Sender identity ID that owns the conversation","example":14},"type":{"type":"string","enum":["EMAIL","LINKEDIN"],"description":"Optional channel to use when selecting the matching conversation. Defaults to the last replyable message channel","example":"EMAIL"},"message":{"type":"string","minLength":1,"description":"Reply message content","example":"Absolutely. I just sent over our pricing breakdown and can walk through it live if helpful."},"attachment":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Attachment URL","example":"https://cdn.enginy.ai/files/pricing-one-pager.pdf"},"name":{"type":"string","minLength":1,"description":"Attachment name","example":"pricing-one-pager.pdf"},"type":{"type":"string","minLength":1,"description":"Attachment MIME type","example":"application/pdf"}},"required":["url","name","type"],"description":"Optional single attachment supported by the manual reply flow"},"requestId":{"type":"string","minLength":1,"description":"Optional idempotency key suffix for the manual reply","example":"manual-reply-20260320-001"}},"required":["contactId","senderIdentityId","message"]},"examples":{"basicEmailReply":{"summary":"Reply on an email thread","value":{"contactId":123,"senderIdentityId":14,"type":"EMAIL","message":"Absolutely. I just sent over our pricing breakdown and can walk through it live if helpful.","requestId":"manual-reply-20260320-001"}},"emailReplyWithAttachment":{"summary":"Reply on an email thread with one attachment","value":{"contactId":123,"senderIdentityId":14,"type":"EMAIL","message":"Sharing the pricing one-pager here as well.","attachment":{"url":"https://cdn.enginy.ai/files/pricing-one-pager.pdf","name":"pricing-one-pager.pdf","type":"application/pdf"},"requestId":"manual-reply-20260320-002"}}}}}},"responses":{"200":{"description":"Inbox message sent successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"contactId":{"type":"number","description":"Contact ID"},"conversationId":{"type":"number","description":"Conversation used for the manual reply"},"type":{"type":"string","enum":["EMAIL","LINKEDIN"],"description":"Channel that was used for the reply"},"success":{"type":"boolean","description":"Whether the message dispatch was accepted by the worker"},"message":{"type":"string","description":"Worker response message"}},"required":["contactId","conversationId","type","success","message"]}},"required":["status","message","data"]},"examples":{"default":{"summary":"Manual reply accepted by the worker","value":{"status":"success","message":"Inbox message sent successfully","data":{"contactId":123,"conversationId":456,"type":"EMAIL","success":true,"message":"Message queued successfully"}}}}}}},"400":{"description":"Invalid payload or the message service was unavailable"},"404":{"description":"Contact, sender identity, or matching conversation not found"}}}},"/v1/webhooks":{"get":{"summary":"List webhook subscriptions","description":"Retrieve a paginated list of webhook subscriptions.\n\n    > **Required scope:** `WEBHOOKS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Webhooks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Page number"},"required":false,"description":"Page number","name":"page","in":"query"},{"schema":{"type":"string","description":"Items per page"},"required":false,"description":"Items per page","name":"pageSize","in":"query"}],"responses":{"200":{"description":"Successful response with paginated webhooks","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Webhook ID"},"name":{"type":"string","description":"Webhook name"},"url":{"type":"string","description":"Webhook URL"},"events":{"type":"array","items":{"type":"string"},"description":"Subscribed event types"},"campaignIds":{"type":"array","items":{"type":"number"},"description":"Filtered campaign IDs"},"customFields":{"type":"array","items":{"type":"string"},"description":"Custom fields included in payloads. Use `GET /v1/contacts/fields` and `GET /v1/companies/fields` to discover valid field names."},"enabled":{"type":"boolean","description":"Whether webhook is enabled"},"createdAt":{"type":"string","format":"date-time","description":"Creation date"},"updatedAt":{"type":"string","format":"date-time","description":"Last update date"},"hasSecret":{"type":"boolean","description":"Whether a secret is configured (actual secret is never returned for security)"}},"required":["id","name","url","events","campaignIds","customFields","enabled","createdAt","updatedAt","hasSecret"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}}}},"post":{"summary":"Create webhook subscription","description":"Create a new webhook subscription.\n\n    > **Required scope:** `WEBHOOKS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Webhooks"],"security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Descriptive name for the webhook"},"url":{"type":"string","format":"uri","description":"Webhook URL (must be valid and not a private IP)"},"secret":{"type":"string","minLength":8,"maxLength":256,"description":"Optional secret for webhook authentication (8-256 characters)"},"events":{"type":"array","items":{"type":"string","enum":["CONNECTION_REQUEST_SENT","CONNECTION_REQUEST_ACCEPTED","LINKEDIN_MESSAGE_SENT","EMAIL_SENT","INMAIL_SENT","MESSAGE_REPLIED","POST_LIKED","PROFILE_VISITED"]},"minItems":1,"description":"Array of event types to subscribe to"},"campaignIds":{"type":"array","items":{"type":"number"},"description":"Optional array of campaign IDs to filter events (empty = all campaigns)"},"customFields":{"type":"array","items":{"type":"string"},"description":"Optional array of additional contact/company fields to include in webhook payloads. Use `GET /v1/contacts/fields` and `GET /v1/companies/fields` to discover valid field names."},"enabled":{"type":"boolean","default":true,"description":"Whether the webhook is enabled"}},"required":["name","url","events"]},"examples":{"basic":{"summary":"Basic webhook for message events","value":{"url":"https://your-domain.com/webhooks/enginy","events":["MESSAGE_REPLIED","EMAIL_SENT"],"enabled":true}},"withSecret":{"summary":"Webhook with secret and campaign filter","value":{"url":"https://your-domain.com/webhooks/enginy","secret":"your-secret-key-here","events":["CONNECTION_REQUEST_SENT","CONNECTION_REQUEST_ACCEPTED"],"campaignIds":[123,456],"customFields":["mobilePhone","leadCountry"],"enabled":true}}}}}},"responses":{"201":{"description":"Webhook created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Webhook ID"},"name":{"type":"string","description":"Webhook name"},"url":{"type":"string","description":"Webhook URL"},"events":{"type":"array","items":{"type":"string"},"description":"Subscribed event types"},"campaignIds":{"type":"array","items":{"type":"number"},"description":"Filtered campaign IDs"},"customFields":{"type":"array","items":{"type":"string"},"description":"Custom fields included in payloads. Use `GET /v1/contacts/fields` and `GET /v1/companies/fields` to discover valid field names."},"enabled":{"type":"boolean","description":"Whether webhook is enabled"},"createdAt":{"type":"string","format":"date-time","description":"Creation date"},"updatedAt":{"type":"string","format":"date-time","description":"Last update date"},"hasSecret":{"type":"boolean","description":"Whether a secret is configured (actual secret is never returned for security)"}},"required":["id","name","url","events","campaignIds","customFields","enabled","createdAt","updatedAt","hasSecret"]}},"required":["status","message","data"]}}}},"400":{"description":"Bad request - validation error"}}}},"/v1/webhooks/{webhookId}":{"get":{"summary":"Get webhook subscription","description":"Retrieve a single webhook by ID.\n\n    > **Required scope:** `WEBHOOKS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Webhooks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID"},"required":true,"description":"Webhook ID","name":"webhookId","in":"path"}],"responses":{"200":{"description":"Webhook retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Webhook ID"},"name":{"type":"string","description":"Webhook name"},"url":{"type":"string","description":"Webhook URL"},"events":{"type":"array","items":{"type":"string"},"description":"Subscribed event types"},"campaignIds":{"type":"array","items":{"type":"number"},"description":"Filtered campaign IDs"},"customFields":{"type":"array","items":{"type":"string"},"description":"Custom fields included in payloads. Use `GET /v1/contacts/fields` and `GET /v1/companies/fields` to discover valid field names."},"enabled":{"type":"boolean","description":"Whether webhook is enabled"},"createdAt":{"type":"string","format":"date-time","description":"Creation date"},"updatedAt":{"type":"string","format":"date-time","description":"Last update date"},"hasSecret":{"type":"boolean","description":"Whether a secret is configured (actual secret is never returned for security)"}},"required":["id","name","url","events","campaignIds","customFields","enabled","createdAt","updatedAt","hasSecret"]}},"required":["status","message","data"]}}}},"404":{"description":"Webhook not found"}}},"patch":{"summary":"Update webhook subscription","description":"Update a webhook subscription.\n\n    > **Required scope:** `WEBHOOKS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Webhooks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID"},"required":true,"description":"Webhook ID","name":"webhookId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Descriptive name for the webhook"},"url":{"type":"string","format":"uri","description":"Webhook URL"},"secret":{"type":["string","null"],"minLength":8,"maxLength":256,"description":"Webhook secret (null to remove)"},"events":{"type":"array","items":{"type":"string","enum":["CONNECTION_REQUEST_SENT","CONNECTION_REQUEST_ACCEPTED","LINKEDIN_MESSAGE_SENT","EMAIL_SENT","INMAIL_SENT","MESSAGE_REPLIED","POST_LIKED","PROFILE_VISITED"]},"minItems":1,"description":"Array of event types"},"campaignIds":{"type":"array","items":{"type":"number"},"description":"Array of campaign IDs to filter"},"customFields":{"type":"array","items":{"type":"string"},"description":"Additional fields to include. Use `GET /v1/contacts/fields` and `GET /v1/companies/fields` to discover valid field names."},"enabled":{"type":"boolean","description":"Enable or disable webhook"}}}}}},"responses":{"200":{"description":"Webhook updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"Webhook ID"},"name":{"type":"string","description":"Webhook name"},"url":{"type":"string","description":"Webhook URL"},"events":{"type":"array","items":{"type":"string"},"description":"Subscribed event types"},"campaignIds":{"type":"array","items":{"type":"number"},"description":"Filtered campaign IDs"},"customFields":{"type":"array","items":{"type":"string"},"description":"Custom fields included in payloads. Use `GET /v1/contacts/fields` and `GET /v1/companies/fields` to discover valid field names."},"enabled":{"type":"boolean","description":"Whether webhook is enabled"},"createdAt":{"type":"string","format":"date-time","description":"Creation date"},"updatedAt":{"type":"string","format":"date-time","description":"Last update date"},"hasSecret":{"type":"boolean","description":"Whether a secret is configured (actual secret is never returned for security)"}},"required":["id","name","url","events","campaignIds","customFields","enabled","createdAt","updatedAt","hasSecret"]}},"required":["status","message","data"]}}}},"404":{"description":"Webhook not found"}}},"delete":{"summary":"Delete webhook subscription","description":"Delete a webhook subscription.\n\n    > **Required scope:** `WEBHOOKS_WRITE`\n    >\n    > **Rate limit:** 30 requests per minute","tags":["Webhooks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID"},"required":true,"description":"Webhook ID","name":"webhookId","in":"path"}],"responses":{"204":{"description":"Webhook deleted successfully"},"404":{"description":"Webhook not found"}}}},"/v1/webhooks/{webhookId}/logs":{"get":{"summary":"Get webhook delivery logs","description":"Retrieve delivery logs for a webhook.\n\n    > **Required scope:** `WEBHOOKS_READ`\n    >\n    > **Rate limit:** 100 requests per minute","tags":["Webhooks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID"},"required":true,"description":"Webhook ID","name":"webhookId","in":"path"},{"schema":{"type":"string","description":"Page number"},"required":false,"description":"Page number","name":"page","in":"query"},{"schema":{"type":"string","description":"Items per page"},"required":false,"description":"Items per page","name":"pageSize","in":"query"}],"responses":{"200":{"description":"Logs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Log entry ID"},"eventType":{"type":"string","description":"Event type that triggered the webhook"},"statusCode":{"type":["number","null"],"description":"HTTP status code from webhook endpoint"},"errorMessage":{"type":["string","null"],"description":"Error message if delivery failed"},"attemptNumber":{"type":"number","description":"Delivery attempt number"},"durationMs":{"type":["number","null"],"description":"Request duration in milliseconds"},"createdAt":{"type":"string","format":"date-time","description":"When the delivery attempt occurred"}},"required":["id","eventType","statusCode","errorMessage","attemptNumber","durationMs","createdAt"]}},"meta":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"total":{"type":"number"}},"required":["page","pageSize","total"]}},"required":["data","meta"]}}}},"404":{"description":"Webhook not found"}}}},"/v1/webhooks/{webhookId}/test":{"post":{"summary":"Test webhook subscription","description":"Send a test event to a webhook.\n\n    > **Required scope:** `WEBHOOKS_WRITE`\n    >\n    > **Rate limit:** 10 requests per minute","tags":["Webhooks"],"security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID"},"required":true,"description":"Webhook ID","name":"webhookId","in":"path"}],"responses":{"200":{"description":"Test webhook sent successfully","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"},"data":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]}},"required":["status","message","data"]}}}},"400":{"description":"Failed to send test webhook"},"404":{"description":"Webhook not found"}}}},"/v1/validate":{"get":{"summary":"Validate API key","tags":["Authentication"],"description":"Validate API key authentication.\n\n    > **Required scope:** `WORKSPACE_READ`\n    >\n    > **Rate limit:** 100 requests per minute","security":[{"apiKey":[]}],"responses":{"204":{"description":"API key is valid"},"401":{"description":"Invalid or missing API key"}}}}},"webhooks":{"/your-webhook-url":{"post":{"summary":"Actions Completed Webhook","description":"This webhook is triggered when an action run completes. You can provide your webhook URL when creating an actions run via the `/v1/actions` endpoint.\n\n**Webhook Requirements:**\n- The URL must be HTTPS in production\n- Your endpoint should respond with a 2xx status code to acknowledge receipt\n- The webhook will be sent as a POST request with a JSON payload\n- If your endpoint fails to respond or returns an error, Enginy will retry the webhook\n\n**When is it sent:**\n- After all actions in a group have finished processing (completed, failed, or cancelled)\n- This is sent for each entity (contact or company) in the actions run\n\n**Use cases:**\n- Trigger follow-up workflows in your system when enrichment completes\n- Get notified when verification or scraping actions finish\n- Monitor the progress of bulk operations without polling\n\n**Example webhook setup:**\nWhen creating an actions run, include the `webhookUrl` parameter:\n\n```json\n{\n  \"actions\": [{ \"type\": \"VERIFY_LEAD_EMAIL\" }],\n  \"contactIds\": [123, 456],\n  \"webhookUrl\": \"https://your-domain.com/webhooks/enginy\"\n}\n```\n\nYour webhook endpoint will receive a POST request with the payload described below.","tags":["Webhooks"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"eventType":{"type":"string","enum":["ACTIONS_COMPLETED"],"description":"Type of webhook event"},"timestamp":{"type":"string","description":"ISO 8601 timestamp when the webhook was sent"},"data":{"type":"object","properties":{"actionsId":{"type":"number","description":"ID of the actions group that completed"},"entity":{"type":"string","enum":["CONTACT","COMPANY"],"description":"Type of entity the actions were run on"},"contactId":{"type":"number","description":"ID of the contact (present when entity is CONTACT)"},"companyId":{"type":"number","description":"ID of the company (present when entity is COMPANY)"},"overallStatus":{"type":"string","enum":["PROCESSING","COMPLETED","FAILED","QUEUED","CANCELLED","PARTIAL"],"description":"Overall status of the actions group. PARTIAL means some actions completed successfully and some failed."},"totalActions":{"type":"number","description":"Total number of actions in the group"},"statusCounts":{"type":"object","properties":{"pending":{"type":"number","description":"Number of pending actions"},"processing":{"type":"number","description":"Number of processing actions"},"completed":{"type":"number","description":"Number of completed actions"},"failed":{"type":"number","description":"Number of failed actions"},"queued":{"type":"number","description":"Number of queued actions"},"cancelled":{"type":"number","description":"Number of cancelled actions"}},"required":["pending","processing","completed","failed","queued","cancelled"],"description":"Breakdown of action statuses"},"progress":{"type":"number","minimum":0,"maximum":100,"description":"Completion percentage (0-100)"},"createdAt":{"type":"string","description":"ISO 8601 timestamp when the actions group was created"},"completedAt":{"type":"string","description":"ISO 8601 timestamp when the actions group completed"}},"required":["actionsId","entity","overallStatus","totalActions","statusCounts","progress","createdAt","completedAt"]}},"required":["eventType","timestamp","data"]},"examples":{"contactCompleted":{"summary":"Contact actions completed successfully","value":{"eventType":"ACTIONS_COMPLETED","timestamp":"2024-01-15T10:30:00.000Z","data":{"actionsId":12345,"entity":"CONTACT","contactId":789,"overallStatus":"COMPLETED","totalActions":3,"statusCounts":{"pending":0,"processing":0,"completed":3,"failed":0,"queued":0,"cancelled":0},"progress":100,"createdAt":"2025-01-15T10:25:00.000Z","completedAt":"2025-01-15T10:30:00.000Z"}}},"companyPartial":{"summary":"Company actions partially completed","value":{"eventType":"ACTIONS_COMPLETED","timestamp":"2024-01-15T10:30:00.000Z","data":{"actionsId":12346,"entity":"COMPANY","companyId":456,"overallStatus":"PARTIAL","totalActions":5,"statusCounts":{"pending":0,"processing":0,"completed":3,"failed":2,"queued":0,"cancelled":0},"progress":100,"createdAt":"2025-01-15T10:20:00.000Z","completedAt":"2025-01-15T10:30:00.000Z"}}}}}}},"responses":{"200":{"description":"Webhook received successfully"},"204":{"description":"Webhook received successfully (no content)"}}}},"/your-conversation-webhook-url":{"post":{"summary":"Conversation Events Webhook","description":"This webhook is triggered when subscribed conversation events occur. You can create webhook subscriptions via the `/v1/webhooks` endpoint to receive these events.\n\n**Available Event Types:**\n- `CONNECTION_REQUEST_SENT`: Triggered when a LinkedIn connection request is sent\n- `CONNECTION_REQUEST_ACCEPTED`: Triggered when a contact accepts a connection request\n- `LINKEDIN_MESSAGE_SENT`: Triggered when a LinkedIn message is sent\n- `EMAIL_SENT`: Triggered when an email is sent\n- `INMAIL_SENT`: Triggered when a LinkedIn InMail is sent\n- `MESSAGE_REPLIED`: Triggered when a contact replies to any message\n\n**Webhook Authentication:**\nIf you provide a `secret` when creating your webhook subscription, it will be included in the request headers as `X-Webhook-Secret`. You can use this to verify that the webhook is coming from Enginy.\n\n**Campaign Filtering:**\nWhen creating a webhook, you can specify `campaignIds` to only receive events from specific campaigns. If not specified or empty, you'll receive events from all campaigns.\n\n**Custom Fields:**\nYou can specify additional contact/company fields to include in the webhook payload via the `customFields` parameter when creating the webhook.\n\n**Retry Logic:**\n- Enginy will retry failed webhook deliveries up to 3 times\n- Retry intervals: 30 seconds, 5 minutes, 50 minutes (exponential backoff)\n- Your endpoint should respond with a 2xx status code to acknowledge receipt\n\n**Example webhook creation:**\n\n```json\n{\n  \"url\": \"https://your-domain.com/webhooks/enginy\",\n  \"secret\": \"your-secret-key\",\n  \"events\": [\"MESSAGE_REPLIED\", \"EMAIL_SENT\"],\n  \"campaignIds\": [123, 456],\n  \"customFields\": [\"mobilePhone\", \"leadCountry\"]\n}\n```","tags":["Webhooks"],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"eventType":{"type":"string","enum":["CONNECTION_REQUEST_SENT"]},"timestamp":{"type":"string"},"data":{"type":"object","properties":{"contact":{"type":"object","properties":{"id":{"type":"number"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"professionalEmail":{"type":["string","null"]},"linkedInProfileUrl":{"type":["string","null"]},"jobTitle":{"type":["string","null"]},"companyId":{"type":["number","null"]}},"required":["id","firstName","lastName","professionalEmail","linkedInProfileUrl","jobTitle","companyId"]},"campaign":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"status":{"type":"string"}},"required":["id","name","status"]},"customMessage":{"type":["string","null"]},"sentAt":{"type":"string"}},"required":["contact","campaign","customMessage","sentAt"]}},"required":["eventType","timestamp","data"]},{"type":"object","properties":{"eventType":{"type":"string","enum":["CONNECTION_REQUEST_ACCEPTED"]},"timestamp":{"type":"string"},"data":{"type":"object","properties":{"contact":{"type":"object","properties":{"id":{"type":"number"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"professionalEmail":{"type":["string","null"]},"linkedInProfileUrl":{"type":["string","null"]},"jobTitle":{"type":["string","null"]},"companyId":{"type":["number","null"]}},"required":["id","firstName","lastName","professionalEmail","linkedInProfileUrl","jobTitle","companyId"]},"campaign":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"status":{"type":"string"}},"required":["id","name","status"]},"acceptedAt":{"type":"string"}},"required":["contact","campaign","acceptedAt"]}},"required":["eventType","timestamp","data"]},{"type":"object","properties":{"eventType":{"type":"string","enum":["LINKEDIN_MESSAGE_SENT","EMAIL_SENT","INMAIL_SENT","MESSAGE_REPLIED"]},"timestamp":{"type":"string"},"data":{"type":"object","properties":{"contact":{"type":"object","properties":{"id":{"type":"number"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"professionalEmail":{"type":["string","null"]},"linkedInProfileUrl":{"type":["string","null"]},"jobTitle":{"type":["string","null"]},"companyId":{"type":["number","null"]}},"required":["id","firstName","lastName","professionalEmail","linkedInProfileUrl","jobTitle","companyId"]},"campaign":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"status":{"type":"string"}},"required":["id","name","status"]},"content":{"type":"string"},"subject":{"type":["string","null"]},"sentAt":{"type":"string"}},"required":["contact","campaign","content","subject","sentAt"]}},"required":["eventType","timestamp","data"]}]},"examples":{"connectionRequestSent":{"summary":"Connection request sent","value":{"eventType":"CONNECTION_REQUEST_SENT","timestamp":"2025-11-03T10:30:00.000Z","data":{"contact":{"id":789,"firstName":"John","lastName":"Doe","professionalEmail":"john.doe@example.com","linkedInProfileUrl":"https://linkedin.com/in/johndoe","jobTitle":"CEO","companyId":123},"campaign":{"id":456,"name":"Outbound Campaign Q4","status":"ACTIVE"},"customMessage":"Hi John, I would like to connect with you","sentAt":"2025-11-03T10:30:00.000Z"}}},"messageReplied":{"summary":"Contact replied to message","value":{"eventType":"MESSAGE_REPLIED","timestamp":"2025-11-03T14:30:00.000Z","data":{"contact":{"id":789,"firstName":"John","lastName":"Doe","professionalEmail":"john.doe@example.com","linkedInProfileUrl":"https://linkedin.com/in/johndoe","jobTitle":"CEO","companyId":123},"campaign":{"id":456,"name":"Outbound Campaign Q4","status":"ACTIVE"},"content":"Thanks for reaching out! I would be interested to learn more.","subject":null,"sentAt":"2025-11-03T14:30:00.000Z"}}}}}}},"responses":{"200":{"description":"Webhook received successfully"},"204":{"description":"Webhook received successfully (no content)"}}}}}}