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 (User Tag) names 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 (User Tag) names 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": [
            "app",
            "role_vip",
            "role_beta",
            "app",
            "Internal User"
          ],
          "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
}