openapi: 3.1.0 info: title: Vivre CRM API version: 1.0.0 description: "The Vivre CRM API: leads, contacts, companies, deals, tasks, notes and\nactivities, pipelines and CRM settings,\ \ imports, reports and CRM webhooks.\n\n* Every endpoint is under https://api.vivrecrm.com/api/v1/. Send an API key\n\ \ as `X-Api-Key: ` or `Authorization: Api-Key `. Make a key in the\n app under Developers, API keys. A key\ \ belongs to one organization and\n works on its CRM endpoints, as its scopes allow.\n* A record's `id` is its public\ \ UUID.\n* Lists are cursor-paginated: follow the `next` and `previous` URLs.\n* Retryable writes take an Idempotency-Key\ \ header (24 hour replay window).\n" servers: - url: https://api.vivrecrm.com security: - apiKeyAuth: [] tags: - name: Contacts - name: Leads - name: Deals - name: Companies - name: Tasks - name: Notes & Activities - name: Taxonomy - name: Saved Views & Filters - name: Custom Fields - name: Dashboard & Search - name: Import - name: Notifications - name: Webhooks - name: Automations paths: /api/v1/contacts/: get: tags: - Contacts summary: List contacts parameters: - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Search' - $ref: '#/components/parameters/Ordering' responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Contact' post: tags: - Contacts summary: Create contact parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Contact' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Contact' '400': $ref: '#/components/responses/ValidationError' /api/v1/contacts/{public_id}/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Contacts summary: Retrieve responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Contact' '404': $ref: '#/components/responses/NotFound' patch: tags: - Contacts summary: Update requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Contact' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Contact' put: tags: - Contacts summary: Replace (full update; PATCH for partial) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Contact' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Contact' delete: tags: - Contacts summary: Soft-delete responses: '204': description: Deleted /api/v1/contacts/{public_id}/restore/: parameters: - $ref: '#/components/parameters/IdPath' post: tags: - Contacts summary: Restore soft-deleted contact responses: '200': description: The restored contact content: application/json: schema: $ref: '#/components/schemas/Contact' /api/v1/contacts/{public_id}/activities/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Contacts summary: Contact activity timeline responses: '200': description: The contact's activities, cursor-paginated content: application/json: schema: $ref: '#/components/schemas/PaginatedActivities' /api/v1/contacts/bulk-merge/: post: tags: - Contacts summary: Merge duplicate contacts responses: '200': description: Merge result with the updated primary contact content: application/json: schema: $ref: '#/components/schemas/ContactBulkMergeResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ContactBulkMergeRequest' /api/v1/contacts/bulk-tag/: post: tags: - Contacts summary: Bulk add tags responses: '200': description: Tag added content: application/json: schema: $ref: '#/components/schemas/BulkTagResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BulkTagRequest' /api/v1/contacts/bulk-untag/: post: tags: - Contacts summary: Bulk remove tags responses: '200': description: Tag removed content: application/json: schema: $ref: '#/components/schemas/BulkUntagResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BulkTagRequest' /api/v1/leads/: get: tags: - Leads summary: List leads parameters: - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Search' - $ref: '#/components/parameters/Ordering' - name: status in: query schema: type: string - name: assigned_to in: query schema: type: string responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Lead' post: tags: - Leads summary: Create lead parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Lead' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Lead' /api/v1/leads/{public_id}/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Leads summary: Retrieve responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Lead' patch: tags: - Leads summary: Update responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Lead' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Lead' put: tags: - Leads summary: Replace (full update; PATCH for partial) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Lead' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Lead' delete: tags: - Leads summary: Soft-delete responses: '204': description: Deleted /api/v1/leads/bulk-assign/: post: tags: - Leads summary: Bulk reassign owner responses: '200': description: Leads reassigned content: application/json: schema: $ref: '#/components/schemas/LeadBulkAssignResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LeadBulkAssignRequest' /api/v1/leads/bulk-update-status/: post: tags: - Leads summary: Bulk status update responses: '200': description: Statuses updated content: application/json: schema: $ref: '#/components/schemas/LeadBulkStatusResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LeadBulkStatusRequest' /api/v1/leads/bulk-delete/: post: tags: - Leads summary: Bulk soft-delete responses: '200': description: Per-id outcome content: application/json: schema: $ref: '#/components/schemas/BulkDeleteResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LeadBulkDeleteRequest' /api/v1/leads/bulk-merge/: post: tags: - Leads summary: Merge duplicate leads of one contact (lead.bulk_merge; owners and admins by default) description: The kept lead takes over the duplicates' deals, tasks, notes, activity, AI jobs, custom values (its own win) and tags; the duplicates are soft-deleted. Only leads of the same contact merge (400 otherwise). Sends lead.deleted.v1 per duplicate, deal.updated.v1 per moved deal and lead.merged.v1. responses: '200': description: Merge result with the kept lead content: application/json: schema: $ref: '#/components/schemas/LeadBulkMergeResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LeadBulkMergeRequest' /api/v1/deals/: get: tags: - Deals summary: List deals parameters: - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Search' - name: ordering in: query description: 'A column of the list, `-` for descending: assigned_to__first_name, closed_at, contact__first_name, created_at, currency, expected_close_date, last_activity_at, pipeline__name, stage__name, status, title, updated_at, value; or `cf__` on the paged route. Anything else is a 400. Default `-created_at`.' schema: type: string - name: status in: query description: '`open` (the default), `won`, `lost`, `abandoned`, or `all`.' schema: type: string - name: filter in: query description: 'The filter panel''s compound filter, as JSON: {op, conditions}. Fields from GET filter-fields/deal/.' schema: type: string - name: pipeline_id in: query description: Pipeline public id. schema: type: string - name: stage_id in: query description: Stage public id. schema: type: string - name: stage in: query description: Stage name. schema: type: string - name: owner_id in: query description: Owner (user) public id. schema: type: string - name: tag_id in: query description: Tag public id. schema: type: string - name: lead_id in: query description: The lead's deals. schema: type: string - name: contact_id in: query description: The contact's deals; one from elsewhere lists nothing. schema: type: string - name: draw in: query description: When present, answers the paged list, `{draw, recordsTotal, recordsFiltered, data}`, paged by `start` and `length` instead of the cursor envelope. `recordsTotal` counts every deal the caller may see. schema: type: integer - name: start in: query description: 'Paged list: offset (default 0).' schema: type: integer - name: length in: query description: 'Paged list: rows (default 50, max 500).' schema: type: integer responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Deal' post: tags: - Deals summary: Create deal parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Deal' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Deal' /api/v1/deals/{public_id}/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Deals summary: Retrieve responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Deal' patch: tags: - Deals summary: Update responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Deal' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Deal' put: tags: - Deals summary: Replace (full update; PATCH for partial) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Deal' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Deal' delete: tags: - Deals summary: Soft-delete responses: '204': description: Deleted /api/v1/deals/{public_id}/won/: parameters: - $ref: '#/components/parameters/IdPath' post: tags: - Deals summary: Mark deal won description: Moves the deal into its pipeline's Won stage and closes it. Works on an open deal, and on a Lost or Abandoned one, which is closed again as won. Needs the permission to mark deals won or lost (`deal.won_lost`). responses: '200': description: The deal, now won content: application/json: schema: $ref: '#/components/schemas/Deal' '400': description: Already won '409': description: Changed by someone else a moment ago requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/DealWonRequest' /api/v1/deals/{public_id}/lost/: parameters: - $ref: '#/components/parameters/IdPath' post: tags: - Deals summary: Mark deal lost description: Moves the deal into its pipeline's Lost stage and closes it, with an optional reason. Needs the permission to mark deals won or lost (`deal.won_lost`). requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/DealLostRequest' responses: '200': description: The deal, now lost content: application/json: schema: $ref: '#/components/schemas/Deal' '400': description: Already lost '409': description: Changed by someone else a moment ago /api/v1/deals/{public_id}/abandoned/: parameters: - $ref: '#/components/parameters/IdPath' post: tags: - Deals summary: Mark deal abandoned description: Moves the deal into its pipeline's Abandoned stage and closes it, with an optional reason. Needs the permission to mark deals won or lost (`deal.won_lost`). requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/DealLostRequest' responses: '200': description: The deal, now abandoned content: application/json: schema: $ref: '#/components/schemas/Deal' '400': description: Already abandoned '409': description: Changed by someone else a moment ago /api/v1/deals/{public_id}/reopen/: parameters: - $ref: '#/components/parameters/IdPath' post: tags: - Deals summary: Reopen a closed deal description: Moves a closed deal back to the open stage it closed from, or to its pipeline's last open stage, and clears the close date and reason. Needs the permission to mark deals won or lost (`deal.won_lost`). responses: '200': description: The deal, reopened content: application/json: schema: $ref: '#/components/schemas/Deal' '400': description: Already open '409': description: Changed a moment ago, or the pipeline has no open stage /api/v1/deals/{public_id}/participants/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Deals summary: List participants responses: '200': description: The deal's participants, oldest first (not paginated) content: application/json: schema: type: array items: $ref: '#/components/schemas/DealParticipant' post: tags: - Deals summary: Add participant responses: '201': description: Participant added content: application/json: schema: $ref: '#/components/schemas/DealParticipant' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DealParticipantCreate' /api/v1/deals/participant-roles/: get: tags: - Deals summary: The roles a deal participant may have responses: '200': description: The roles a participant may have content: application/json: schema: type: array items: $ref: '#/components/schemas/DealParticipantRoleOption' /api/v1/deals/bulk-move-stage/: post: tags: - Deals summary: Bulk move stage description: 'The target stage decides each deal''s status: Won, Lost or Abandoned closes the deals (for Lost and Abandoned the reason, if given, is kept as `lost_reason`), and an open stage reopens closed ones. Moving deals into or out of a closed stage also needs the permission to mark deals won or lost (`deal.won_lost`).' responses: '200': description: Deals moved content: application/json: schema: $ref: '#/components/schemas/DealBulkMoveStageResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DealBulkMoveStageRequest' /api/v1/deals/ids/: get: tags: - Deals summary: Ids of every deal the list shows description: '"Select all N matching". Takes the list''s own query (search, status (open by default; all, won, lost), stage, pipeline, owner and tag), and answers the public ids in the list''s order, up to 10,000, with the total. Pass them in batches to the bulk actions.' responses: '200': description: Matching ids content: application/json: schema: $ref: '#/components/schemas/MatchingIds' /api/v1/deals/stats/: get: tags: - Deals summary: Deal counts and values for the list's cards responses: '200': description: Deal counts content: application/json: schema: $ref: '#/components/schemas/DealStats' /api/v1/deals/bulk-assign/: post: tags: - Deals summary: Bulk reassign owner description: Needs deal.bulk_assign (admins by default). Emits deal.assigned / deal.unassigned per deal whose owner changed and tells the new owner once. parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DealBulkAssignRequest' responses: '200': description: Deals reassigned content: application/json: schema: $ref: '#/components/schemas/DealBulkAssignResult' /api/v1/deals/bulk-delete/: post: tags: - Deals summary: Bulk soft-delete description: Needs deal.bulk_delete (admins by default). Best-effort, per id. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DealBulkDeleteRequest' responses: '200': description: Per-id outcome content: application/json: schema: $ref: '#/components/schemas/BulkDeleteResult' /api/v1/companies/: get: tags: - Companies summary: List companies parameters: - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Search' responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Company' post: tags: - Companies summary: Create company requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Company' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Company' /api/v1/companies/{public_id}/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Companies summary: Retrieve responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Company' patch: tags: - Companies summary: Update responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Company' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Company' put: tags: - Companies summary: Replace (full update; PATCH for partial) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Company' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Company' delete: tags: - Companies summary: Soft-delete responses: '204': description: Deleted /api/v1/companies/bulk-delete/: post: tags: - Companies summary: Bulk delete responses: '200': description: Per-id outcome content: application/json: schema: $ref: '#/components/schemas/BulkDeleteResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CompanyBulkDeleteRequest' /api/v1/tasks/: get: tags: - Tasks summary: List tasks parameters: - $ref: '#/components/parameters/Cursor' responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Task' post: tags: - Tasks summary: Create task requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Task' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Task' /api/v1/tasks/{public_id}/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Tasks summary: Retrieve responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Task' patch: tags: - Tasks summary: Update responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Task' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Task' put: tags: - Tasks summary: Replace (full update; PATCH for partial) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Task' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Task' delete: tags: - Tasks summary: Delete responses: '204': description: Deleted /api/v1/tasks/{public_id}/complete/: parameters: - $ref: '#/components/parameters/IdPath' post: tags: - Tasks summary: Mark complete responses: '200': description: The task, now done content: application/json: schema: $ref: '#/components/schemas/Task' requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/TaskCompleteRequest' /api/v1/tasks/bulk-complete/: post: tags: - Tasks summary: Bulk complete responses: '200': description: How many tasks were completed content: application/json: schema: $ref: '#/components/schemas/TaskBulkCompleteResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskBulkCompleteRequest' /api/v1/notes/: get: tags: - Notes & Activities summary: List notes description: The notes on one record, newest first. Notes on a lead, deal or task the caller cannot open are left out. A note names its record by `entity_public_id`, the record's public id. `entity_id` is accepted as the public id on writes, but is still answered as the record's integer key; use `entity_public_id`. parameters: - $ref: '#/components/parameters/Cursor' - name: entity_type in: query required: true schema: type: string enum: - Contact - Lead - Deal - Company - Task - name: entity_id in: query required: true description: The record's public id. Its integer key is still accepted for now. schema: type: string - name: search in: query required: false description: Only notes whose text contains this. schema: type: string responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Note' post: tags: - Notes & Activities summary: Create note requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Note' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Note' /api/v1/notes/{public_id}/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Notes & Activities summary: Retrieve responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Note' patch: tags: - Notes & Activities summary: Update responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Note' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Note' put: tags: - Notes & Activities summary: Replace (full update; PATCH for partial) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Note' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Note' delete: tags: - Notes & Activities summary: Delete responses: '204': description: Deleted /api/v1/activities/: get: tags: - Notes & Activities summary: List activities parameters: - $ref: '#/components/parameters/Cursor' - name: source in: query description: 'Only activity from this source: `app` (people using the app), `api_key`, `connected_app`, `automation` or `import`. Any other value is a 400.' schema: type: string enum: - app - api_key - connected_app - automation - import - inbound_webhook responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Activity' /api/v1/tags/: get: tags: - Taxonomy summary: List tags responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Tag' post: tags: - Taxonomy summary: Create tag responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Tag' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Tag' /api/v1/tags/{public_id}/: parameters: - $ref: '#/components/parameters/IdPath' patch: tags: - Taxonomy summary: Update tag responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Tag' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Tag' put: tags: - Taxonomy summary: Replace (full update; PATCH for partial) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Tag' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Tag' delete: tags: - Taxonomy summary: Delete tag responses: '204': description: Deleted /api/v1/pipelines/: get: tags: - Taxonomy summary: List pipelines responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Pipeline' post: tags: - Taxonomy summary: Create pipeline responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Pipeline' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Pipeline' /api/v1/pipelines/{public_id}/stages/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Taxonomy summary: List stages responses: '200': description: Every stage of the pipeline, in order. Not paginated. content: application/json: schema: type: array items: $ref: '#/components/schemas/PipelineStage' post: tags: - Taxonomy summary: Create stage responses: '201': description: The created stage. content: application/json: schema: $ref: '#/components/schemas/PipelineStage' requestBody: required: true content: application/json: schema: allOf: - $ref: '#/components/schemas/PipelineStageWrite' - type: object required: - name - order properties: {} /api/v1/automations/: get: tags: - Automations summary: List automations description: Every member reads them. Each carries its last run. responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Automation' post: tags: - Automations summary: Create an automation description: 'Owners and admins (automation.manage). Checked as a whole: a trigger of the record type, conditions as a list filter (match all is AND, match any is OR, `{}` for none), 1 to 10 actions with their inputs. Created switched on past the plan''s max_automations is a 402.' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Automation' '400': description: What is wrong, by field; `actions` lists each step's errors in order ({} for a step that is fine) '402': description: The plan's limit on automations switched on '403': description: Not allowed (members and viewers read only) requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Automation' /api/v1/automations/catalogue/: get: tags: - Automations summary: What an automation can be made of description: Per record type, its triggers and the actions it takes with their inputs (`kind` says what to draw; a `field` input lists the fields update_field may set). And where the organization stands against its plan. responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AutomationCatalogue' /api/v1/automations/runs/: get: tags: - Automations summary: Every automation's runs, newest first description: Kept 90 days. parameters: - name: status in: query schema: type: string enum: - queued - running - succeeded - failed - skipped responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/AutomationRun' '400': description: An unknown status /api/v1/automations/{public_id}/: parameters: - name: public_id in: path required: true schema: type: string format: uuid get: tags: - Automations summary: Retrieve an automation responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Automation' put: tags: - Automations summary: Replace an automation description: Owners and admins. Switching it on past the plan's max_automations is a 402. responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Automation' '402': description: The plan's limit on automations switched on requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Automation' patch: tags: - Automations summary: Update an automation description: Owners and admins. A change is checked against the rest (a new record type needs its own trigger and actions). Switching it on past the plan's max_automations is a 402. responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Automation' '402': description: The plan's limit on automations switched on requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Automation' delete: tags: - Automations summary: Delete an automation description: Owners and admins. Its run history goes with it. responses: '204': description: Deleted /api/v1/automations/{public_id}/runs/: parameters: - name: public_id in: path required: true schema: type: string format: uuid get: tags: - Automations summary: One automation's runs, newest first parameters: - name: status in: query schema: type: string enum: - queued - running - succeeded - failed - skipped responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/AutomationRun' /api/v1/task-types/: get: tags: - Taxonomy summary: List task types responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/TaskType' post: tags: - Taxonomy summary: Create task type responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/TaskType' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskType' /api/v1/task-priorities/: get: tags: - Taxonomy summary: List task priorities responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/TaskPriority' post: tags: - Taxonomy summary: Create task priority responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/TaskPriority' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskPriority' /api/v1/custom-field-definitions/: get: tags: - Custom Fields summary: List definitions responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/CustomFieldDefinition' post: tags: - Custom Fields summary: Create definition requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CustomFieldDefinition' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/CustomFieldDefinition' /api/v1/saved_views/: get: tags: - Saved Views & Filters summary: List saved views responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/SavedView' post: tags: - Saved Views & Filters summary: Create saved view requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SavedView' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/SavedView' /api/v1/saved_views/{public_id}/: parameters: - $ref: '#/components/parameters/IdPath' get: tags: - Saved Views & Filters summary: Retrieve responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/SavedView' patch: tags: - Saved Views & Filters summary: Update responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/SavedView' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SavedView' put: tags: - Saved Views & Filters summary: Replace (full update; PATCH for partial) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/SavedView' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SavedView' delete: tags: - Saved Views & Filters summary: Delete responses: '204': description: Deleted /api/v1/saved_views/{public_id}/copy/: parameters: - $ref: '#/components/parameters/IdPath' post: tags: - Saved Views & Filters summary: Copy a view description: A new view with the same setup, owned by whoever copies it. Members copy into a personal view only; owners and admins into either. Viewers copy nothing (403). The name must be free (400). requestBody: required: true content: application/json: schema: type: object properties: name: type: string scope: type: string enum: - personal - org default: personal required: - name responses: '201': description: The copy content: application/json: schema: $ref: '#/components/schemas/SavedView' /api/v1/search/: post: tags: - Dashboard & Search summary: Global search description: Searches the text of contacts, leads, deals, companies and notes, best match first. `created_by`, a member's public id, finds what that person wrote or did (their notes, including notes on tasks, and their activity), with or without `q`; send `q`, `created_by` or both. Activity is searched when `entity_types` names it, and by default with `created_by`. A person narrows only notes and activity, so naming another entity type together with `created_by` is a 400. Results respect what the caller may see (for example, lead visibility set to "Assigned only"). requestBody: required: true content: application/json: schema: type: object properties: q: type: string entity_types: type: array items: type: string enum: - Contact - Lead - Deal - Company - Note - Activity created_by: type: string format: uuid description: A member's public id (user_id); never an integer. responses: '200': description: Matches per entity type, with true counts content: application/json: schema: $ref: '#/components/schemas/GlobalSearchResult' /api/v1/filter-fields/{entity}/: parameters: - name: entity in: path required: true schema: type: string get: tags: - Dashboard & Search summary: Filter field metadata responses: '200': description: Filterable fields for the entity content: application/json: schema: $ref: '#/components/schemas/FilterFieldsResponse' /api/v1/list-views/{list_name}/: parameters: - name: list_name in: path required: true schema: type: string enum: - leads - contacts - companies - tasks - deals get: tags: - Dashboard & Search summary: A list's quick-view chips and default columns description: The quick-view chips shown above a list, each with the `filter` value it stands for (worked out now, in the organization's time zone, with "mine" written as "@me"), and the list's columns in their default order. Any member may read it. responses: '200': description: The list's chips and columns content: application/json: schema: type: object properties: list: type: string quick_views: type: array items: type: object properties: key: type: string label: type: string filter: type: object nullable: true description: A condition tree as the list's ?filter= takes; null for "all". columns: type: array items: type: object properties: key: type: string label: type: string group: type: string visible: type: boolean locked: type: boolean description: The column cannot be hidden. '404': description: Not a list /api/v1/dashboard/summary/: get: tags: - Dashboard & Search summary: Dashboard summary responses: '200': description: KPI overview for the period content: application/json: schema: $ref: '#/components/schemas/DashboardSummary' /api/v1/dashboard/pipeline-by-stage/: get: tags: - Dashboard & Search summary: Pipeline by stage responses: '200': description: One row per stage, ordered by pipeline then stage order content: application/json: schema: type: array items: $ref: '#/components/schemas/PipelineStageSummary' /api/v1/dashboard/activity-feed/: get: tags: - Dashboard & Search summary: Activity feed responses: '200': description: Most recent activities, newest first content: application/json: schema: type: array items: $ref: '#/components/schemas/Activity' /api/v1/import/file/: get: tags: - Import summary: List uploaded files responses: '200': description: Uploaded files, newest first; or with ?in_progress=true the latest unfinished one content: application/json: schema: oneOf: - type: array items: $ref: '#/components/schemas/ImportFile' - $ref: '#/components/schemas/ImportFileInProgress' post: tags: - Import summary: Upload import file (multipart) requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary responses: '201': description: Uploaded and parsed content: application/json: schema: $ref: '#/components/schemas/ImportFileUploaded' '400': description: Not .csv/.xlsx, over the size limit, or more rows than the plan's import_rows_per_file /api/v1/import/file/{file_id}/preview/: parameters: - name: file_id in: path required: true schema: type: string format: uuid get: tags: - Import summary: Preview rows responses: '200': description: Headers and sample rows content: application/json: schema: $ref: '#/components/schemas/ImportFilePreview' /api/v1/import/file/{file_id}/auto-detect/: parameters: - name: file_id in: path required: true schema: type: string format: uuid get: tags: - Import summary: Auto-detect mapping responses: '200': description: Suggested column mappings and the fields available content: application/json: schema: $ref: '#/components/schemas/ImportAutoDetect' /api/v1/import/mapping/: get: tags: - Import summary: List mappings responses: '200': description: Saved mappings, newest first content: application/json: schema: type: array items: $ref: '#/components/schemas/ImportMapping' post: tags: - Import summary: Create mapping responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/ImportMapping' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ImportMappingWrite' /api/v1/import/job/: get: tags: - Import summary: List jobs responses: '200': description: Import jobs, newest first content: application/json: schema: type: array items: $ref: '#/components/schemas/ImportJob' post: tags: - Import summary: Create job responses: '201': description: Job created and queued content: application/json: schema: $ref: '#/components/schemas/ImportJob' '409': description: An import of the same rows (same file or same bytes) is pending, running or paused; body has detail, job_id, status requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ImportJobCreate' /api/v1/import/job/{job_id}/: parameters: - name: job_id in: path required: true schema: type: string format: uuid get: tags: - Import summary: Job detail responses: '200': description: The job, for polling progress content: application/json: schema: $ref: '#/components/schemas/ImportJob' /api/v1/import/job/{job_id}/skip-report/: parameters: - name: job_id in: path required: true schema: type: string format: uuid get: tags: - Import summary: Skip report responses: '200': description: CSV attachment with columns row_number, reason content: text/csv: schema: type: string format: binary /api/v1/import/job/{job_id}/rerun/: parameters: - name: job_id in: path required: true schema: type: string format: uuid post: tags: - Import summary: Re-run job responses: '201': description: A new job over the same rows, queued content: application/json: schema: $ref: '#/components/schemas/ImportJob' /api/v1/import/job/{job_id}/resume/: parameters: - name: job_id in: path required: true schema: type: string format: uuid post: tags: - Import summary: Resume job responses: '200': description: The resumed job content: application/json: schema: $ref: '#/components/schemas/ImportJob' '400': description: Only paused jobs can be resumed /api/v1/webhooks/vivre/endpoints/: get: tags: - Webhooks summary: List outbound endpoints responses: '200': description: The CRM's webhook endpoints (scope `vivre`), newest first. Not paginated. content: application/json: schema: type: array items: $ref: '#/components/schemas/WebhookEndpoint' post: tags: - Webhooks summary: Create outbound endpoint responses: '201': description: 'Created. An API key is not given the signing secret in this response: to read it, rotate the secret in the app.' content: application/json: schema: $ref: '#/components/schemas/WebhookEndpointCreated' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookEndpointCreateRequest' /api/v1/webhooks/vivre/endpoints/{endpoint_id}/: parameters: - name: endpoint_id in: path required: true schema: type: string get: tags: - Webhooks summary: Endpoint detail responses: '200': description: The endpoint. content: application/json: schema: $ref: '#/components/schemas/WebhookEndpoint' patch: tags: - Webhooks summary: Update endpoint responses: '200': description: The updated endpoint, with the full URL. content: application/json: schema: $ref: '#/components/schemas/WebhookEndpoint' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookEndpointUpdateRequest' delete: tags: - Webhooks summary: Delete endpoint responses: '204': description: Deleted /api/v1/webhooks/vivre/events/: get: tags: - Webhooks summary: Event catalog responses: '200': description: The events a vivre-scoped endpoint may subscribe to. content: application/json: schema: $ref: '#/components/schemas/WebhookEventCatalog' /api/v1/webhooks/vivre/inbound/tokens/: get: tags: - Webhooks summary: List inbound tokens responses: '200': description: The organization's inbound tokens, newest first. Not paginated. `token` is left out for members, viewers and API keys. content: application/json: schema: type: array items: $ref: '#/components/schemas/InboundToken' post: tags: - Webhooks summary: Create inbound token responses: '201': description: 'Created, with `token` and, when signing is on, `secret`. Not available to API keys (403): do this in the app.' content: application/json: schema: $ref: '#/components/schemas/InboundToken' requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/InboundTokenCreateRequest' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/mapping/: parameters: - name: token_id in: path required: true schema: type: string patch: tags: - Webhooks summary: Set the field mapping (formula + value_map); a required field needs a payload field, formula or non-blank default responses: '200': description: Mapping saved and marked confirmed. content: application/json: schema: $ref: '#/components/schemas/InboundMappingResult' '400': description: Invalid mapping requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InboundMappingRequest' /api/v1/attribution-field-config/: get: tags: - Custom Fields summary: List attribution field configs (the value lists admins customised) responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/AttributionFieldConfig' post: tags: - Custom Fields summary: Create an attribution field config responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/AttributionFieldConfig' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttributionFieldConfig' /api/v1/attribution-field-config/upsert/: put: tags: - Custom Fields summary: Replace one field's whole value list, creating the config if needed responses: '200': description: An existing config for field_name was updated. content: application/json: schema: $ref: '#/components/schemas/AttributionFieldConfig' '201': description: A new config was created. content: application/json: schema: $ref: '#/components/schemas/AttributionFieldConfig' requestBody: required: true content: application/json: schema: type: object required: - field_name properties: field_name: type: string enum: - source - medium - channel - platform - priority - campaign - status - company_type description: 'The field whose value list this is: a lead attribution field (`source`, `medium`, `channel`, `platform`, `priority`, `campaign`), the lead `status`, or the company''s `company_type`.' values: type: array items: type: string description: Ordered option list. For status and company_type it must be non-empty with no blanks. /api/v1/attribution-field-config/{public_id}/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Custom Fields summary: Retrieve an attribution field config responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AttributionFieldConfig' put: tags: - Custom Fields summary: Replace an attribution field config responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AttributionFieldConfig' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttributionFieldConfig' patch: tags: - Custom Fields summary: Update an attribution field config responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AttributionFieldConfig' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttributionFieldConfig' delete: tags: - Custom Fields summary: Delete an attribution field config (back to the seeded values) responses: '204': description: Deleted. /api/v1/companies/bulk-tag/: post: tags: - Companies summary: Add tags to many companies responses: '200': description: Tag added content: application/json: schema: $ref: '#/components/schemas/BulkTagResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BulkTagRequest' /api/v1/companies/bulk-untag/: post: tags: - Companies summary: Remove tags from many companies responses: '200': description: Tag removed content: application/json: schema: $ref: '#/components/schemas/BulkUntagResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BulkTagRequest' /api/v1/companies/stats/: get: tags: - Companies summary: Company counts for the list header responses: '200': description: Company counts content: application/json: schema: $ref: '#/components/schemas/CompanyStats' /api/v1/companies/ids/: get: tags: - Companies summary: Ids of every company the list shows description: '"Select all N matching". Takes the list''s own query (search, filter (compound JSON) and ordering), and answers the public ids in the list''s order, up to 10,000, with the total. Pass them in batches to the bulk actions.' responses: '200': description: Matching ids content: application/json: schema: $ref: '#/components/schemas/MatchingIds' /api/v1/companies/{public_id}/activities/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Companies summary: A company's activity timeline responses: '200': description: The company's activities, cursor-paginated content: application/json: schema: $ref: '#/components/schemas/PaginatedActivities' /api/v1/companies/{public_id}/contacts/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Companies summary: A company's contacts, paginated responses: '200': description: The company's live contacts, newest first, cursor-paginated content: application/json: schema: $ref: '#/components/schemas/PaginatedContactSummaries' /api/v1/companies/{public_id}/restore/: parameters: - name: public_id in: path required: true schema: type: string post: tags: - Companies summary: Restore a deleted company responses: '200': description: The restored company content: application/json: schema: $ref: '#/components/schemas/Company' /api/v1/companies/{public_id}/tags/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Companies summary: A company's tags responses: '200': description: The company's tags by name (not paginated) content: application/json: schema: type: array items: $ref: '#/components/schemas/Tag' post: tags: - Companies summary: Tag a company responses: '201': description: The tag that was added content: application/json: schema: $ref: '#/components/schemas/Tag' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TagAssignRequest' /api/v1/companies/{public_id}/tags/{tag_id}/: parameters: - name: public_id in: path required: true schema: type: string - name: tag_id in: path required: true schema: type: string delete: tags: - Companies summary: Remove a tag from a company responses: '204': description: Tag removed /api/v1/contacts/bulk-delete/: post: tags: - Contacts summary: Delete many contacts (their leads and deals go with them) responses: '200': description: Per-id outcome content: application/json: schema: $ref: '#/components/schemas/BulkDeleteResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ContactBulkDeleteRequest' /api/v1/contacts/delete-impact/: post: tags: - Contacts summary: How many leads and deals deleting these contacts would take with them responses: '200': description: What deleting these contacts would take with it content: application/json: schema: $ref: '#/components/schemas/ContactDeleteImpact' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ContactDeleteImpactRequest' /api/v1/contacts/stats/: get: tags: - Contacts summary: Contact counts for the list header responses: '200': description: Contact counts content: application/json: schema: $ref: '#/components/schemas/ContactStats' /api/v1/contacts/ids/: get: tags: - Contacts summary: Ids of every contact the list shows description: '"Select all N matching". Takes the list''s own query (search, filter (compound JSON) and ordering), and answers the public ids in the list''s order, up to 10,000, with the total. Pass them in batches to the bulk actions.' responses: '200': description: Matching ids content: application/json: schema: $ref: '#/components/schemas/MatchingIds' /api/v1/contacts/{public_id}/deals/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Contacts summary: A contact's deals, paginated responses: '200': description: Deals of this contact (direct, through its leads, or as participant), cursor-paginated content: application/json: schema: $ref: '#/components/schemas/PaginatedDeals' /api/v1/contacts/{public_id}/leads/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Contacts summary: A contact's leads, paginated responses: '200': description: Leads of this contact the caller can see, cursor-paginated content: application/json: schema: $ref: '#/components/schemas/PaginatedLeads' /api/v1/contacts/{public_id}/tags/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Contacts summary: A contact's tags responses: '200': description: The contact's tags by name (not paginated) content: application/json: schema: type: array items: $ref: '#/components/schemas/Tag' post: tags: - Contacts summary: Tag a contact responses: '201': description: The tag that was added content: application/json: schema: $ref: '#/components/schemas/Tag' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TagAssignRequest' /api/v1/contacts/{public_id}/tags/{tag_id}/: parameters: - name: public_id in: path required: true schema: type: string - name: tag_id in: path required: true schema: type: string delete: tags: - Contacts summary: Remove a tag from a contact responses: '204': description: Tag removed /api/v1/custom-field-definitions/{public_id}/: parameters: - name: public_id in: path required: true schema: type: string put: tags: - Custom Fields summary: Replace a custom field definition responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/CustomFieldDefinition' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CustomFieldDefinition' patch: tags: - Custom Fields summary: Update a custom field definition (name, options, visibility) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/CustomFieldDefinition' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CustomFieldDefinition' delete: tags: - Custom Fields summary: Delete a custom field definition and its values responses: '204': description: Deleted, along with the fields it replaced and every stored value. /api/v1/custom-field-definitions/{public_id}/migrate-values/: parameters: - name: public_id in: path required: true schema: type: string post: tags: - Custom Fields summary: Move stored values to new options after an option edit responses: '200': description: Migration report. content: application/json: schema: $ref: '#/components/schemas/CustomFieldMigrationReport' requestBody: required: false content: application/json: schema: type: object properties: on_failure: type: string enum: - empty - default - add_option - abort default: empty description: 'What to do with a value the new type will not take: `empty` leaves the record with no value, `default` stores `default` instead, `add_option` adds the value to the options (select fields only), and `abort` changes nothing at all and answers 400 when any value will not convert.' default: description: Value stored for unconvertible values when on_failure=default; coerced to the field's type first. Any JSON type. /api/v1/custom-field-definitions/{public_id}/retype-preview/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Custom Fields summary: Which stored values would survive a change of type responses: '200': description: Conversion report. Writes nothing. content: application/json: schema: $ref: '#/components/schemas/CustomFieldConversionReport' /api/v1/custom-field-definitions/{public_id}/retype/: parameters: - name: public_id in: path required: true schema: type: string post: tags: - Custom Fields summary: Change a custom field's type responses: '201': description: The new, empty successor field. The old field is now superseded. content: application/json: schema: $ref: '#/components/schemas/CustomFieldDefinition' requestBody: required: true content: application/json: schema: type: object required: - field_type properties: field_type: type: string enum: - text - number - date - select - checkbox - email - url description: The new type. Must differ from the current one. options: type: array items: type: string description: Required (non-empty) when field_type is select. /api/v1/dashboard/leads-by-source/: get: tags: - Dashboard & Search summary: Leads by source for a date range responses: '200': description: Lead counts grouped by source for the window content: application/json: schema: $ref: '#/components/schemas/LeadsBySource' /api/v1/deals/bulk-tag/: post: tags: - Deals summary: Add tags to many deals responses: '200': description: Tag added content: application/json: schema: $ref: '#/components/schemas/BulkTagResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BulkTagRequest' /api/v1/deals/bulk-untag/: post: tags: - Deals summary: Remove tags from many deals responses: '200': description: Tag removed content: application/json: schema: $ref: '#/components/schemas/BulkUntagResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BulkTagRequest' /api/v1/deals/{public_id}/activities/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Deals summary: A deal's activity timeline responses: '200': description: The deal's activities, cursor-paginated content: application/json: schema: $ref: '#/components/schemas/PaginatedActivities' /api/v1/deals/{public_id}/companies/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Deals summary: Company links made before deals stopped linking to companies (read only) responses: '200': description: Company links made before deals stopped being linked to companies (not paginated) content: application/json: schema: type: array items: $ref: '#/components/schemas/DealCompanyLink' /api/v1/deals/{public_id}/participants/{participant_id}/: parameters: - name: public_id in: path required: true schema: type: string - name: participant_id in: path required: true schema: type: string delete: tags: - Deals summary: Remove a participant from a deal responses: '204': description: Participant removed /api/v1/deals/{public_id}/restore/: parameters: - name: public_id in: path required: true schema: type: string post: tags: - Deals summary: Restore a deleted deal responses: '200': description: The restored deal content: application/json: schema: $ref: '#/components/schemas/Deal' /api/v1/deals/{public_id}/tags/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Deals summary: A deal's tags responses: '200': description: The deal's tags by name (not paginated) content: application/json: schema: type: array items: $ref: '#/components/schemas/Tag' post: tags: - Deals summary: Tag a deal responses: '201': description: The tag that was added content: application/json: schema: $ref: '#/components/schemas/Tag' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TagAssignRequest' /api/v1/deals/{public_id}/tags/{tag_id}/: parameters: - name: public_id in: path required: true schema: type: string - name: tag_id in: path required: true schema: type: string delete: tags: - Deals summary: Remove a tag from a deal responses: '204': description: Tag removed /api/v1/import/file/{file_id}/reuse/: parameters: - name: file_id in: path required: true schema: type: string post: tags: - Import summary: Start a new import from a file already uploaded responses: '201': description: A new file record sharing the source's stored object content: application/json: schema: $ref: '#/components/schemas/ImportFile' /api/v1/import/file/{file_id}/scan-values/: parameters: - name: file_id in: path required: true schema: type: string post: tags: - Import summary: Distinct values in the file's mapped select columns responses: '200': description: Distinct values in the mapped select, boolean and date columns content: application/json: schema: $ref: '#/components/schemas/ImportScanValues' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ImportScanValuesRequest' /api/v1/import/job/{job_id}/import-remaining/: parameters: - name: job_id in: path required: true schema: type: string post: tags: - Import summary: Import the rows beyond one job's cap, as a follow-up job responses: '201': description: A follow-up job for the rows beyond the source job's window, queued content: application/json: schema: $ref: '#/components/schemas/ImportJob' /api/v1/import/job/{job_id}/rows/: parameters: - name: job_id in: path required: true schema: type: string get: tags: - Import summary: An import's rows and what happened to each responses: '200': description: Per-row outcome for the job, page-numbered content: application/json: schema: $ref: '#/components/schemas/ImportJobRows' /api/v1/import/mapping/{mapping_id}/: parameters: - name: mapping_id in: path required: true schema: type: string get: tags: - Import summary: Retrieve a saved column mapping responses: '200': description: The mapping content: application/json: schema: $ref: '#/components/schemas/ImportMapping' put: tags: - Import summary: Replace a saved column mapping responses: '200': description: Replaced content: application/json: schema: $ref: '#/components/schemas/ImportMapping' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ImportMappingWrite' delete: tags: - Import summary: Delete a saved column mapping responses: '204': description: Deleted /api/v1/leads/bulk-tag/: post: tags: - Leads summary: Add tags to many leads responses: '200': description: Tag added content: application/json: schema: $ref: '#/components/schemas/BulkTagResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BulkTagRequest' /api/v1/leads/bulk-untag/: post: tags: - Leads summary: Remove tags from many leads responses: '200': description: Tag removed content: application/json: schema: $ref: '#/components/schemas/BulkUntagResult' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BulkTagRequest' /api/v1/leads/stats/: get: tags: - Leads summary: Lead counts for the list header responses: '200': description: Lead counts content: application/json: schema: $ref: '#/components/schemas/LeadStats' /api/v1/leads/ids/: get: tags: - Leads summary: Ids of every lead the list shows description: '"Select all N matching". Takes the list''s own query (search, filter (compound JSON) and ordering), and answers the public ids in the list''s order, up to 10,000, with the total. Pass them in batches to the bulk actions.' responses: '200': description: Matching ids content: application/json: schema: $ref: '#/components/schemas/MatchingIds' /api/v1/leads/{public_id}/activities/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Leads summary: A lead's activity timeline responses: '200': description: The lead's activities, cursor-paginated content: application/json: schema: $ref: '#/components/schemas/PaginatedActivities' /api/v1/leads/{public_id}/restore/: parameters: - name: public_id in: path required: true schema: type: string post: tags: - Leads summary: Restore a deleted lead responses: '200': description: The restored lead content: application/json: schema: $ref: '#/components/schemas/Lead' /api/v1/leads/{public_id}/tags/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Leads summary: A lead's tags responses: '200': description: The lead's tags by name (not paginated) content: application/json: schema: type: array items: $ref: '#/components/schemas/Tag' post: tags: - Leads summary: Tag a lead responses: '201': description: The tag that was added content: application/json: schema: $ref: '#/components/schemas/Tag' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TagAssignRequest' /api/v1/leads/{public_id}/tags/{tag_id}/: parameters: - name: public_id in: path required: true schema: type: string - name: tag_id in: path required: true schema: type: string delete: tags: - Leads summary: Remove a tag from a lead responses: '204': description: Tag removed /api/v1/notifications/slack-routes/: get: tags: - Notifications summary: The Slack channels with the CRM notification types each takes, and the CRM's types (owner or admin) responses: '200': description: The channels with the CRM types each takes, and the CRM's types content: application/json: schema: type: object properties: channels: type: array items: $ref: '#/components/schemas/SlackRoute' crm_events: type: array items: $ref: '#/components/schemas/SlackEventType' /api/v1/notifications/slack-routes/{channel_id}/: parameters: - name: channel_id in: path required: true schema: type: string format: uuid patch: tags: - Notifications summary: Choose which CRM notification types go to a Slack channel (owner or admin) responses: '200': description: The channel's CRM types content: application/json: schema: type: object properties: id: type: string format: uuid name: type: string crm_events: type: array items: type: string requestBody: required: true content: application/json: schema: type: object required: - crm_events properties: crm_events: type: array description: Replaces the CRM's types only; the organization's are kept items: type: string /api/v1/pipelines/{public_id}/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Taxonomy summary: Retrieve a pipeline with its stages responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Pipeline' put: tags: - Taxonomy summary: Replace a pipeline responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Pipeline' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Pipeline' patch: tags: - Taxonomy summary: Update a pipeline (the default moves to another, never unset; names unique in any case) responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Pipeline' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Pipeline' delete: tags: - Taxonomy summary: Delete a pipeline and its stages responses: '204': description: Deleted '409': description: It has deals (deleted ones included), or is the default or the last pipeline /api/v1/pipelines/{public_id}/stages/reorder/: parameters: - name: public_id in: path required: true schema: type: string post: tags: - Taxonomy summary: Put every stage of the pipeline in a new order requestBody: required: true content: application/json: schema: type: object required: - order properties: order: type: array items: type: string format: uuid responses: '200': description: Every stage of the pipeline in its new order. content: application/json: schema: type: array items: $ref: '#/components/schemas/PipelineStage' '400': description: Not every stage once /api/v1/custom-field-definitions/reorder/: post: tags: - Custom Fields summary: Put an entity's active custom fields in the order forms show them requestBody: required: true content: application/json: schema: type: object required: - entity_type - order properties: entity_type: type: string order: type: array items: type: string format: uuid responses: '200': description: The order as saved. content: application/json: schema: type: object properties: order: type: array items: type: string format: uuid description: The field ids as sent, now in position order. '400': description: Not every active field once /api/v1/pipelines/{public_id}/stages/{stage_id}/: parameters: - name: public_id in: path required: true schema: type: string - name: stage_id in: path required: true schema: type: string patch: tags: - Taxonomy summary: Update a stage responses: '200': description: The updated stage. content: application/json: schema: $ref: '#/components/schemas/PipelineStage' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PipelineStageWrite' delete: tags: - Taxonomy summary: Delete a stage responses: '204': description: Deleted. /api/v1/reports/: get: tags: - Dashboard & Search summary: Scheduled reports responses: '200': description: The organization's scheduled reports, by name content: application/json: schema: type: array items: $ref: '#/components/schemas/ScheduledReport' post: tags: - Dashboard & Search summary: Create a scheduled report responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/ScheduledReport' requestBody: required: true content: application/json: schema: allOf: - $ref: '#/components/schemas/ScheduledReportWrite' - required: - name - cadence /api/v1/reports/downloads/{download_id}/: parameters: - name: download_id in: path required: true schema: type: string get: tags: - Dashboard & Search summary: A report download's progress responses: '200': description: Whether a queued report file is ready content: application/json: schema: $ref: '#/components/schemas/ReportDownloadStatus' /api/v1/reports/downloads/{download_id}/file/: parameters: - name: download_id in: path required: true schema: type: string get: tags: - Dashboard & Search summary: Download a finished report file responses: '200': description: The CSV file, as an attachment content: text/csv: schema: type: string format: binary /api/v1/reports/health/: get: tags: - Dashboard & Search summary: Scheduled reports that are failing responses: '200': description: Active report count and failing runs in the last 7 days content: application/json: schema: $ref: '#/components/schemas/ScheduledReportHealth' /api/v1/reports/schema/: get: tags: - Dashboard & Search summary: Report builder fields description: The columns, filter-only fields and operators a scheduled report can use. Admins only. responses: '200': description: Columns, filter-only fields and the operator catalogue for the report builder. content: application/json: schema: $ref: '#/components/schemas/SavedViewSchema' /api/v1/reports/{report_id}/: parameters: - name: report_id in: path required: true schema: type: string get: tags: - Dashboard & Search summary: Retrieve a scheduled report responses: '200': description: The report content: application/json: schema: $ref: '#/components/schemas/ScheduledReport' patch: tags: - Dashboard & Search summary: Update a scheduled report responses: '200': description: Updated content: application/json: schema: $ref: '#/components/schemas/ScheduledReport' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ScheduledReportWrite' delete: tags: - Dashboard & Search summary: Delete a scheduled report responses: '204': description: Deleted /api/v1/reports/{report_id}/logs/: parameters: - name: report_id in: path required: true schema: type: string get: tags: - Dashboard & Search summary: A scheduled report's runs responses: '200': description: The report's latest 50 runs, newest first content: application/json: schema: type: array items: $ref: '#/components/schemas/ScheduledReportLog' /api/v1/reports/{report_id}/run/: parameters: - name: report_id in: path required: true schema: type: string post: tags: - Dashboard & Search summary: Run a scheduled report now responses: '200': description: The CSV itself, when delivery=download and the report is small enough content: text/csv: schema: type: string format: binary '202': description: Mailing queued, or (delivery=download over the row limit) the file is being prepared content: application/json: schema: oneOf: - $ref: '#/components/schemas/ReportRunQueued' - $ref: '#/components/schemas/ReportDownloadQueued' requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/ReportRunRequest' /api/v1/task-priorities/{public_id}/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Taxonomy summary: Retrieve a task priority responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/TaskPriority' put: tags: - Taxonomy summary: Replace a task priority responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/TaskPriority' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskPriority' patch: tags: - Taxonomy summary: Update a task priority responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/TaskPriority' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskPriority' delete: tags: - Taxonomy summary: Delete a task priority responses: '204': description: Deleted. /api/v1/task-priorities/{public_id}/toggle/: parameters: - name: public_id in: path required: true schema: type: string post: tags: - Taxonomy summary: Turn a task priority on or off responses: '200': description: The built-in priority with its new disabled state. content: application/json: schema: $ref: '#/components/schemas/TaskPriority' /api/v1/task-types/{public_id}/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Taxonomy summary: Retrieve a task type responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/TaskType' put: tags: - Taxonomy summary: Replace a task type responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/TaskType' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskType' patch: tags: - Taxonomy summary: Update a task type responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/TaskType' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskType' delete: tags: - Taxonomy summary: Delete a task type responses: '204': description: Deleted. /api/v1/task-types/{public_id}/toggle/: parameters: - name: public_id in: path required: true schema: type: string post: tags: - Taxonomy summary: Turn a task type on or off responses: '200': description: The built-in task type with its new disabled state. content: application/json: schema: $ref: '#/components/schemas/TaskType' /api/v1/tasks/stats/: get: tags: - Tasks summary: Task counts for the list header responses: '200': description: Task counts content: application/json: schema: $ref: '#/components/schemas/TaskStats' /api/v1/tasks/ids/: get: tags: - Tasks summary: Ids of every task the list shows description: '"Select all N matching". Takes the list''s own query (search, filter (compound JSON), status, type, priority, assignee, dates and ordering), and answers the public ids in the list''s order, up to 10,000, with the total. Pass them in batches to the bulk actions.' responses: '200': description: Matching ids content: application/json: schema: $ref: '#/components/schemas/MatchingIds' /api/v1/templates/: get: tags: - Taxonomy summary: Message templates responses: '200': description: OK content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Template' post: tags: - Taxonomy summary: Create a message template description: 'WhatsApp templates are created and approved in WhatsApp (Meta), not here: `type` `whatsapp` is a 400. They are listed, read only, so they can be picked.' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Template' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Template' /api/v1/templates/{public_id}/: parameters: - name: public_id in: path required: true schema: type: string get: tags: - Taxonomy summary: Retrieve a message template responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Template' put: tags: - Taxonomy summary: Replace a message template description: 'A WhatsApp template is refused here (400 on type): they are made and approved in WhatsApp (Meta).' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Template' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Template' patch: tags: - Taxonomy summary: Update a message template description: 'A WhatsApp template is refused here (400 on type): they are made and approved in WhatsApp (Meta).' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Template' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Template' delete: tags: - Taxonomy summary: Delete a message template description: 'A WhatsApp template is refused here (400 on type): they are made and approved in WhatsApp (Meta).' responses: '204': description: Deleted. /api/v1/templates/{public_id}/preview/: parameters: - name: public_id in: path required: true schema: type: string post: tags: - Taxonomy summary: Render a template with the given values responses: '200': description: The template rendered with the given values. Writes nothing. content: application/json: schema: $ref: '#/components/schemas/TemplatePreview' requestBody: required: false content: application/json: schema: type: object properties: values: type: object additionalProperties: type: string default: {} description: Variable name to replacement text. /api/v1/webhooks/vivre/endpoints/{endpoint_id}/deliveries/: parameters: - name: endpoint_id in: path required: true schema: type: string get: tags: - Webhooks summary: An endpoint's deliveries, paginated and filterable responses: '200': description: The endpoint's deliveries, newest first, cursor-paginated. Filters ?status= and ?event_type=. content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/WebhookDelivery' /api/v1/webhooks/vivre/endpoints/{endpoint_id}/deliveries/{delivery_id}/retry/: parameters: - name: endpoint_id in: path required: true schema: type: string - name: delivery_id in: path required: true schema: type: string post: tags: - Webhooks summary: Send a failed delivery again responses: '200': description: The delivery, reset to pending and queued again. content: application/json: schema: $ref: '#/components/schemas/WebhookDelivery' /api/v1/webhooks/vivre/endpoints/{endpoint_id}/rotate-secret/: parameters: - name: endpoint_id in: path required: true schema: type: string post: tags: - Webhooks summary: Issue a new signing secret responses: '200': description: 'The new signing secret. Not available to API keys (403): do this in the app.' content: application/json: schema: $ref: '#/components/schemas/WebhookSecret' /api/v1/webhooks/vivre/endpoints/{endpoint_id}/subscriptions/: parameters: - name: endpoint_id in: path required: true schema: type: string get: tags: - Webhooks summary: An endpoint's event subscriptions responses: '200': description: The endpoint's subscriptions. Not paginated. content: application/json: schema: type: array items: $ref: '#/components/schemas/WebhookSubscription' post: tags: - Webhooks summary: Subscribe an endpoint to events responses: '201': description: Subscribed. content: application/json: schema: $ref: '#/components/schemas/WebhookSubscriptionCreated' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookSubscriptionRequest' delete: tags: - Webhooks summary: Unsubscribe an endpoint from events responses: '204': description: Unsubscribed. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookSubscriptionRequest' /api/v1/webhooks/vivre/endpoints/{endpoint_id}/test/: parameters: - name: endpoint_id in: path required: true schema: type: string post: tags: - Webhooks summary: Send a signed test event responses: '200': description: The receiver answered. Its status may be any code, including non-2xx. content: application/json: schema: $ref: '#/components/schemas/WebhookTestResult' /api/v1/webhooks/vivre/fields/{entity}/: parameters: - name: entity in: path required: true schema: type: string get: tags: - Webhooks summary: An entity's fields, standard and custom, for mapping in Zapier, Pabbly or n8n responses: '200': description: Standard and custom fields for the entity. content: application/json: schema: $ref: '#/components/schemas/WebhookFieldDiscovery' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/: parameters: - name: token_id in: path required: true schema: type: string get: tags: - Webhooks summary: Retrieve an inbound token responses: '200': description: The token. `token` is left out for members, viewers and API keys. content: application/json: schema: $ref: '#/components/schemas/InboundToken' patch: tags: - Webhooks summary: Update an inbound token (state, mapping, label) responses: '200': description: The updated token. It never includes `secret`, and `token` is left out for API keys. content: application/json: schema: $ref: '#/components/schemas/InboundToken' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InboundTokenUpdateRequest' delete: tags: - Webhooks summary: Delete an inbound token responses: '204': description: Deleted. description: 'Deletes the token. Not available to API keys (403): do this in the app.' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/logs/: parameters: - name: token_id in: path required: true schema: type: string get: tags: - Webhooks summary: A token's received payloads responses: '200': description: The token's received payloads, newest first, cursor-paginated. Filter ?status=. content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/InboundLogRow' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/logs/{log_id}/: parameters: - name: token_id in: path required: true schema: type: string - name: log_id in: path required: true schema: type: string get: tags: - Webhooks summary: One received payload, its tries and the record made responses: '200': description: One payload with every try. content: application/json: schema: $ref: '#/components/schemas/InboundLogDetail' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/logs/{log_id}/replay/: parameters: - name: token_id in: path required: true schema: type: string - name: log_id in: path required: true schema: type: string post: tags: - Webhooks summary: Process one held or failed payload again responses: '200': description: The payload was claimed and queued as a batch of one. content: application/json: schema: $ref: '#/components/schemas/InboundReplayStarted' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/replay/: parameters: - name: token_id in: path required: true schema: type: string post: tags: - Webhooks summary: Process held or failed payloads again, as a batch responses: '200': description: Every held and failed payload was claimed and queued as one batch. content: application/json: schema: $ref: '#/components/schemas/InboundReplayStarted' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/replay/{batch_id}/: parameters: - name: token_id in: path required: true schema: type: string - name: batch_id in: path required: true schema: type: string get: tags: - Webhooks summary: A replay batch's progress responses: '200': description: Progress of one replay. content: application/json: schema: $ref: '#/components/schemas/InboundReplayProgress' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/rotate-secret/: parameters: - name: token_id in: path required: true schema: type: string post: tags: - Webhooks summary: Issue a new signing secret for a token responses: '200': description: 'The token with its new signing secret. Not available to API keys (403): do this in the app.' content: application/json: schema: $ref: '#/components/schemas/InboundToken' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/sample/: parameters: - name: token_id in: path required: true schema: type: string get: tags: - Webhooks summary: The latest payload, for mapping responses: '200': description: The latest payload and the keys seen recently, for the mapper. content: application/json: schema: $ref: '#/components/schemas/InboundSample' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/secret/: parameters: - name: token_id in: path required: true schema: type: string delete: tags: - Webhooks summary: Stop requiring a signature on a token responses: '200': description: 'Signing turned off: the token, with `signing_enabled` false. Not available to API keys (403): do this in the app.' content: application/json: schema: $ref: '#/components/schemas/InboundToken' /api/v1/webhooks/vivre/inbound/tokens/{token_id}/stats/: parameters: - name: token_id in: path required: true schema: type: string get: tags: - Webhooks summary: A token's received, processed and failed counts responses: '200': description: Payload counts by status, and their total. content: application/json: schema: $ref: '#/components/schemas/InboundTokenStats' components: securitySchemes: apiKeyAuth: type: apiKey in: header name: X-Api-Key description: 'An API key, made in the app under Developers, API keys. Send it as `X-Api-Key: ` or `Authorization: Api-Key `. A key belongs to one organization and works on that organization''s CRM endpoints, as its scopes and the role of the person it acts for allow.' parameters: IdPath: name: public_id in: path required: true description: The record's public id (a UUID). schema: type: string Cursor: name: cursor in: query schema: type: string description: Opaque pagination cursor (follow next/previous URLs). Search: name: search in: query schema: type: string Ordering: name: ordering in: query schema: type: string description: Field to order by; prefix with '-' for descending. IdempotencyKey: name: Idempotency-Key in: header schema: type: string description: Unique key for safe retries (24h replay window). responses: ValidationError: description: Validation error (field dict or detail string) content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: Not found content: application/json: schema: $ref: '#/components/schemas/Error' schemas: Error: type: object description: Standard error envelope. `detail` is a string or a per-field map; some endpoints use `error`/`message`. properties: detail: oneOf: - type: string - type: object - type: array items: type: string error: type: string message: type: string Automation: type: object properties: id: type: string format: uuid readOnly: true name: type: string maxLength: 120 entity: enum: - Lead - Contact - Company - Deal - Task type: string trigger: type: string maxLength: 64 trigger_label: description: Computed by the server. readOnly: true conditions: type: object additionalProperties: true actions: type: array items: {} run_on_imports: type: boolean is_active: type: boolean created_by: description: Computed by the server. readOnly: true last_run: description: Computed by the server. readOnly: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true required: - name - entity - trigger AutomationRun: type: object description: One time an automation fired. `skipped` says why in `reason`; `steps` is what each action did, in order, up to the first that failed. properties: id: type: string format: uuid automation: type: object properties: id: type: string format: uuid name: type: string trigger: type: string entity: type: string record_id: type: string description: The record's public id status: type: string enum: - queued - running - succeeded - failed - skipped reason: type: string steps: type: array items: type: object properties: action: type: string ok: type: boolean detail: type: string data: type: object created_at: type: string format: date-time finished_at: type: - string - 'null' format: date-time AutomationCatalogue: type: object properties: entities: type: array items: type: object properties: entity: type: string triggers: type: array items: type: object properties: key: type: string label: type: string actions: type: array items: type: object properties: key: type: string label: type: string params: type: array items: type: object properties: key: type: string label: type: string kind: type: string enum: - text - number - choice - member - field - value - endpoint - task_type - task_priority required: type: boolean choices: type: array items: type: string limits: type: object properties: max_automations: type: integer active: type: integer automation_runs_per_day: type: integer runs_today: type: integer PaginatedEnvelope: type: object properties: count: type: integer next: type: - string - 'null' format: uri previous: type: - string - 'null' format: uri results: type: array items: type: object Contact: type: object properties: created_source: enum: - '' - api_key - connected_app - automation - import - inbound_webhook type: string readOnly: true created_source_label: type: string readOnly: true id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true company: type: object properties: id: type: string format: uuid readOnly: true name: type: string maxLength: 255 required: - name readOnly: true company_public_id: type: string format: uuid writeOnly: true nullable: true first_name: type: string maxLength: 150 last_name: type: string maxLength: 150 full_name: type: string readOnly: true job_title: type: string maxLength: 150 email: type: string format: email nullable: true maxLength: 254 email_secondary: type: string format: email nullable: true maxLength: 254 phone_country_code: type: string maxLength: 5 phone: type: string nullable: true maxLength: 20 phone_secondary_country_code: type: string maxLength: 5 phone_secondary: type: string nullable: true maxLength: 20 whatsapp_country_code: type: string maxLength: 5 whatsapp_number: type: string nullable: true maxLength: 20 opted_out_channels: type: object additionalProperties: true last_activity_at: type: string format: date-time readOnly: true nullable: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true created_by_uuid: description: Computed by the server. readOnly: true created_by_username: description: Computed by the server. readOnly: true created_by_first_name: description: Computed by the server. readOnly: true created_by_last_name: description: Computed by the server. readOnly: true created_by_name: description: Computed by the server. readOnly: true custom_fields: type: object additionalProperties: true required: - first_name Lead: type: object properties: created_source: enum: - '' - api_key - connected_app - automation - import - inbound_webhook type: string readOnly: true created_source_label: type: string readOnly: true id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true contact: type: object properties: id: type: string format: uuid readOnly: true first_name: type: string maxLength: 150 last_name: type: string maxLength: 150 full_name: type: string readOnly: true email: type: string format: email nullable: true maxLength: 254 phone: type: string nullable: true maxLength: 20 phone_country_code: type: string maxLength: 5 job_title: type: string maxLength: 150 whatsapp_number: type: string nullable: true maxLength: 20 whatsapp_country_code: type: string maxLength: 5 company_name: description: Computed by the server. readOnly: true company_id: description: Computed by the server. readOnly: true required: - first_name readOnly: true contact_id: type: string writeOnly: true nullable: true lead_origin: enum: - import - api - manual type: string readOnly: true status: type: string maxLength: 255 source: type: string nullable: true maxLength: 255 medium: type: string nullable: true maxLength: 255 channel: type: string nullable: true maxLength: 100 platform: type: string nullable: true maxLength: 255 campaign: type: string nullable: true maxLength: 255 priority: type: string nullable: true maxLength: 100 lead_date: type: string format: date nullable: true score: type: integer maximum: 100 minimum: 0 assigned_to_id: type: string writeOnly: true nullable: true assigned_to_uuid: description: Computed by the server. readOnly: true assigned_to_username: description: Computed by the server. readOnly: true assigned_to_first_name: description: Computed by the server. readOnly: true assigned_to_last_name: description: Computed by the server. readOnly: true assigned_to_name: description: Computed by the server. readOnly: true tags: description: Computed by the server. readOnly: true custom_fields: type: object additionalProperties: true import_job_id: type: string format: uuid readOnly: true nullable: true is_potential_duplicate: type: boolean readOnly: true duplicate_reason: type: string enum: - '' - duplicate readOnly: true notes_count: description: Computed by the server. readOnly: true activities_count: description: Computed by the server. readOnly: true deals_count: description: Computed by the server. readOnly: true tasks_count: description: Computed by the server. readOnly: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true Deal: type: object properties: created_source: enum: - '' - api_key - connected_app - automation - import - inbound_webhook type: string readOnly: true created_source_label: type: string readOnly: true id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true contact: type: object properties: id: type: string format: uuid readOnly: true first_name: type: string maxLength: 150 last_name: type: string maxLength: 150 full_name: type: string readOnly: true email: type: string format: email nullable: true maxLength: 254 phone: type: string nullable: true maxLength: 20 phone_country_code: type: string maxLength: 5 job_title: type: string maxLength: 150 whatsapp_number: type: string nullable: true maxLength: 20 whatsapp_country_code: type: string maxLength: 5 company_name: description: Computed by the server. readOnly: true company_id: description: Computed by the server. readOnly: true required: - first_name readOnly: true contact_id: type: string writeOnly: true nullable: true lead: type: object properties: id: type: string format: uuid readOnly: true lead_origin: enum: - import - api - manual type: string source: type: string nullable: true maxLength: 255 status: type: string maxLength: 255 score: type: integer maximum: 100 minimum: 0 created_at: type: string format: date-time readOnly: true readOnly: true lead_id: type: string writeOnly: true nullable: true pipeline: type: object properties: id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true name: type: string maxLength: 255 is_default: type: boolean stages: type: array items: type: object properties: id: type: string format: uuid readOnly: true name: type: string maxLength: 100 order: type: integer maximum: 2147483647 minimum: 0 probability: type: integer maximum: 2147483647 minimum: -2147483648 stage_type: enum: - open - won - lost - abandoned type: string color: type: string maxLength: 7 created_at: type: string format: date-time readOnly: true required: - name - order readOnly: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true required: - name readOnly: true pipeline_id: type: string writeOnly: true stage: type: object properties: id: type: string format: uuid readOnly: true name: type: string maxLength: 100 order: type: integer maximum: 2147483647 minimum: 0 probability: type: integer maximum: 2147483647 minimum: -2147483648 stage_type: enum: - open - won - lost - abandoned type: string color: type: string maxLength: 7 created_at: type: string format: date-time readOnly: true required: - name - order readOnly: true stage_id: type: string writeOnly: true title: type: string maxLength: 255 status: enum: - open - won - lost - abandoned type: string readOnly: true value: type: string format: decimal multipleOf: 0.01 maximum: 10000000000 minimum: -10000000000 nullable: true currency: type: string maxLength: 3 expected_close_date: type: string format: date nullable: true closed_at: type: string format: date readOnly: true nullable: true lost_reason: type: string readOnly: true nullable: true last_activity_at: type: string format: date-time readOnly: true nullable: true assigned_to_id: type: string writeOnly: true nullable: true assigned_to_uuid: description: Computed by the server. readOnly: true assigned_to_username: description: Computed by the server. readOnly: true assigned_to_first_name: description: Computed by the server. readOnly: true assigned_to_last_name: description: Computed by the server. readOnly: true assigned_to_name: description: Computed by the server. readOnly: true stage_name: type: string readOnly: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true custom_fields: type: object additionalProperties: true required: - title Company: type: object properties: created_source: enum: - '' - api_key - connected_app - automation - import - inbound_webhook type: string readOnly: true created_source_label: type: string readOnly: true id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true name: type: string maxLength: 255 contacts_count: description: Computed by the server. readOnly: true industry: type: string nullable: true maxLength: 100 size: enum: - 1-10 - 11-50 - 51-200 - 201-500 - 501-1000 - 1000+ type: string nullable: true phone_country_code: type: string maxLength: 5 phone: type: string nullable: true maxLength: 20 email: type: string format: email nullable: true maxLength: 254 website: type: string nullable: true maxLength: 500 linkedin_url: type: string nullable: true maxLength: 500 company_type: type: string nullable: true maxLength: 255 owner_id: type: string writeOnly: true nullable: true owner_uuid: description: Computed by the server. readOnly: true owner_name: description: Computed by the server. readOnly: true street: type: string nullable: true city: type: string nullable: true maxLength: 100 state: type: string nullable: true maxLength: 100 postal_code: type: string nullable: true maxLength: 20 country: type: string nullable: true maxLength: 100 gstin: type: string nullable: true maxLength: 40 pan: type: string nullable: true maxLength: 40 annual_revenue: type: string format: decimal multipleOf: 0.01 maximum: 10000000000000000 minimum: -10000000000000000 nullable: true annual_revenue_currency: type: string maxLength: 10 employee_count: type: integer maximum: 2147483647 nullable: true minimum: 0 description: type: string nullable: true founded_year: type: integer maximum: 32767 nullable: true minimum: 0 parent_company: description: Computed by the server. readOnly: true parent_company_id: type: string writeOnly: true nullable: true tags: description: Computed by the server. readOnly: true last_activity_at: type: string format: date-time readOnly: true nullable: true created_by_uuid: description: Computed by the server. readOnly: true created_by_username: description: Computed by the server. readOnly: true created_by_first_name: description: Computed by the server. readOnly: true created_by_last_name: description: Computed by the server. readOnly: true created_by_name: description: Computed by the server. readOnly: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true custom_fields: type: object additionalProperties: true required: - name Task: type: object properties: created_source: enum: - '' - api_key - connected_app - automation - import - inbound_webhook type: string readOnly: true created_source_label: type: string readOnly: true id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true title: type: string maxLength: 255 type: type: string maxLength: 100 description: type: string due_date: type: string format: date nullable: true priority: type: string default: medium maxLength: 100 assignee_id: type: string writeOnly: true nullable: true linked_entity_type: type: string nullable: true maxLength: 50 linked_entity_id: type: string nullable: true maxLength: 36 status: enum: - pending - in_progress - done - cancelled type: string completed_at: type: string format: date-time readOnly: true nullable: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true required: - title - type Note: type: object properties: created_source: enum: - '' - api_key - connected_app - automation - import - inbound_webhook type: string readOnly: true created_source_label: type: string readOnly: true id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true entity_type: enum: - Contact - Lead - Deal - Company - Task type: string entity_id: type: string nullable: true entity_public_id: type: string format: uuid readOnly: true content: type: string created_by_uuid: description: Computed by the server. readOnly: true created_by_username: description: Computed by the server. readOnly: true created_by_first_name: description: Computed by the server. readOnly: true created_by_last_name: description: Computed by the server. readOnly: true created_by_name: description: Computed by the server. readOnly: true edited_by: type: integer readOnly: true edited_by_uuid: description: Computed by the server. readOnly: true edited_by_username: description: Computed by the server. readOnly: true edited_by_first_name: description: Computed by the server. readOnly: true edited_by_last_name: description: Computed by the server. readOnly: true edited_by_name: description: Computed by the server. readOnly: true edited_at: type: string format: date-time readOnly: true nullable: true is_ai_generated: type: boolean slash_commands: description: Computed by the server. readOnly: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true required: - entity_type - content CustomFieldDefinition: type: object properties: id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true entity_type: type: string maxLength: 50 field_name: type: string maxLength: 255 field_type: enum: - text - number - date - select - checkbox - email - url type: string is_required: type: boolean options: type: array items: {} confirm_orphans: type: boolean writeOnly: true default: false state: enum: - active - superseded - archived type: string readOnly: true name_clash: description: Computed by the server. readOnly: true created_at: type: string format: date-time readOnly: true required: - entity_type - field_name - field_type SavedView: type: object properties: id: type: string format: uuid readOnly: true name: type: string maxLength: 255 scope: enum: - personal - org type: string entity: enum: - lead type: string readOnly: true config: type: object additionalProperties: true created_by: description: Computed by the server. readOnly: true can_edit: description: Computed by the server. readOnly: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true required: - name PaginatedLeads: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Lead' PaginatedDeals: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Deal' Activity: type: object properties: source: enum: - '' - api_key - connected_app - automation - import - inbound_webhook type: string readOnly: true source_label: type: string readOnly: true id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true entity_type: enum: - Contact - Lead - Deal - Company type: string readOnly: true entity_id: type: string readOnly: true entity_public_id: description: Computed by the server. readOnly: true type: enum: - email_sent - email_received - whatsapp_sent - call_made - call_received - meeting - note_added - note_edited - note_deleted - task_created - task_completed - stage_changed - status_changed - lead_created - contact_created - company_created - deal_created - tag_added - tag_removed - ai_action - import - other type: string readOnly: true actor_type: enum: - human - ai - automation type: string readOnly: true created_by_uuid: description: Computed by the server. readOnly: true created_by_username: description: Computed by the server. readOnly: true created_by_first_name: description: Computed by the server. readOnly: true created_by_last_name: description: Computed by the server. readOnly: true created_by_name: description: Computed by the server. readOnly: true is_outbound: type: boolean readOnly: true response_time_seconds: type: integer readOnly: true nullable: true content: type: string readOnly: true nullable: true created_at: type: string format: date-time readOnly: true email: description: Computed by the server. readOnly: true AttributionFieldConfig: type: object properties: id: type: string format: uuid readOnly: true field_name: type: string maxLength: 50 values: type: array items: {} updated_at: type: string format: date-time readOnly: true required: - field_name Pipeline: type: object properties: id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true name: type: string maxLength: 255 is_default: type: boolean stages: type: array items: type: object properties: id: type: string format: uuid readOnly: true name: type: string maxLength: 100 order: type: integer maximum: 2147483647 minimum: 0 probability: type: integer maximum: 2147483647 minimum: -2147483648 stage_type: enum: - open - won - lost - abandoned type: string color: type: string maxLength: 7 created_at: type: string format: date-time readOnly: true required: - name - order readOnly: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true required: - name Tag: type: object properties: id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true name: type: string maxLength: 255 color_hex: type: string maxLength: 7 created_at: type: string format: date-time readOnly: true required: - name TaskPriority: type: object properties: id: type: string format: uuid readOnly: true name: type: string maxLength: 100 slug: type: string maxLength: 100 color: type: string maxLength: 7 is_builtin: type: boolean readOnly: true order: type: integer readOnly: true disabled: description: Computed by the server. readOnly: true required: - name - slug TaskType: type: object properties: id: type: string format: uuid readOnly: true name: type: string maxLength: 100 slug: type: string maxLength: 100 is_builtin: type: boolean readOnly: true order: type: integer readOnly: true disabled: description: Computed by the server. readOnly: true required: - name - slug Template: type: object properties: id: type: string format: uuid readOnly: true organisation: type: string format: uuid readOnly: true name: type: string maxLength: 255 type: enum: - email - whatsapp - note - task type: string content: type: string variables: type: array items: {} subject: type: string readOnly: true is_shared: type: boolean readOnly: true created_by_uuid: description: Computed by the server. readOnly: true created_by_username: description: Computed by the server. readOnly: true created_by_first_name: description: Computed by the server. readOnly: true created_by_last_name: description: Computed by the server. readOnly: true created_by_name: description: Computed by the server. readOnly: true created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true required: - name - type - content PipelineStage: type: object description: A stage of a pipeline. properties: id: type: string format: uuid readOnly: true description: The stage's public_id. name: type: string maxLength: 100 order: type: integer minimum: 0 description: Position in the pipeline; unique per pipeline. probability: type: integer minimum: 0 maximum: 100 stage_type: type: string enum: - open - won - lost - abandoned description: '`open`, `won`, `lost` or `abandoned`. Won, Lost and Abandoned are the fixed stages every pipeline ends in; every other stage is open.' color: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: '#RRGGBB; stored upper-cased.' created_at: type: string format: date-time readOnly: true PipelineStageWrite: type: object description: Writable fields of an open stage. On create, name and order are required; a position Won, Lost or Abandoned holds may be asked for, and they move past it, staying last. The fixed stages cannot be changed (400) or deleted (409), nor the last open stage deleted (409). properties: name: type: string maxLength: 100 description: Trimmed; must not be blank and must be unique in the pipeline. order: type: integer minimum: 0 description: Must not be held by another stage of the pipeline. probability: type: integer minimum: 0 maximum: 100 default: 0 stage_type: type: string enum: - open default: open description: A stage people add is an open one, and a stage keeps its type (400 otherwise). Won, Lost and Abandoned come with every pipeline. color: type: string pattern: ^#[0-9A-Fa-f]{6}$ default: '#8B3A20' CustomFieldConversionReport: type: object description: What changing a field's type would do to its stored values. Writes nothing. properties: total: type: integer description: Records holding a key for the field. clean: type: integer description: Values that convert without change. blank: type: integer description: Records whose stored value is null or empty. lossy: type: array items: type: object properties: record_id: type: string format: uuid value: description: The stored value as held in JSON (any JSON type). becomes: type: string description: Text form of the converted value. failed: type: array items: type: object properties: record_id: type: string format: uuid value: description: The stored value as held in JSON (any JSON type). reason: type: string CustomFieldMigrationReport: type: object description: What happened when the old field's values were moved onto the new field that replaced it. properties: migrated: type: integer lossy: type: integer failed: type: integer blank: type: integer added_options: type: array items: type: string description: Options appended to the select list (on_failure=add_option). SavedViewColumnField: type: object description: A column the saved-view builder can show. Custom field entries carry custom, required and field_id. properties: key: type: string description: Value for column.field, e.g. lead__status or cf__lead__Budget. entity: type: string enum: - lead - contact - company field: type: string label: type: string type: type: string enum: - text - email - number - date - datetime - select - user - tags - checkbox - url description: The column's data type, which decides the operators it takes. options: type: - array - 'null' items: type: string description: Choices for select fields; null otherwise. filterable: type: boolean filter_key: type: - string - 'null' description: Key to use in filter.field; null when not filterable. filter_ops: type: array description: The type's operators, without `is_null` and `is_not_null` where no record can be empty. A saved filter using one of those is still accepted. items: type: string enum: - eq - neq - contains - gt - lt - gte - lte - in - not_in - is_null - is_not_null custom: type: boolean description: Present (true) only on custom field entries. required: type: boolean description: Custom field entries only. field_id: type: string format: uuid description: Custom field entries only. SavedViewFilterOnlyField: type: object description: A field usable in filters but not as a column. properties: key: type: string entity: type: string enum: - lead - contact field: type: string label: type: string type: type: string enum: - user_id - record_id - tag_id description: 'What the field filters by: a user, a record or a tag.' options: type: - array - 'null' items: type: string description: Always null for the current filter-only fields. filter_ops: type: array items: type: string enum: - eq - neq - contains - gt - lt - gte - lte - in - not_in - is_null - is_not_null SavedViewFilterOp: type: object properties: label: type: string needs_value: type: boolean SavedViewSchema: type: object description: The fields and operators the report builder can use. properties: column_fields: type: array items: $ref: '#/components/schemas/SavedViewColumnField' filter_only_fields: type: array items: $ref: '#/components/schemas/SavedViewFilterOnlyField' filter_ops: type: object description: 'Map of op name to its metadata. Keys: eq, neq, contains, gt, lt, gte, lte, in, not_in, is_null, is_not_null.' additionalProperties: $ref: '#/components/schemas/SavedViewFilterOp' TemplatePreview: type: object properties: template_id: type: string format: uuid description: The template's public id. A read-only key may preview. rendered_content: type: string description: Content with each known {{variable}} replaced; unknown placeholders are left as written. GlobalSearchResult: type: object description: Ranked matches per entity type. Only the entity types searched appear in `results` and `counts`. properties: q: type: string description: The query, trimmed. created_by: type: string format: uuid nullable: true description: The member searched for, as given; null without one. total: type: integer description: Rows returned across all types (each type capped at `limit`), not the true match count. results: type: object description: One list per searched entity type, each at most `limit` rows. properties: Contact: type: array items: $ref: '#/components/schemas/Contact' Lead: type: array items: $ref: '#/components/schemas/Lead' Deal: type: array items: $ref: '#/components/schemas/Deal' Company: type: array items: $ref: '#/components/schemas/Company' Note: type: array items: $ref: '#/components/schemas/Note' Activity: type: array items: $ref: '#/components/schemas/Activity' counts: type: object description: True number of matches per searched entity type, ignoring the cap. properties: Contact: type: integer Lead: type: integer Deal: type: integer Company: type: integer Note: type: integer Activity: type: integer total_matches: type: integer description: Sum of `counts`. limit: type: integer description: The most results returned per entity type (currently 20). truncated: type: boolean description: True when any entity type had more matches than were returned. FilterFieldEntry: type: object description: 'One filterable field: the standard fields, then the organization''s custom fields.' required: - key - label - type - group - is_custom - can_be_empty properties: key: type: string description: The key to use in a compound `filter` condition; custom fields are `cf__`. label: type: string type: type: string description: 'Standard fields: `string`, `email`, `choice`, `integer`, `decimal`, `date`, `datetime` or `uuid`. Custom fields: the field''s own type, `text`, `number`, `date`, `select`, `checkbox`, `email` or `url`.' enum: - string - email - choice - integer - decimal - date - datetime - uuid - text - number - select - checkbox - url group: type: string description: Panel group, e.g. "Contact Info", "Dates", "Custom Fields". choices: type: array description: Present for choice fields, for lead attribution fields the organization has values for, and for custom select fields with options. items: type: string is_custom: type: boolean can_be_empty: type: boolean description: Whether any record can have no value here. False for a field that always holds one (required, or with a default, such as Status, Score, Title, Created At), where "is empty" finds nothing; only when this is true do `is_null` and `not_null` make sense. Empty means no value, or blank text. field_id: type: string format: uuid description: Custom fields only; the definition's stable public id. FilterFieldsResponse: type: object properties: entity: type: string description: The entity, capitalised. enum: - Lead - Contact - Deal - Task - Company fields: type: array items: $ref: '#/components/schemas/FilterFieldEntry' CurrencyTotals: type: object description: Map of currency code to summed deal value in that currency. Never summed across currencies. additionalProperties: type: number DashboardSummary: type: object properties: pipeline_value_by_currency: $ref: '#/components/schemas/CurrencyTotals' deals_open: type: integer deals_won_this_month: type: integer description: Deals won in the selected period (named for the default 30d window). deals_lost_this_month: type: integer description: Deals lost in the selected period. win_rate: type: number description: Won / (won + lost) in the period, as a percentage rounded to 1 dp; 0.0 when none closed. tasks_due_today: type: integer contacts_total: type: integer leads_total: type: integer total_companies: type: integer period_start: type: string format: date time_range: type: string enum: - today - 7d - 30d - 90d description: Present only when no from_date/to_date were given. from_date: type: string format: date description: Present only for a custom range. to_date: type: string format: date description: Present only for a custom range. PipelineStageSummary: type: object properties: stage_uuid: type: string format: uuid description: The stage's public id. stage_name: type: string pipeline_uuid: type: string format: uuid description: The pipeline's public id, the id the ?pipeline_id= filter takes. order: type: integer deal_count: type: integer description: Open, non-deleted deals in the stage visible to the caller. deal_value_by_currency: $ref: '#/components/schemas/CurrencyTotals' LeadsBySource: type: object properties: results: type: array description: Biggest count first, then by source name. items: type: object properties: source: type: string description: Source label; leads with no source are grouped under "Unknown". count: type: integer time_range: type: string enum: - today - 7d - 30d - 90d - 6m period_start: type: string format: date ImportFileAnalysis: type: object description: A quality analysis of the file, made at upload. Files uploaded before this was added may not have it. properties: columns: type: object description: Map of header to its stats; repeated headers get a _2, _3 suffix. additionalProperties: type: object properties: blank_rate: type: number description: Fraction 0.0-1.0 of blank values. duplicate_row_count: type: integer email_column_hints: type: array items: type: string phone_column_hints: type: array items: type: string placeholder_hints: type: array items: type: object properties: column: type: string value: type: string row_count: type: integer distinct_counterparts: type: - integer - 'null' total_rows: type: integer share: type: number total_rows: type: integer ImportFile: type: object properties: id: type: string format: uuid original_name: type: string row_count: type: integer description: Rows an import job will process. total_rows_in_file: type: integer description: True data rows in the file; 0 on older rows and on files created by reuse. headers: type: array items: type: string wizard_step: type: string enum: - uploaded - mapped - resolved - confirmed - running - done - failed - paused uploaded_at: type: string format: date-time file_analysis: oneOf: - $ref: '#/components/schemas/ImportFileAnalysis' - type: 'null' PreviousImport: type: object description: The latest import in this organization of a file with identical bytes. properties: job_id: type: string format: uuid status: type: string enum: - pending - processing - paused - done - failed file_name: type: string created_at: type: string format: date-time completed_at: type: - string - 'null' format: date-time success_rows: type: integer total_rows: type: integer ImportFileUploaded: allOf: - $ref: '#/components/schemas/ImportFile' - type: object properties: previous_import: oneOf: - $ref: '#/components/schemas/PreviousImport' - type: 'null' ImportFileInProgress: type: object properties: in_progress: type: boolean file: description: The latest unfinished file with its latest job and that job's mapping, or null. oneOf: - type: 'null' - allOf: - $ref: '#/components/schemas/ImportFile' - type: object properties: mapping: oneOf: - $ref: '#/components/schemas/ImportMapping' - type: 'null' job: oneOf: - $ref: '#/components/schemas/ImportJob' - type: 'null' ImportFilePreview: type: object properties: id: type: string format: uuid original_name: type: string headers: type: array items: type: string row_count: type: integer sample_rows: type: array description: Up to `rows` (max 100) data rows, each keyed by header. items: type: object additionalProperties: type: - string - 'null' ImportScanValuesRequest: type: object required: - entity_type - column_mappings properties: entity_type: type: string description: Field registry entity, e.g. Lead, Contact, Company, Deal. column_mappings: type: object description: Map of file header to CRM field key (null or empty to ignore the column). additionalProperties: type: - string - 'null' ImportScanValues: type: object description: Only mapped select, boolean and date fields appear; all four maps are empty when none are mapped. properties: select: type: object description: Field key to the sorted distinct values found; recognised values are folded to the choice's casing. additionalProperties: type: array items: type: string boolean: type: object additionalProperties: type: object properties: distinct: type: array items: type: string needs_resolution: type: boolean description: True when a value is not one of true/false/yes/no/1/0 (any case). date: type: object additionalProperties: type: object properties: detected_format: type: - string - 'null' description: Human label such as DD/MM/YYYY; null when no single format fits. fmt_token: type: - string - 'null' description: strptime token, e.g. %d/%m/%Y. ambiguous: type: boolean sample: type: array description: Up to 5 distinct raw values. items: type: string choices: type: object description: Field key to the sorted values each select field accepts. additionalProperties: type: array items: type: string ImportAutoDetect: type: object properties: suggested_mappings: type: object description: Map of every file header to the matched CRM field key, or null. additionalProperties: type: - string - 'null' available_fields: type: array items: type: object properties: key: type: string description: The standard field's key, or `__cf__` for a custom field. label: type: string type: type: string description: The field's data type. enum: - text - number - date - select - boolean - email - url required: type: boolean is_custom: type: boolean is_member: type: boolean description: True for fields that take an organization member's email. choices: type: array description: Select fields with choices only. items: type: string empty_columns: type: array description: Headers with no non-empty value anywhere in the file (empty if the file could not be read). items: type: string ImportMapping: type: object properties: id: type: string format: uuid readOnly: true name: type: string maxLength: 255 entity_type: type: string enum: - Lead - Contact - Company - Deal column_mappings: type: object description: Map of file header to CRM field key (null to ignore). additionalProperties: type: - string - 'null' field_defaults: type: - object - 'null' description: Map of field key to a constant applied when the column is absent or blank. Validated per field type. additionalProperties: true field_policies: type: - object - 'null' description: Map of field key to a per-field policy. additionalProperties: type: string enum: - leave_empty - skip_row auto_created: type: boolean description: True for single-use mappings created by the wizard. created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true ImportMappingWrite: type: object required: - name - entity_type properties: name: type: string maxLength: 255 entity_type: type: string enum: - Lead - Contact - Company - Deal column_mappings: type: object description: Map of file header to CRM field key (null to ignore). Defaults to {}. additionalProperties: type: - string - 'null' field_defaults: type: - object - 'null' description: Field key to constant. Keys must be fields of entity_type; select values must be a choice, number/date values must parse, member fields must be an active member's email. additionalProperties: true field_policies: type: - object - 'null' description: Field key to policy; leave_empty is refused on required fields. additionalProperties: type: string enum: - leave_empty - skip_row auto_created: type: boolean default: false ImportJob: type: object properties: id: type: string format: uuid status: type: string enum: - pending - processing - paused - done - failed file_id: type: string format: uuid file_name: type: string entity_type: type: - string - 'null' description: The mapping's entity type; null when the mapping was deleted. mapping_id: type: - string - 'null' format: uuid total_rows: type: integer success_rows: type: integer skipped_rows: type: integer last_committed_row: type: integer progress_rows: type: integer error_message: type: string created_at: type: string format: date-time started_at: type: - string - 'null' format: date-time completed_at: type: - string - 'null' format: date-time ImportJobCreate: type: object required: - file_id - mapping_id properties: file_id: type: string format: uuid mapping_id: type: string format: uuid value_resolutions: type: object description: 'Field key to a map of raw file value to the value to store, e.g. {"source": {"web form": "web_form"}}.' additionalProperties: type: object additionalProperties: type: string default: {} ImportJobRows: type: object description: Page-numbered (not cursor) list of one import's rows and their outcome. properties: count: type: integer description: Rows matching `outcome`, before paging. page: type: integer page_size: type: integer summary: type: object description: Counts over all rows of the job's window, regardless of `outcome`. properties: added: type: integer skipped: type: integer pending: type: integer results: type: array items: type: object properties: row: type: integer description: File-relative row number (header is row 1). outcome: type: string enum: - added - skipped - pending reason: type: - string - 'null' description: Skip reason; null unless skipped. ReportColumn: type: object required: - field - label properties: field: type: string description: Saved-view column key, e.g. lead__status or cf__lead__budget. label: type: string visible: type: boolean order: type: integer ReportFilterCondition: type: object required: - field - op properties: field: type: string description: Saved-view filter key, e.g. lead__status or cf__lead__budget. op: type: string enum: - eq - neq - contains - gt - lt - gte - lte - in - not_in - is_null - is_not_null value: description: Any JSON value; a list for in/not_in; omitted for is_null/is_not_null. ReportFilterGroup: type: object required: - conditions properties: op: type: string description: AND, OR or NOT (case-insensitive; defaults to AND). conditions: type: array items: oneOf: - $ref: '#/components/schemas/ReportFilterCondition' - $ref: '#/components/schemas/ReportFilterGroup' ReportFilters: description: A list of conditions (all must match) or a nested AND/OR/NOT group. oneOf: - type: array items: oneOf: - $ref: '#/components/schemas/ReportFilterCondition' - $ref: '#/components/schemas/ReportFilterGroup' - $ref: '#/components/schemas/ReportFilterGroup' ScheduledReportLog: type: object properties: id: type: string format: uuid description: The run's public id. period_label: type: string triggered_by: type: string enum: - schedule - manual status: type: string enum: - sent - partial - failed - empty - downloaded recipient_count: type: integer row_count: type: integer error: type: string created_at: type: string format: date-time ScheduledReport: type: object properties: public_id: type: string format: uuid readOnly: true name: type: string maxLength: 255 is_active: type: boolean columns: type: array items: $ref: '#/components/schemas/ReportColumn' filters: $ref: '#/components/schemas/ReportFilters' cadence: type: string enum: - daily - weekly - monthly - manual window: type: string enum: - 24h - 7d - 30d - mtd - all send_hour: type: integer minimum: 0 maximum: 23 description: Hour on the organization's local clock. recipient_type: type: string enum: - org - admins - specific_users specific_users: type: array readOnly: true items: type: object properties: id: type: string format: uuid email: type: string display_name: type: string last_run_at: type: - string - 'null' format: date-time readOnly: true last_log: readOnly: true oneOf: - $ref: '#/components/schemas/ScheduledReportLog' - type: 'null' created_at: type: string format: date-time readOnly: true updated_at: type: string format: date-time readOnly: true ScheduledReportWrite: type: object properties: name: type: string maxLength: 255 is_active: type: boolean default: true columns: type: array default: [] items: $ref: '#/components/schemas/ReportColumn' filters: $ref: '#/components/schemas/ReportFilters' cadence: type: string enum: - daily - weekly - monthly - manual window: type: string enum: - 24h - 7d - 30d - mtd - all default: 7d send_hour: type: integer minimum: 0 maximum: 23 default: 8 recipient_type: type: string enum: - org - admins - specific_users default: admins specific_user_ids: type: array description: User public ids; required (non-empty) when recipient_type is specific_users. Non-members are dropped silently. items: type: string format: uuid ReportRunRequest: type: object properties: delivery: type: string enum: - download - admins - org - specific_users description: Omit to mail the report's stored recipients. user_ids: type: array description: Member public ids; required when delivery is specific_users. items: type: string format: uuid ReportRunQueued: type: object description: The run was queued for mailing. properties: status: type: string enum: - queued detail: type: string ReportDownloadQueued: type: object description: 'Answered for `delivery=download` when the report is over the row limit (currently 10,000 rows): the file is built in the background. Poll the download until it is ready.' properties: status: type: string enum: - pending - ready - failed row_count: type: integer download_id: type: string format: uuid url: type: - string - 'null' description: Relative link with token; null until ready. detail: type: string ReportDownloadStatus: type: object properties: status: type: string enum: - pending - ready - failed row_count: type: integer error: type: string expires_at: type: string format: date-time url: type: - string - 'null' description: /api/v1/reports/downloads/{id}/file/?token=... when ready, else null. ScheduledReportHealth: type: object properties: active: type: integer description: Active reports in the organization. failed_7d: type: integer partial_7d: type: integer last_failure: description: Latest failed or partial run in the last 7 days, or null. oneOf: - type: 'null' - type: object properties: report_id: type: string format: uuid report_name: type: string status: type: string enum: - failed - partial error: type: string at: type: string format: date-time WebhookEndpoint: type: object description: 'An outbound webhook endpoint: a URL the CRM''s events are sent to.' properties: id: type: string format: uuid label: type: string url: type: string description: The full URL for owners and admins. Members and viewers get only the origin, for example "https://hooks.example.com/…", or "…" when the URL has no scheme or host. scope: type: string enum: - org - vivre description: '`vivre` for the CRM''s endpoints, the only ones an API key reaches.' is_active: type: boolean circuit_state: type: string enum: - closed - open - half_open description: 'Delivery health, set by the server: `closed` delivers normally, `open` holds deliveries after repeated failures, and `half_open` is trying the endpoint again.' created_at: type: string format: date-time updated_at: type: string format: date-time required: - id - label - url - scope - is_active - circuit_state - created_at - updated_at WebhookEndpointCreated: description: The new endpoint, with its signing secret. The only response that returns the secret besides rotate-secret. allOf: - $ref: '#/components/schemas/WebhookEndpoint' - type: object properties: secret: type: string description: 64 hex characters. required: - secret WebhookEndpointCreateRequest: type: object properties: url: type: string format: uri description: Must be https:// and resolve only to public internet addresses. label: type: string required: - url - label WebhookEndpointUpdateRequest: type: object description: Only `label`, `url` and `is_active` are written. Sending another of the endpoint's fields (for example `secret`, `scope`, `billing_paused`, `deleted_at` or `circuit_state`) is a 400; other keys are ignored. properties: label: type: string url: type: string format: uri description: Must be https:// unless it equals the saved URL. is_active: type: boolean description: true is refused (400) while the endpoint is billing-paused. WebhookDeliveryAttempt: type: object description: One try of a delivery, in its `response_log`. properties: attempt: type: integer status_code: type: - integer - 'null' description: null when no HTTP response was received, and on the manual-retry marker entry. response_body: type: string description: 'The first 500 characters of the receiver''s reply. When there was no reply it is a short note of why: a timeout, a connection error, an address that is not allowed, or an unexpected error; on a manual retry, who asked for it. Left out for members and viewers.' attempted_at: type: string format: date-time duration_ms: type: integer WebhookDelivery: type: object description: One event sent, or to be sent, to an endpoint. properties: id: type: string format: uuid event_type: type: string status: type: string enum: - pending - processing - success - failed - dead - cancelled description: '`pending` (queued, or held while the endpoint is failing), `processing` (being sent), `success`, `failed` (will be tried again), `dead` (no more tries) or `cancelled`.' attempt_count: type: integer created_at: type: string format: date-time resolved_at: type: - string - 'null' format: date-time next_attempt_at: type: - string - 'null' format: date-time last_attempted_at: type: - string - 'null' format: date-time response_log: type: array items: $ref: '#/components/schemas/WebhookDeliveryAttempt' payload: type: object additionalProperties: true description: 'Owners and admins only. The body that was sent, as it was at sending: the event envelope `{id, type, occurred_at, organisation_id, data, previous?}`. Free-form.' request_headers: type: object additionalProperties: type: string description: 'Owners and admins only. The headers each try sends, except `X-Vivre-Signature`, which is not kept: Content-Type, X-Vivre-Event, X-Vivre-Version and X-Vivre-Delivery.' required: - id - event_type - status - attempt_count - created_at - resolved_at - next_attempt_at - last_attempted_at - response_log WebhookSubscription: type: object properties: id: type: string format: uuid event_type: type: string created_at: type: string format: date-time required: - id - event_type - created_at WebhookSubscriptionCreated: type: object properties: id: type: string format: uuid event_type: type: string required: - id - event_type WebhookSubscriptionRequest: type: object properties: event_type: type: string description: Must be one of the events in `GET /api/v1/webhooks/vivre/events/`, for example `lead.created.v1`. required: - event_type WebhookEventCatalog: type: object properties: events: type: array items: type: string description: The event type names an endpoint may subscribe to, for example `lead.created.v1`. required: - events WebhookTestResult: type: object properties: status_code: type: integer description: The receiver's HTTP status. Any status, 2xx or not, is a 200 here. body: type: string description: First 500 characters of the receiver's reply. required: - status_code - body WebhookSecret: type: object properties: secret: type: string description: The new signing secret, 64 hex characters. The previous one stops working at once. required: - secret WebhookDiscoveredField: type: object description: 'One field a mapping can use: the standard fields, then the organization''s custom fields.' properties: key: type: string description: The standard field's key, or for a custom field `cf_`, `cf_lead_` or `cf_contact_`. label: type: string type: type: string description: 'Standard fields: string, email, choice, integer, uuid, date, decimal, or select when an attribution field has values set by the organization. Custom fields: the definition''s field_type.' entity_type: type: string description: Lead, Contact, Deal or Task. group: type: string description: What a mapper lists the field under, that is the entity type, "Contact" for a lead token's contact fields, or "Custom lead" / "Custom contact" / "Custom deal" / "Custom task". required: type: boolean options: type: array items: type: string description: For choice/select fields only. Lead status and attribution options are the organization's own lists. note: type: string mapper_hidden: type: boolean description: Present (true) on fields that are not mapping targets (contact_id). is_member: type: boolean description: Present (true) when the value is an organization member's UUID (assigned_to, assignee). is_custom: type: boolean description: Present (true) on custom fields only. legacy_key: type: - string - 'null' description: Custom fields only. The old name-keyed form of key. required: - key - label - type - entity_type - group - required WebhookFieldDiscovery: type: object properties: entity: type: string enum: - lead - contact - deal - task fields: type: array items: $ref: '#/components/schemas/WebhookDiscoveredField' description: Standard fields, then active custom fields. A lead lists both Lead and Contact custom fields. required: - entity - fields InboundFieldMappingEntry: description: 'How one CRM field is filled from a payload. A bare string is the older form, meaning `{source: }`. A formula wins over `source`.' oneOf: - type: string description: The payload key (legacy form). - type: object properties: source: type: - string - 'null' description: Payload key, flattened with "__" for nesting; matched case-insensitively. default: type: - string - number - boolean - 'null' description: Used as given when the source/formula yields nothing. Not validated. formula: type: - string - 'null' description: A formula over the payload's fields. An invalid formula is a 400. value_map: type: - object - 'null' additionalProperties: type: string description: Payload value -> CRM option label. String keys and values only. InboundFieldMapping: type: object description: Keyed by CRM field key (standard key, or a custom field key such as cf_lead_). additionalProperties: $ref: '#/components/schemas/InboundFieldMappingEntry' InboundToken: type: object description: 'An inbound webhook token: the address a form or tool posts to, and how its payloads become leads or contacts.' properties: id: type: string format: uuid description: The token's token_id. label: type: string is_active: type: boolean status: type: string enum: - active - paused - inactive description: '`active`, `paused` or `inactive`.' state: type: string enum: - active - paused - 'off' description: 'What the token does now, from `is_active` and `status`: `active` processes payloads, `paused` holds them, and `off` refuses them.' billing_paused: type: boolean allowed_ip_ranges: type: array items: type: string description: CIDR ranges; empty accepts every address. scope: type: string enum: - org - vivre source_label: type: string description: The record type it makes (lead or contact), or empty when not set. field_mapping: $ref: '#/components/schemas/InboundFieldMapping' mapping_confirmed: type: boolean _ignored: type: array items: type: string description: Payload keys an admin chose to discard (the stored ignored_fields). created_at: type: - string - 'null' format: date-time signing_enabled: type: boolean description: Whether the token has a signing secret, i.e. requires a signature. token: type: string description: The secret part of the inbound URL `/webhooks/vivre/{org_id}/{token}/`. Left out for members and viewers on reads, and always for API keys. secret: type: string description: The signing secret. Present only on create and rotate-secret, and only when the token has one. required: - id - label - is_active - status - state - billing_paused - allowed_ip_ranges - scope - source_label - field_mapping - mapping_confirmed - _ignored - created_at - signing_enabled InboundTokenCreateRequest: type: object description: No field is required. Unknown keys are ignored. properties: label: type: string default: '' source_label: type: string enum: - lead - contact - '' default: '' description: 'The record type the token makes: `lead` or `contact`. Any other non-empty value is a 400.' status: type: string enum: - active - paused - inactive default: active description: When sent, sets is_active too (inactive -> false). Wins over is_active. is_active: type: boolean default: true description: Used only when status is not sent; sets status to active or inactive. allowed_ip_ranges: type: array items: type: string default: [] description: CIDR ranges; an invalid one is a 400. secret: type: string minLength: 16 description: Caller-chosen signing secret. When absent, one is generated unless require_signature is false. require_signature: type: - boolean - string - integer default: true description: false (also "false", "False", 0, "0") creates the token with no secret, so payloads are not signature-checked. Ignored when secret is sent. InboundTokenUpdateRequest: type: object description: Only these keys are written. Sending token, secret, token_id, scope, field_mapping or mapping_confirmed is a 400; other keys are ignored. properties: label: type: string status: type: string enum: - active - paused - inactive description: Sets is_active too. Wins over is_active. is_active: type: boolean description: Sets status to active or inactive when status is not sent. allowed_ip_ranges: type: array items: type: string description: CIDR ranges; an invalid one is a 400. source_label: type: string enum: - lead - contact - '' InboundMappingRequest: type: object properties: field_mapping: $ref: '#/components/schemas/InboundFieldMapping' source_label: type: string enum: - lead - contact description: When sent, name-keyed custom field keys are upgraded to id keys, and the mapping must cover every mandatory field with a source, formula or non-blank default. When absent the mandatory check is skipped. _ignored: type: array items: type: string description: Payload keys to discard. Replaces the stored list; absent clears it. InboundMappingResult: type: object properties: mapping_confirmed: type: boolean enum: - true warnings: type: array items: type: string description: Present when a field has both formula and source. upgraded_keys: type: object additionalProperties: type: string description: 'Present when custom field keys were rewritten: {old key: new key}. What was stored is not what was sent.' required: - mapping_confirmed InboundSample: type: object description: The latest payload a token received, for the mapper. Under "Assigned only" lead visibility, members and viewers see every value in raw_payload, detected_fields and all_fields as "[hidden]" (keys and shape kept). properties: token_id: type: string format: uuid raw_payload: type: object additionalProperties: true description: The latest payload as received. Free-form. detected_fields: type: object additionalProperties: true description: 'The latest payload flattened, {"address__city": "Mumbai"}. Passed through as stored.' all_fields: type: object additionalProperties: true description: Every flattened key the last 50 payloads carried, with the newest value as the example. suggested_mapping: type: object additionalProperties: type: string description: '`{payload key: CRM field}` for payload keys whose name is a known alias of a CRM field.' source_headers: type: object additionalProperties: type: string description: Request headers of the latest payload, with Authorization and Cookie removed. For members, viewers and API keys, headers naming a signature, secret, token, auth, cookie or key are removed as well. captured_at: type: string format: date-time replaced_count: type: integer new_unknown_fields: type: array items: type: string description: Payload keys that are neither mapped nor ignored. required: - token_id - raw_payload - detected_fields - all_fields - suggested_mapping - source_headers - captured_at - replaced_count - new_unknown_fields InboundLogStatus: type: string enum: - success - partial - failed - held - skipped - rejected - processing - superseded description: '`success` (record made, all fields mapped), `partial` (record made, some optional fields missed), `failed` (can be tried again), `held` (waiting for the token''s mapping), `skipped` (nothing to make), `rejected` (a required field was missing), `processing` (a try is running or due) or `superseded` (the same payload was already processed).' InboundLogRow: type: object description: One received payload. properties: id: type: string format: uuid status: $ref: '#/components/schemas/InboundLogStatus' entity_type: type: string description: lead, contact, or empty. entity_id: type: - string - 'null' description: The record it created, when it did. mapping_result: type: object additionalProperties: true description: '{CRM field: value} that was mapped. Free-form; values read "[hidden]" for members and viewers under "Assigned only".' mapping_misses: type: array items: type: string description: Field keys with no value, or sentences naming a value that was not saved. received_at: type: string format: date-time processed_at: type: - string - 'null' format: date-time attempt_count: type: integer superseded_by: type: - string - 'null' format: uuid repeat_of: type: - string - 'null' format: uuid description: 'The payload this one repeated: same token, same mapped values, within 24 hours.' miss_labels: type: object additionalProperties: type: string description: '{field key: display name} for keys named in mapping_misses.' reason: type: - string - 'null' description: The last try's error. Always null for members and viewers. required: - id - status - entity_type - entity_id - mapping_result - mapping_misses - received_at - processed_at - attempt_count - superseded_by - miss_labels - reason InboundLogAttempt: type: object description: One try at processing a payload. properties: number: type: integer trigger: type: string enum: - received - retry - replay description: 'What started the try: `received` (the payload arrived), `retry` (an automatic retry) or `replay`.' status: $ref: '#/components/schemas/InboundLogStatus' started_at: type: string format: date-time finished_at: type: - string - 'null' format: date-time error: type: string description: Owners and admins only; left out for everyone else. mapping_misses: type: array items: type: string entity_type: type: string entity_id: type: - string - 'null' requested_by_name: type: - string - 'null' description: Who asked for a replay (full name, else email, else username). replay_batch: type: - string - 'null' format: uuid required: - number - trigger - status - started_at - finished_at - mapping_misses - entity_type - entity_id - requested_by_name - replay_batch InboundLogDetail: type: object description: One payload with every try. properties: id: type: string format: uuid status: $ref: '#/components/schemas/InboundLogStatus' entity_type: type: string entity_id: type: - string - 'null' raw_payload: type: object additionalProperties: true description: The payload as received. Free-form; values read "[hidden]" for members and viewers under "Assigned only". mapping_result: type: object additionalProperties: true description: Free-form; hidden as raw_payload is. mapping_misses: type: array items: type: string received_at: type: string format: date-time processed_at: type: - string - 'null' format: date-time superseded_by: type: - string - 'null' format: uuid repeat_of: type: - string - 'null' format: uuid description: 'The payload this one repeated: same token, same mapped values, within 24 hours.' attempts: type: array items: $ref: '#/components/schemas/InboundLogAttempt' miss_labels: type: object additionalProperties: type: string required: - id - status - entity_type - entity_id - raw_payload - mapping_result - mapping_misses - received_at - processed_at - superseded_by - attempts - miss_labels InboundReplayStarted: type: object properties: replayed: type: integer description: How many payloads were claimed and queued. batch_id: type: string format: uuid description: Poll GET .../replay/{batch_id}/ for progress. required: - replayed - batch_id InboundReplayProgress: type: object description: Where a replay has got to. Counts are of the batch's payloads by their current status. properties: batch_id: type: string format: uuid total: type: integer processing: type: integer success: type: integer partial: type: integer failed: type: integer held: type: integer skipped: type: integer rejected: type: integer finished: type: boolean outcome: type: - string - 'null' description: Once finished, a summary such as "2 succeeded, 1 failed" or "nothing processed"; null before. finished_at: type: - string - 'null' format: date-time created_at: type: string format: date-time required: - batch_id - total - processing - success - partial - failed - held - skipped - rejected - finished - outcome - finished_at - created_at InboundTokenStats: type: object description: Payload counts by status for one token; every status present, at 0 when none. properties: success: type: integer partial: type: integer failed: type: integer held: type: integer skipped: type: integer rejected: type: integer processing: type: integer superseded: type: integer total: type: integer repeats: type: integer description: How many payloads were repeats (created and flagged), counted within the statuses above. required: - success - partial - failed - held - skipped - rejected - processing - superseded - total BulkDeleteResult: type: object description: Best-effort bulk delete. Each id is either deleted or listed in failed with a reason. properties: deleted: type: array description: The ids that were deleted, as strings, in request order (duplicates removed). items: type: string format: uuid deleted_count: type: integer failed: type: array description: Ids not deleted. An id that is not a UUID, is in another organization, is already deleted or is outside the caller's visibility is reported as "Not found.". items: type: object properties: id: description: The id exactly as sent. reason: type: string failed_count: type: integer ContactBulkDeleteRequest: type: object required: - ids properties: ids: type: array minItems: 1 maxItems: 1000 description: Contact public ids. A value that is not a UUID is not rejected; it is reported in failed. items: type: string format: uuid LeadBulkDeleteRequest: type: object description: Send ids; lead_ids is the older key and is read only when ids is absent. anyOf: - required: - ids - required: - lead_ids properties: ids: type: array minItems: 1 maxItems: 1000 description: Lead public ids. A value that is not a UUID is reported in failed. items: type: string format: uuid lead_ids: type: array minItems: 1 maxItems: 1000 description: Older name for ids. items: type: string format: uuid CompanyBulkDeleteRequest: type: object description: Send ids; company_ids is the older key and is read only when ids is absent. anyOf: - required: - ids - required: - company_ids properties: ids: type: array minItems: 1 maxItems: 1000 description: Company public ids. A value that is not a UUID is reported in failed. items: type: string format: uuid company_ids: type: array minItems: 1 maxItems: 1000 description: Older name for ids. items: type: string format: uuid ContactDeleteImpactRequest: type: object required: - ids properties: ids: type: array minItems: 1 maxItems: 1000 description: Contact public ids. Values that are not UUIDs or not found are ignored. items: type: string format: uuid ContactDeleteImpact: type: object properties: contacts: type: integer description: How many of the ids name a contact the caller can see. leads: type: integer description: Live leads of those contacts. deals: type: integer description: Live deals of those contacts. BulkTagRequest: type: object required: - entity_ids - tag_id properties: entity_ids: type: array minItems: 1 maxItems: 1000 description: Public ids of the records. All must be live records of the organization, else 400. items: type: string format: uuid tag_id: type: string format: uuid description: The tag's public id. BulkTagResult: type: object properties: created_count: type: integer description: Assignments added (records that already had the tag are not counted). entity_ids: type: array description: Public ids of the records acted on, leaving out leads and deals the caller cannot see. items: type: string format: uuid tag_id: type: string format: uuid BulkUntagResult: type: object properties: removed_count: type: integer description: Tag assignments deleted. entity_ids: type: array description: Public ids of the records acted on, leaving out leads and deals the caller cannot see. items: type: string format: uuid tag_id: type: string format: uuid TagAssignRequest: type: object required: - tag_public_id properties: tag_public_id: type: string format: uuid description: A tag of the organization not already on this record (400 otherwise). ContactBulkMergeRequest: type: object required: - primary_contact_id - duplicate_contact_ids properties: primary_contact_id: type: string format: uuid duplicate_contact_ids: type: array minItems: 1 maxItems: 1000 description: Must not contain the primary. All must be live contacts of the organization. items: type: string format: uuid fields: type: object description: 'Values to set on the primary contact. Only these keys are accepted (400 otherwise). `opted_out_channels` must be an object and `company_public_id` a company of the organization; other values are set as given. `email`, `phone` and `phone_country_code` never replace the primary''s own: they fill an empty field, or else are kept as its secondary.' properties: first_name: type: string last_name: type: string job_title: type: string email: type: - string - 'null' email_secondary: type: - string - 'null' phone_country_code: type: string phone: type: - string - 'null' phone_secondary_country_code: type: string phone_secondary: type: - string - 'null' whatsapp_country_code: type: string whatsapp_number: type: - string - 'null' company_public_id: type: - string - 'null' format: uuid description: null clears the primary's company. opted_out_channels: type: object additionalProperties: true description: Free-form map of channel slug to opt-out flag. Replaces the merged map of all contacts' opt-outs when sent. additionalProperties: false LeadBulkMergeRequest: type: object required: - primary_lead_id - duplicate_lead_ids properties: primary_lead_id: type: string format: uuid description: The lead to keep. duplicate_lead_ids: type: array minItems: 1 maxItems: 1000 description: Must not contain the kept lead. All must be live leads of the same contact that the caller can see. items: type: string format: uuid fields: type: object description: Values to keep, checked as an edit of the kept lead is (400 with the lead's own errors). Only these keys are accepted. properties: source: type: string medium: type: string platform: type: string campaign: type: string channel: type: string priority: type: string lead_date: type: string format: date score: type: integer minimum: 0 maximum: 100 status: type: string assigned_to_id: type: - string - 'null' description: A member's public id, or null for no owner. additionalProperties: false LeadBulkMergeResult: type: object properties: primary_lead_id: type: string format: uuid merged_count: type: integer description: Duplicates merged in and soft-deleted. lead: $ref: '#/components/schemas/Lead' ContactBulkMergeResult: type: object properties: primary_contact_id: type: string format: uuid merged_count: type: integer description: Duplicates merged in and soft-deleted. contact: $ref: '#/components/schemas/Contact' LeadBulkAssignRequest: type: object required: - lead_ids - assigned_to_id properties: lead_ids: type: array minItems: 1 maxItems: 1000 description: All must be live leads of the organization, else 400. items: type: string format: uuid assigned_to_id: type: string format: uuid description: Public id of a member of the organization. Null is not accepted. LeadBulkAssignResult: type: object properties: updated_count: type: integer lead_ids: type: array description: Public ids of the leads reassigned (leads a non-admin cannot see under "Assigned only" visibility are left out). items: type: string format: uuid assigned_to_id: type: string format: uuid description: The new owner's public id, as sent. LeadBulkStatusRequest: type: object required: - lead_ids - status properties: lead_ids: type: array minItems: 1 maxItems: 1000 description: All must be live leads of the organization, else 400. items: type: string format: uuid status: type: string maxLength: 255 description: One of the organization's lead statuses (400 otherwise). LeadBulkStatusResult: type: object properties: updated_count: type: integer lead_ids: type: array description: Public ids of the leads updated. items: type: string format: uuid status: type: string skipped_count: type: integer description: Present only when some leads were skipped (not assigned to the caller under assigned_only). message: type: string description: Present only with skipped_count. DealBulkMoveStageRequest: type: object required: - deal_ids - stage_id properties: deal_ids: type: array minItems: 1 maxItems: 1000 description: All must be live deals of the organization in the stage's pipeline, else 400. items: type: string format: uuid stage_id: type: string format: uuid reason: type: string description: Written as the activity line on each deal; default "Deal stage moved to ". DealBulkMoveStageResult: type: object properties: updated_count: type: integer description: 'Deals moved. The target stage decides the status: Won, Lost or Abandoned closes them, and an open stage reopens closed ones.' skipped_count: type: integer description: Always 0; kept for older clients (closed deals used to be left where they were). deal_ids: type: array description: Public ids of the deals moved. items: type: string format: uuid stage_id: type: string format: uuid stage_name: type: string DealWonRequest: type: object properties: closed_at: type: string format: date description: Close date, not in the future (organization's date). Default today in the organization's time zone. DealLostRequest: type: object description: The body of `POST /deals/{id}/lost/` and `/abandoned/`. properties: reason: type: string description: Why it was lost or abandoned (stored as lost_reason). Default empty. closed_at: type: string format: date description: Close date, not in the future. Default today in the organization's time zone. DealParticipantRole: type: string enum: - Champion - Decision Maker - Influencer - Blocker - End User DealParticipant: type: object properties: id: type: string format: uuid contact_id: type: string description: The contact's integer primary key, rendered as a string. contact_public_id: type: string format: uuid contact_name: type: string role: $ref: '#/components/schemas/DealParticipantRole' created_at: type: string format: date-time DealParticipantCreate: type: object description: Name the contact by contact_id or, when contact_id is absent, contact_uuid. One of the two is required. The contact must not already be on the deal. required: - role properties: contact_uuid: type: string format: uuid description: Alternate key, read only when contact_id is not sent. role: type: string maxLength: 50 description: One of the participant roles (see /deals/participant-roles/), matched in any case. DealParticipantRoleOption: type: object properties: value: $ref: '#/components/schemas/DealParticipantRole' label: type: string DealCompanyLink: type: object description: A deal-company link made before deals stopped being linked to companies. properties: id: type: string format: uuid description: Its public id. company: type: object properties: id: type: string format: uuid name: type: string created_at: type: string format: date-time ContactSummary: type: object properties: id: type: string format: uuid first_name: type: string last_name: type: string full_name: type: string email: type: - string - 'null' phone: type: - string - 'null' phone_country_code: type: string job_title: type: string whatsapp_number: type: - string - 'null' whatsapp_country_code: type: string company_name: type: - string - 'null' company_id: type: - string - 'null' format: uuid description: The company's public id. PaginatedActivities: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/Activity' PaginatedContactSummaries: allOf: - $ref: '#/components/schemas/PaginatedEnvelope' - type: object properties: results: type: array items: $ref: '#/components/schemas/ContactSummary' ContactStats: type: object description: Counts over the contacts the list query matches (same query params as the list). properties: total: type: integer mine: type: integer description: Created by the caller. unassigned: type: integer description: No created_by. tagged: type: integer this_month: type: integer description: Created since the 1st of the organization's current month. with_company: type: integer with_email: type: integer LeadStats: type: object description: Counts over the leads the list query matches (same query params as the list). properties: total: type: integer avg_score: type: - number - 'null' description: Mean score rounded to 2 places; null when there are no leads. mine: type: integer description: Assigned to the caller. unassigned: type: integer by_status: type: object description: Count per status. Every status in the organization's list appears (0 included), plus any stored status outside it. additionalProperties: type: integer CompanyStats: type: object description: Counts over the companies the list query matches (same query params as the list). properties: total: type: integer mine: type: integer description: Owned by the caller. unassigned: type: integer description: No owner. tagged: type: integer this_month: type: integer description: Created since the 1st of the organization's current month. with_website: type: integer with_phone: type: integer thin_coverage: type: integer description: Companies with fewer than 2 live contacts. TaskStats: type: object description: Counts over the tasks the list query matches (same query params as the list). properties: total: type: integer mine: type: integer description: Assigned to the caller. open: type: integer description: Status pending or in_progress. pending: type: integer overdue: type: integer description: Due before today (organization's date) and still open. due_today: type: integer high_priority: type: integer description: Priority high or urgent. completed_7d: type: integer description: Completed in the last 7 days. TaskCompleteRequest: type: object properties: content: type: string description: 'Text of the "task completed" activity on the linked record. Default "Task completed: ". Used only when the task was not already done.' TaskBulkCompleteRequest: type: object required: - task_ids properties: task_ids: type: array minItems: 1 maxItems: 1000 description: Task public ids. Any value that is not a UUID is a 400. Tasks not found, not visible to the caller or not open are skipped. items: type: string format: uuid TaskBulkCompleteResult: type: object properties: completed_count: type: integer description: Open tasks (pending or in_progress) marked done. SlackRoute: type: object properties: id: type: string format: uuid name: type: string is_active: type: boolean crm_events: type: array items: type: string last_status: type: string last_sent_at: type: - string - 'null' format: date-time SlackEventType: type: object properties: key: type: string label: type: string group: type: string group_label: type: string MatchingIds: type: object description: Every record the list shows for the same query. required: - count - ids - limit properties: count: type: integer description: Every match, which may be more than `limit`. ids: type: array items: type: string format: uuid description: Public ids of the first `limit` matches, in the list's order. limit: type: integer description: 'The most ids answered: 10,000.' DealStats: type: object description: Over the deals the list query matches (same query params as the list). Money is one total per currency, as a decimal string, never summed across currencies. This month is the organization's month. properties: total: type: integer open: type: integer open_value: type: object description: Currency -> value of the open deals. additionalProperties: type: string won_this_month: type: integer description: Won, closed this month. won_value_this_month: type: object description: Currency -> value of those. additionalProperties: type: string closing_this_month: type: integer description: Open, expected to close this month. DealBulkAssignRequest: type: object required: - deal_ids - assigned_to_id properties: deal_ids: type: array minItems: 1 maxItems: 1000 description: All must be live deals of the organization, else 400. items: type: string format: uuid assigned_to_id: type: string format: uuid description: Public id of a member of the organization. Null is not accepted. DealBulkAssignResult: type: object properties: updated_count: type: integer deal_ids: type: array items: type: string format: uuid description: Public ids of the deals reassigned (deals a non-admin cannot see under "Assigned only" visibility are left out). assigned_to_id: type: string format: uuid description: The new owner's public id, as sent. DealBulkDeleteRequest: type: object required: - ids properties: ids: type: array minItems: 1 maxItems: 1000 description: Deal public ids. A value that is not a UUID is reported in failed. items: type: string format: uuid