Skip to content
Dashboard

Create or update a contact

POST/v2/contacts

Creates a new contact or updates an existing one.

If a contact with the given email or userId already exists, it will be updated. Otherwise, a new contact will be created.

At least one of email or userId must be provided for identification.

Request Body

FieldTypeRequiredDescription
emailstringOne of email/userIdContact email address
userIdstringOne of email/userIdExternal user ID from your system
namestringNoContact display name
profilePicturestringNoProfile picture URL
companiesarrayNoCompanies the contact belongs to
customFieldsobjectNoCustom field values
subscribedToChangelogbooleanNoWhether subscribed to changelog
localestringNoContact locale/language
phonestringNoContact phone number
rolesarrayNoRole IDs to assign
userHashstringNoHMAC hash for identity verification
createdAtstringNoWhen the contact was created (ISO 8601)

Company Object

Each company in the companies array can have:

  • id (required) - External company ID from your system
  • name (required) - Company name
  • monthlySpend - Monthly spend/revenue
  • customFields - Custom field values
  • industry - Industry
  • website - Company website URL
  • plan - Current plan/subscription
  • companySize - Number of employees
  • createdAt - When the company was created

Response

Returns the created or updated contact object.

  • 201 Created - A new contact was created
  • 200 OK - An existing contact was updated

Example Request

{
  "email": "john@example.com",
  "name": "John Doe",
  "userId": "usr_12345",
  "companies": [
    {
      "id": "company_123",
      "name": "Acme Inc",
      "monthlySpend": 500,
      "plan": "enterprise"
    }
  ],
  "customFields": {
    "plan": "pro",
    "signupSource": "website"
  },
  "subscribedToChangelog": true
}

Example Response

{
  "object": "contact",
  "id": "676f0f6765bdaa7d7d760f88",
  "email": "john@example.com",
  "name": "John Doe",
  "userId": "usr_12345",
  "type": "customer",
  "companies": [...],
  "customFields": {...},
  ...
}

Version Availability

This endpoint is only available in API version 2026-01-01.nova and newer.

Header ParametersExpand Collapse
"Featurebase-Version": optional "2026-01-01.nova" or "2025-12-12.clover"
One of the following:
"2026-01-01.nova"
"2025-12-12.clover"
Body ParametersJSONExpand Collapse
companies: optional array of object { id, name, companyHash, 7 more }

Companies the contact belongs to

id: string

External company ID from your system

minLength1
maxLength500
name: string

Company name

minLength1
maxLength500
companyHash: optional string

HMAC-SHA256 hash of company ID for identity verification

maxLength256
companySize: optional number

Number of employees in the company

minimum0
createdAt: optional string

When the company was created (ISO 8601)

customFields: optional object { industry, plan, priority }

Custom field values on the company. Values can be string, number, boolean, null, or array of primitives.

industry: optional string
plan: optional string
priority: optional string
industry: optional string

Industry the company operates in

maxLength500
monthlySpend: optional number

Monthly spend/revenue from this company

minimum0
plan: optional string

Current plan/subscription name

maxLength500
website: optional string

Company website URL

maxLength500
createdAt: optional string

When the contact was created in your system (ISO 8601)

customFields: optional object { accountType, plan, signupSource }

Custom field values on the contact. Values can be string, number, boolean, null, or array of primitives.

accountType: optional string
plan: optional string
signupSource: optional string
email: optional string

Contact email address. Used for identification if userId is not provided.

maxLength500
formatemail
locale: optional string

Contact locale/language preference

maxLength10
name: optional string

Contact display name

maxLength500
phone: optional string

Contact phone number

maxLength500
profilePicture: optional string

Profile picture URL

formaturi
roles: optional array of string

Array of role IDs to assign to the contact

subscribedToChangelog: optional boolean

Whether the contact is subscribed to changelog updates

userHash: optional string

HMAC-SHA256 hash of userId or email for identity verification

maxLength256
userId: optional string

External user ID from your system. Takes precedence over email for identification.

maxLength500

Create or update a contact

curl https://do.featurebase.app/v2/contacts \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $FEATUREBASE_API_KEY" \
    -d '{
          "createdAt": "2024-01-15T10:30:00Z",
          "email": "john@example.com",
          "locale": "en",
          "name": "John Doe",
          "phone": "+1234567890",
          "profilePicture": "https://example.com/avatar.png",
          "roles": [
            "role_vip",
            "role_beta"
          ],
          "subscribedToChangelog": true,
          "userHash": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
          "userId": "usr_12345"
        }'
{
  "id": "676f0f6765bdaa7d7d760f88",
  "name": "John Steezy",
  "object": "contact",
  "type": "customer",
  "commentsCreated": 0,
  "companies": [
    {
      "id": "507f1f77bcf86cd799439011",
      "companyId": "comp_12345",
      "companySize": 250,
      "createdAt": "2025-01-01T12:00:00.000Z",
      "industry": "Technology",
      "lastActivity": "2025-01-15T00:00:00.000Z",
      "linkedUsers": 15,
      "monthlySpend": 5000,
      "name": "Acme Inc",
      "object": "company",
      "plan": "enterprise",
      "updatedAt": "2025-01-10T15:30:00.000Z",
      "website": "https://acme.com",
      "customFields": {
        "location": "bar",
        "priority": "bar"
      }
    }
  ],
  "customFields": {
    "foo": "bar"
  },
  "description": "",
  "email": "john@example.com",
  "lastActivity": "2025-01-03T21:42:30.181Z",
  "locale": "en",
  "manuallyOptedOutFromChangelog": false,
  "organizationId": "5febde12dc56d60012d47db6",
  "postsCreated": 0,
  "profilePicture": "https://fb-usercontent.fra1.cdn.digitaloceanspaces.com/anon_23.png",
  "roles": [
    "string"
  ],
  "subscribedToChangelog": true,
  "userId": "676f0f673dbb299c8a4f3057",
  "verified": true
}
Returns Examples
{
  "id": "676f0f6765bdaa7d7d760f88",
  "name": "John Steezy",
  "object": "contact",
  "type": "customer",
  "commentsCreated": 0,
  "companies": [
    {
      "id": "507f1f77bcf86cd799439011",
      "companyId": "comp_12345",
      "companySize": 250,
      "createdAt": "2025-01-01T12:00:00.000Z",
      "industry": "Technology",
      "lastActivity": "2025-01-15T00:00:00.000Z",
      "linkedUsers": 15,
      "monthlySpend": 5000,
      "name": "Acme Inc",
      "object": "company",
      "plan": "enterprise",
      "updatedAt": "2025-01-10T15:30:00.000Z",
      "website": "https://acme.com",
      "customFields": {
        "location": "bar",
        "priority": "bar"
      }
    }
  ],
  "customFields": {
    "foo": "bar"
  },
  "description": "",
  "email": "john@example.com",
  "lastActivity": "2025-01-03T21:42:30.181Z",
  "locale": "en",
  "manuallyOptedOutFromChangelog": false,
  "organizationId": "5febde12dc56d60012d47db6",
  "postsCreated": 0,
  "profilePicture": "https://fb-usercontent.fra1.cdn.digitaloceanspaces.com/anon_23.png",
  "roles": [
    "string"
  ],
  "subscribedToChangelog": true,
  "userId": "676f0f673dbb299c8a4f3057",
  "verified": true
}