Skip to documentation

Accounts

Manage the workspace people and Accounts that connect product engagement across calls, signals, and insights.

15 endpoints

GET

List people

GET /external/v1/people

List the workspace people directory across all Accounts, including unassigned people created from public email addresses. Each result includes its linked signal count.

Requirements

API scopes required:
accounts:read

Request

Parameters

NameTypeDescription
q stringSearch name, email, role, Account name, or Account domain.
limit numberMaximum results, from 1 to 100.
offset numberNumber of people to skip.

Responses

200
Success

Workspace people were retrieved.

Schema
PeoplePage

Example Request

GET
/external/v1/people
curl
curl -X GET 'https://zentrik.ai/api/external/v1/people?q=buyer' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

200 OK
json
{
  "items": [
    {
      "id": "person-uuid",
      "name": "Primary product contact",
      "email": "buyer@example.com",
      "role": "VP Product",
      "accountId": "account-uuid",
      "account": {
        "id": "account-uuid",
        "name": "Example",
        "domain": "example.com"
      },
      "signalCount": 4
    }
  ],
  "totalRecords": 1,
  "limit": 50,
  "offset": 0,
  "hasMore": false
}
POST

Create a person

POST /external/v1/people

Create a workspace person. accountId is optional, so public-email and not-yet-matched people can exist before Account assignment.

Requirements

API scopes required:
accounts:write

Request

Request body (application/json)

namestring
Required

Person display name.

emailstring

Email used for deterministic matching on later calls.

rolestring

Role or title.

accountIduuid | null

Account assignment, or null for unassigned.

Responses

201
Created

The person was created.

Schema
Person
409
Conflict

A person with the same workspace email already exists.

Example Request

POST
/external/v1/people
json
{
  "name": "Primary product contact",
  "email": "buyer@example.com",
  "role": "VP Product",
  "accountId": "account-uuid"
}
PATCH

Update or assign a person

PATCH /external/v1/people/:id

Update a person or assign an unassigned person to an Account. Existing signal history stays linked to the person.

Requirements

API scopes required:
accounts:write

Request

Parameters

NameTypeDescription
id *uuidThe person UUID.

Request body (application/json)

namestring

Updated display name.

emailstring

Updated email.

rolestring

Updated role or title.

accountIduuid | null

New Account assignment, or null to unassign.

Responses

200
Updated

The person was updated.

Schema
Person

Example Request

PATCH
/external/v1/people/:id
curl
curl -X PATCH https://zentrik.ai/api/external/v1/people/person-uuid \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"accountId":"account-uuid"}'
DELETE

Delete a person

DELETE /external/v1/people/:id

Delete a workspace person and its signal links. Signals and Accounts are not deleted.

Requirements

API scopes required:
accounts:write

Request

Parameters

NameTypeDescription
id *uuidThe person UUID.

Responses

200
Deleted

The person was deleted.

Example Request

DELETE
/external/v1/people/:id
curl
curl -X DELETE https://zentrik.ai/api/external/v1/people/person-uuid \
  -H 'Authorization: Bearer YOUR_API_KEY'
GET

List all accounts

GET /external/v1/accounts

List accounts in the current workspace. This is the main lookup endpoint for CRM automation before transcript ingestion.

Requirements

API scopes required:
accounts:read

Request

Parameters

NameTypeDescription
limit numberMaximum number of accounts to return.
offset numberNumber of accounts to skip.
q stringCase-insensitive search across name, domain, website, and externalId.
name stringExact account name match (case-insensitive).
domain stringExact domain or website match (case-insensitive).
externalId stringStable client-side identifier such as crm-example-account.

Responses

200
Success

Accounts were successfully retrieved.

Schema
Array<Account>

Example Request

GET
/external/v1/accounts
curl
curl -X GET 'https://zentrik.ai/api/external/v1/accounts?externalId=crm-example-account' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

200 OK
json
[
  {
    "id": "account-uuid",
    "name": "Example Account",
    "domain": "example.com",
    "website": "https://example.com",
    "lifecycleStage": "TRIAL",
    "externalId": "crm-example-account",
    "workspaceId": "workspace-uuid",
    "contactIds": [
      "contact-1"
    ],
    "insightIds": [
      "insight-1"
    ],
    "opportunityIds": [
      "opportunity-1"
    ],
    "ideaIds": [
      "idea-1"
    ],
    "createdAt": "2026-04-09T10:00:00Z",
    "updatedAt": "2026-04-09T10:00:00Z"
  }
]
GET

Find duplicate accounts

GET /external/v1/accounts/duplicate-candidates

Find likely duplicate Account groups in the workspace before a merge. Candidates are grouped by shared domain, normalized name, or legal name and ordered by confidence. This operation does not change data; a candidate is evidence for review, not an automatic merge decision.

Requirements

API scopes required:
accounts:read

Responses

200
Success

Likely duplicate Account groups were retrieved.

Schema
Array<AccountDuplicateCandidate>

Example Request

GET
/external/v1/accounts/duplicate-candidates
curl
curl -X GET https://zentrik.ai/api/external/v1/accounts/duplicate-candidates \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

200 OK
json
[
  {
    "score": 100,
    "reason": "domain",
    "accounts": [
      {
        "id": "account-uuid-1",
        "name": "Example",
        "domain": "example.com",
        "lifecycleStage": "ACTIVE"
      },
      {
        "id": "account-uuid-2",
        "name": "Example Inc.",
        "domain": "example.com",
        "lifecycleStage": "TRIAL"
      }
    ]
  }
]
GET

Get one account

GET /external/v1/accounts/:id

Retrieve one account from the current workspace.

Requirements

API scopes required:
accounts:read

Request

Parameters

NameTypeDescription
id *uuidThe backend account UUID.

Responses

200
Success

The account was successfully retrieved.

Schema
404
Not Found

No account found with the provided id.

Example Request

GET
/external/v1/accounts/:id
curl
curl -X GET https://zentrik.ai/api/external/v1/accounts/account-uuid \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

200 OK
json
{
  "id": "account-uuid",
  "name": "Example Account",
  "domain": "example.com",
  "website": "https://example.com",
  "lifecycleStage": "TRIAL",
  "externalId": "crm-example-account",
  "workspaceId": "workspace-uuid",
  "contactIds": [
    "contact-1"
  ],
  "insightIds": [
    "insight-1"
  ],
  "opportunityIds": [
    "opportunity-1"
  ],
  "ideaIds": [
    "idea-1"
  ],
  "createdAt": "2026-04-09T10:00:00Z",
  "updatedAt": "2026-04-09T10:00:00Z"
}
POST

Create an account

POST /external/v1/accounts

Create an account in the current workspace. CRM agents typically use `externalId` as the durable bridge between local records and Zentrik accounts. Manage contacts with the account contacts endpoints after the account exists.

Requirements

API scopes required:
accounts:write

Request

Request body (application/json)

namestring
Required

Account display name.

externalIdstring

Stable client-side identifier such as crm-example-account.

domainstring

Primary company domain.

websitestring

Canonical website URL.

industrystring

Industry or vertical label.

companySizestring

Company size bucket.

lifecycleStagestring

Canonical Zentrik lifecycle stage: LEAD, TRIAL, ACTIVE, CHURNED, or PARTNER.

notesstring

Supplemental operator or CRM notes.

Responses

201
Created

The account was successfully created.

Schema

Example Request

POST
/external/v1/accounts
json
{
  "name": "Example Account",
  "externalId": "crm-example-account",
  "domain": "example.com",
  "website": "https://example.com",
  "industry": "B2B software",
  "companySize": "11-50",
  "lifecycleStage": "TRIAL",
  "notes": "Primary contact evaluates roadmap fit."
}

Example Response

201 Created
json
{
  "id": "account-uuid",
  "name": "Example Account",
  "externalId": "crm-example-account",
  "domain": "example.com",
  "website": "https://example.com",
  "industry": "B2B software",
  "companySize": "11-50",
  "lifecycleStage": "TRIAL",
  "workspaceId": "workspace-uuid",
  "contactIds": [],
  "insightIds": [],
  "opportunityIds": [],
  "ideaIds": [],
  "createdAt": "2026-04-09T10:00:00Z",
  "updatedAt": "2026-04-09T10:00:00Z"
}
PATCH

Update an account

PATCH /external/v1/accounts/:id

Update an existing account in the current workspace. Contact arrays are not accepted here; use the dedicated contact endpoints for people and roles.

Requirements

API scopes required:
accounts:write

Request

Parameters

NameTypeDescription
id *uuidThe backend account UUID.

Request body (application/json)

namestring

Updated display name.

externalIdstring

Updated stable client-side identifier.

domainstring

Updated primary company domain.

websitestring

Updated canonical website URL.

industrystring

Updated industry or vertical label.

companySizestring

Updated company size bucket.

lifecycleStagestring

Updated canonical Zentrik lifecycle stage.

notesstring

Updated operator or CRM notes.

Responses

200
Updated

The account was successfully updated.

Schema

Example Request

PATCH
/external/v1/accounts/:id
curl
curl -X PATCH https://zentrik.ai/api/external/v1/accounts/account-uuid \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"lifecycleStage":"ACTIVE"}'
DELETE

Delete an account

DELETE /external/v1/accounts/:id

Delete an account from the current workspace.

Requirements

API scopes required:
accounts:delete

Request

Parameters

NameTypeDescription
id *uuidThe backend account UUID.

Responses

200
Deleted

The account was successfully deleted.

Example Request

DELETE
/external/v1/accounts/:id
curl
curl -X DELETE https://zentrik.ai/api/external/v1/accounts/account-uuid \
  -H 'Authorization: Bearer YOUR_API_KEY'
POST

Preview or merge duplicate accounts

POST /external/v1/accounts/:id/merge

Preview or execute a destructive duplicate Account merge. The path Account survives; source Accounts are folded into it and deleted. Start with dryRun set to true, review moved records and field choices, resolve every blocking conflict, then repeat the same request with dryRun set to false.

Requirements

API scopes required:
accounts:delete

Request

Parameters

NameTypeDescription
id *uuidThe Account UUID that must survive the merge.

Request body (application/json)

sourceAccountIdsuuid[]
Required

One or more duplicate Account UUIDs to fold into the survivor and delete.

dryRunboolean

Set true to return the merge plan without writing. Defaults to false.

fieldOverridesobject

Explicit survivor field values to use when duplicate records disagree.

Responses

200
Success

A dry run returns the merge plan. An executed merge returns the surviving Account.

Schema
AccountMergePreview | Account
400
Invalid request

The source list is empty, includes the survivor, or contains an invalid Account reference.

404
Not found

The survivor or a source Account is outside the API-key workspace or does not exist.

409
Blocking conflict

A source identity or integration binding must be resolved before the Accounts can be merged.

Example Request

POST
/external/v1/accounts/:id/merge
curl
curl -X POST https://zentrik.ai/api/external/v1/accounts/account-uuid-1/merge \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"sourceAccountIds":["account-uuid-2"],"dryRun":true}'

Example Response

200 OK
json
{
  "survivorId": "account-uuid-1",
  "survivorName": "Example",
  "losers": [
    {
      "id": "account-uuid-2",
      "name": "Example Inc."
    }
  ],
  "moves": {
    "signals": 3,
    "insights": 2,
    "ideas": 0,
    "opportunities": 1,
    "contacts": 2
  },
  "totalMoves": 8,
  "fieldResolutions": [],
  "conflicts": [],
  "blocking": false
}
GET

List account contacts

GET /external/v1/accounts/:id/contacts

List contacts linked to an account in the current workspace. Use this before contact sync automation rather than relying on account `contactIds` alone.

Requirements

API scopes required:
accounts:read

Request

Parameters

NameTypeDescription
id *uuidThe backend account UUID.

Responses

200
Success

Contacts were successfully retrieved.

Schema
Array<Contact>
404
Not Found

No account found with the provided id in the current workspace.

Example Request

GET
/external/v1/accounts/:id/contacts
curl
curl -X GET https://zentrik.ai/api/external/v1/accounts/account-uuid/contacts \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

200 OK
json
[
  {
    "id": "contact-uuid",
    "accountId": "account-uuid",
    "name": "Primary product contact",
    "role": "VP Product",
    "email": "product-contact@example.com",
    "phone": null,
    "notes": "Primary product evaluator and champion.",
    "isPrimary": true,
    "createdAt": "2026-04-09T10:00:00Z",
    "updatedAt": "2026-04-09T10:00:00Z"
  }
]
POST

Create an account contact

POST /external/v1/accounts/:id/contacts

Create one contact on an account. This is the preferred way to add contacts; do not patch the account `contacts` array for incremental updates.

Requirements

API scopes required:
accounts:write

Request

Parameters

NameTypeDescription
id *uuidThe backend account UUID.

Request body (application/json)

namestring
Required

Contact display name.

rolestring

Role, title, or account-specific responsibility.

emailstring

Email address.

phonestring

Phone number.

notesstring

Operator notes such as influence, interests, and outreach guidance.

isPrimaryboolean

Whether this is the primary contact for the account.

Responses

201
Created

The contact was successfully created.

Schema
Contact
404
Not Found

No account found with the provided id in the current workspace.

Example Request

POST
/external/v1/accounts/:id/contacts
json
{
  "name": "Primary product contact",
  "role": "VP Product",
  "email": "product-contact@example.com",
  "notes": "Primary product evaluator and champion.",
  "isPrimary": true
}

Example Response

201 Created
json
{
  "id": "contact-uuid",
  "accountId": "account-uuid",
  "name": "Primary product contact",
  "role": "VP Product",
  "email": "product-contact@example.com",
  "notes": "Primary product evaluator and champion.",
  "isPrimary": true,
  "createdAt": "2026-04-09T10:00:00Z",
  "updatedAt": "2026-04-09T10:00:00Z"
}
PATCH

Update an account contact

PATCH /external/v1/accounts/:id/contacts/:contactId

Update one contact on an account. The contact must belong to the requested account in the current workspace.

Requirements

API scopes required:
accounts:write

Request

Parameters

NameTypeDescription
id *uuidThe backend account UUID.
contactId *uuidThe backend contact UUID.

Request body (application/json)

namestring

Updated contact display name.

rolestring

Updated role, title, or account-specific responsibility.

emailstring

Updated email address.

phonestring

Updated phone number.

notesstring

Updated operator notes.

isPrimaryboolean

Updated primary-contact flag.

Responses

200
Updated

The contact was successfully updated.

Schema
Contact
404
Not Found

No account/contact pair found in the current workspace.

Example Request

PATCH
/external/v1/accounts/:id/contacts/:contactId
curl
curl -X PATCH https://zentrik.ai/api/external/v1/accounts/account-uuid/contacts/contact-uuid \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"notes":"Strategic evaluator. Reach out for roadmap and pricing context."}'
DELETE

Delete an account contact

DELETE /external/v1/accounts/:id/contacts/:contactId

Remove one person from an Account without deleting the person or their engagement history.

Requirements

API scopes required:
accounts:write

Request

Parameters

NameTypeDescription
id *uuidThe backend account UUID.
contactId *uuidThe backend contact UUID.

Responses

200
Unassigned

The person is now unassigned and remains available in People.

404
Not Found

No account/contact pair found in the current workspace.

Example Request

DELETE
/external/v1/accounts/:id/contacts/:contactId
curl
curl -X DELETE https://zentrik.ai/api/external/v1/accounts/account-uuid/contacts/contact-uuid \
  -H 'Authorization: Bearer YOUR_API_KEY'