Skip to main content
PUT
/
crm
/
people
Assert a CRM person (upsert)
curl --request PUT \
  --url https://api.zeeg.me/v2/crm/people \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "firstName": "Jane",
  "lastName": "Doe",
  "salutation": "<string>",
  "emails": [
    "jane.doe@acme.com"
  ],
  "jobTitle": "<string>",
  "description": "<string>",
  "phoneNumber": "<string>",
  "primaryLocation": "<string>",
  "avatarUrl": "<string>",
  "companyId": "<string>",
  "socials": {
    "linkedin": "<string>",
    "twitter": "<string>",
    "facebook": "<string>",
    "instagram": "<string>"
  }
}
'
{
  "success": true,
  "status": 200,
  "person": {
    "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "firstName": "Jane",
    "lastName": "Doe",
    "salutation": "Ms",
    "emails": [
      "jane.doe@acme.com"
    ],
    "jobTitle": "Head of Product",
    "description": "Key decision-maker at Acme Corp.",
    "phoneNumber": "+4930123456789",
    "primaryLocation": "Berlin, Germany",
    "avatarUrl": null,
    "company": {
      "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
      "name": "<string>",
      "domain": "<string>"
    },
    "socials": {
      "linkedin": "https://linkedin.com/in/janedoe",
      "twitter": null,
      "facebook": null,
      "instagram": null
    },
    "customAttributes": {},
    "createdAt": "2025-01-15T09:00:00+00:00",
    "updatedAt": "2025-06-01T12:00:00+00:00"
  }
}

Documentation Index

Fetch the complete documentation index at: https://developer.zeeg.me/llms.txt

Use this file to discover all available pages before exploring further.

Creates or updates a CRM person record using a unique attribute to find an existing match.
  • If a person with the same value for matchingAttribute is found → it is updated and 200 is returned.
  • If no match is found → a new person is created and 201 is returned.

Matching attribute

The matchingAttribute query parameter specifies which field to use for the lookup. It can be any standard or custom attribute slug on the people object.
PUT /v2/crm/people?matchingAttribute=email
PUT /v2/crm/people?matchingAttribute=phone_number
PUT /v2/crm/people?matchingAttribute=my_custom_attribute

Email matching

When matchingAttribute is email or emails, the lookup checks both the primary email and all secondary email addresses, so a person is found regardless of which email slot holds the value.

Other attributes

All other standard attributes (e.g. phone_number) and custom attributes are matched using exact equality.

Use case

Assert is the recommended endpoint for bulk imports and sync jobs. Send your full person payload and let the API decide whether to create or update — no need to pre-check for duplicates.
{
  "firstName": "Jane",
  "lastName": "Doe",
  "emails": ["jane.doe@acme.com"],
  "jobTitle": "Head of Product",
  "primaryLocation": "Berlin, Germany",
  "socials": {
    "linkedin": "https://linkedin.com/in/janedoe"
  }
}

Authorizations

Authorization
string
header
required

Query Parameters

matchingAttribute
string
required

Attribute slug to use when searching for an existing person. Can be any standard or custom attribute slug. Use email (or emails) to match against the person's primary email and secondary emails. All other attributes are matched using an exact equality check.

Body

application/json
firstName
string | null

First name. Required if lastName is not provided.

Example:

"Jane"

lastName
string | null

Last name. Required if firstName is not provided.

Example:

"Doe"

salutation
string | null
emails
string<email>[] | null

List of email addresses. The first entry is the primary (matching) email.

Example:
["jane.doe@acme.com"]
jobTitle
string | null
description
string | null
phoneNumber
string | null
primaryLocation
string | null
avatarUrl
string | null
companyId
string | null
socials
object

Response

Updated — a person with the matching email was found and updated

success
boolean
Example:

true

status
integer
Example:

200

person
object

A CRM person record.

Last modified on May 7, 2026