Skip to main content

Bit CRM Contacts API Documentation for Developers

Estimated reading: 12 minutes 65 views

The Bit CRM Contacts API lets you create, search, retrieve, update, and tag contacts. All endpoints are relative to your base URL and authenticated with an API key — see Introduction & Authentication.

Contact field keys

Create and update requests take contact fields inside a systemDefinedFieldsValues object. All values are strings; only last_name is required.

  • title — one of mrs, mr, miss, ms, dr
  • first_name, last_name (required), email, secondary_email, phone, mobile, fax, date_of_birth
  • company_id — ID of the contact’s company
  • parent_id — ID of the contact this contact reports to
  • department, assistant, assistant_phone
  • lead_source — one of none, advertisement, cold_call, employee_referral, external_referral, online_store, facebook
  • owner_id — WordPress user ID of the contact owner
  • currency — currency code; defaults to your home currency. Send it at the top level of the payload (beside systemDefinedFieldsValues, not inside it — a nested value is ignored).
  • billing_address_line_1, billing_address_line_2, billing_city, billing_county, billing_state, billing_zip, billing_country
  • shipping_address_line_1, shipping_address_line_2, shipping_city, shipping_county, shipping_state, shipping_zip, shipping_country
  • description

Note: If you have defined custom fields for contacts (a Pro feature), send their values in a separate customFieldsValues object alongside systemDefinedFieldsValues, keyed by field key — each entry carries the field’s field_id and its field_value. Custom field values are accepted on both create and update, and come back in the response as custom_fields_values.

Create a contact

POST /contacts/store — requires capability bit_crm_contact_create.

  • systemDefinedFieldsValues — object, required. Contact fields (see above); last_name is required.
  • tagIds — array of integers, optional. IDs of existing contact tags to attach.
  • newTagTitles — array of strings, optional. New tags to create and attach.
  • clientPortal — boolean, optional. Give the contact client portal access; requires email to be set.
POST https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/store
  • Bash
  • PHP
  • JavaScript
curl -X POST "https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/store" \
  --user "your-username:YOUR API KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "systemDefinedFieldsValues": {
      "first_name": "Jane",
      "last_name": "Doe",
      "email": "[email protected]",
      "phone": "+1 555 0100"
    },
    "customFieldsValues": {
      "membership_tier": {
        "field_id": 3,
        "field_value": "Gold"
      }
    },
    "newTagTitles": [
      "Newsletter"
    ]
  }'
$ch = curl_init('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/store');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'your-username:YOUR API KEY',
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'systemDefinedFieldsValues' => [
            'first_name' => 'Jane',
            'last_name' => 'Doe',
            'email' => '[email protected]',
            'phone' => '+1 555 0100',
        ],
        'customFieldsValues' => [
            'membership_tier' => [
                'field_id' => 3,
                'field_value' => 'Gold',
            ],
        ],
        'newTagTitles' => [
            'Newsletter',
        ],
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/store', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('your-username:YOUR API KEY'),
  },
  body: JSON.stringify({
    "systemDefinedFieldsValues": {
      "first_name": "Jane",
      "last_name": "Doe",
      "email": "[email protected]",
      "phone": "+1 555 0100"
    },
    "customFieldsValues": {
      "membership_tier": {
        "field_id": 3,
        "field_value": "Gold"
      }
    },
    "newTagTitles": [
      "Newsletter"
    ]
  }),
});
const result = await response.json();

Example response — data is the created contact:

{
  "status": "success",
  "code": "SUCCESS",
  "data": {
    "id": 42,
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+1 555 0100",
    "currency": "USD",
    "reference_uuid": "3f2b9c8e-7a41-4b6d-9e2f-1c5a8d7b6e40",
    "created_by": 1,
    "created_at": "2026-08-04 10:30:00",
    "updated_at": "2026-08-04 10:30:00",
    "custom_fields_values": {
      "membership_tier": { "field_id": 3, "field_value": "Gold", "field_key": "membership_tier" }
    }
  }
}

Search contacts

POST /contacts/search — requires capability bit_crm_contact_view.

  • page — integer, optional, default 1.
  • perPage — integer, optional, default 10.
  • searchTerm — string. Matches first name, last name, and email. Send "" when not searching.
  • sortBy — string, optional, default id. A contact column to sort by.
  • sortOrder — asc or desc, optional, default desc.
  • tags — array of tag IDs, optional. Limits results to contacts holding these tags.
  • filters — object of field: value pairs, optional.
  • advancedFilterGroups — array, optional. Advanced filter groups in the same shape the CRM’s own filter UI sends (field_key, operator, field_type, is_custom, value).
POST https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/search
  • Bash
  • PHP
  • JavaScript
curl -X POST "https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/search" \
  --user "your-username:YOUR API KEY" \
  -H "Content-Type: application/json" \
  -d '{"page": 1, "perPage": 10, "searchTerm": "jane"}'
$ch = curl_init('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/search');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'your-username:YOUR API KEY',
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode(['page' => 1, 'perPage' => 10, 'searchTerm' => 'jane']),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/search', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('your-username:YOUR API KEY'),
  },
  body: JSON.stringify({"page": 1, "perPage": 10, "searchTerm": "jane"}),
});
const result = await response.json();

Example response — a paginated object; each row also carries company_name, owner_name, and parent_name:

{
  "status": "success",
  "code": "SUCCESS",
  "data": {
    "data": [
      {
        "id": 42,
        "first_name": "Jane",
        "last_name": "Doe",
        "email": "[email protected]",
        "company_name": "Acme Inc",
        "owner_name": "Sam Owner",
        "parent_name": null,
        "created_at": "2026-08-04 10:30:00"
      }
    ],
    "pages": 1,
    "total": 1,
    "current_total": 1,
    "current_page": 1,
    "last_page": 1,
    "per_page": 10
  }
}

Retrieve a contact

GET /contacts/{id} — requires capability bit_crm_contact_view.

data holds every contact field plus created_by_name and updated_by_name, the contact’s tags (each {id, title, slug} — present only when the contact has tags), and previous_id / next_id for record navigation. Trashed contacts are not returned.

GET https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/42
  • Bash
  • PHP
  • JavaScript
curl "https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/42" \
  --user "your-username:YOUR API KEY"
$ch = curl_init('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/42');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'your-username:YOUR API KEY',
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/42', {
  headers: { 'Authorization': 'Basic ' + btoa('your-username:YOUR API KEY') },
});
const result = await response.json();

Update a contact

POST /contacts/{id} — requires capability bit_crm_contact_update.

Send the fields to change inside systemDefinedFieldsValues. Always include last_name — it is validated as required even when you are updating other fields.

POST https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/42
  • Bash
  • PHP
  • JavaScript
curl -X POST "https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/42" \
  --user "your-username:YOUR API KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "systemDefinedFieldsValues": {
      "last_name": "Doe",
      "phone": "+1 555 0199"
    }
  }'
$ch = curl_init('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/42');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'your-username:YOUR API KEY',
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'systemDefinedFieldsValues' => [
            'last_name' => 'Doe',
            'phone' => '+1 555 0199',
        ],
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/42', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('your-username:YOUR API KEY'),
  },
  body: JSON.stringify({
    "systemDefinedFieldsValues": {
      "last_name": "Doe",
      "phone": "+1 555 0199"
    }
  }),
});
const result = await response.json();

Example response — message is Contact updated successfully. and data is the updated contact.

Attach a tag

POST /contacts/attach-tag — requires capability bit_crm_contact_update.

  • title — string, required. Matched against the tag’s slug in the contact module. If no such tag exists and the key’s user can create tags (bit_crm_tag_create), a new tag is created from this value.
  • contact_id — integer, required.
POST https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/attach-tag
  • Bash
  • PHP
  • JavaScript
curl -X POST "https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/attach-tag" \
  --user "your-username:YOUR API KEY" \
  -H "Content-Type: application/json" \
  -d '{"title": "newsletter", "contact_id": 42}'
$ch = curl_init('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/attach-tag');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'your-username:YOUR API KEY',
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode(['title' => 'newsletter', 'contact_id' => 42]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/attach-tag', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('your-username:YOUR API KEY'),
  },
  body: JSON.stringify({"title": "newsletter", "contact_id": 42}),
});
const result = await response.json();

Example response — note that data is a plain string on this endpoint: "Tag added successfully.", or "Tag already added" when the contact already holds the tag.

Detach a tag

POST /contacts/detach-tag — requires capability bit_crm_contact_update.

  • tag_id — integer, required. The tag’s ID (find it with the Tags API).
  • contact_id — integer, required.
POST https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/detach-tag
  • Bash
  • PHP
  • JavaScript
curl -X POST "https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/detach-tag" \
  --user "your-username:YOUR API KEY" \
  -H "Content-Type: application/json" \
  -d '{"tag_id": 7, "contact_id": 42}'
$ch = curl_init('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/detach-tag');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'your-username:YOUR API KEY',
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode(['tag_id' => 7, 'contact_id' => 42]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/detach-tag', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('your-username:YOUR API KEY'),
  },
  body: JSON.stringify({"tag_id": 7, "contact_id": 42}),
});
const result = await response.json();

Example response — data is the string "Tag removed successfully."

Attach tags in bulk

POST /contacts/attach-tags — requires capability bit_crm_contact_update. Attaches one or more existing tags to one or more contacts in a single request. Unlike attach-tag, this endpoint takes tag IDs and never creates tags. Pairs that already exist are skipped.

  • contact_ids — array of integers, required, up to 100 IDs.
  • tag_ids — array of integers, required. Tag IDs from the Tags API; the tags must belong to the contact module.
POST https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/attach-tags
  • Bash
  • PHP
  • JavaScript
curl -X POST "https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/attach-tags" \
  --user "your-username:YOUR API KEY" \
  -H "Content-Type: application/json" \
  -d '{"contact_ids":[12,15],"tag_ids":[7,9]}'
$ch = curl_init('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/attach-tags');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'your-username:YOUR API KEY',
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode(['contact_ids' => [12, 15], 'tag_ids' => [7, 9]]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/attach-tags', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('your-username:YOUR API KEY'),
  },
  body: JSON.stringify({"contact_ids":[12,15],"tag_ids":[7,9]}),
});
const result = await response.json();

Example response — data is the string "Tag added successfully.". If every requested pair already exists, the request fails with the message Tags already added.

Detach tags in bulk

POST /contacts/detach-tags — requires capability bit_crm_contact_update. Removes one or more tags from one or more contacts in a single request.

  • contact_ids — array of integers, required, up to 100 IDs.
  • tag_ids — array of integers, required.
POST https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/detach-tags
  • Bash
  • PHP
  • JavaScript
curl -X POST "https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/detach-tags" \
  --user "your-username:YOUR API KEY" \
  -H "Content-Type: application/json" \
  -d '{"contact_ids":[12,15],"tag_ids":[7]}'
$ch = curl_init('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/detach-tags');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'your-username:YOUR API KEY',
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode(['contact_ids' => [12, 15], 'tag_ids' => [7]]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/detach-tags', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('your-username:YOUR API KEY'),
  },
  body: JSON.stringify({"contact_ids":[12,15],"tag_ids":[7]}),
});
const result = await response.json();

Example response — data is the string "Tag(s) removed successfully."

Move contacts to the trash

POST /contacts/trash — requires capability bit_crm_contact_delete. This is a soft delete: the records move to the recycle bin (Settings → Data Management) and can be restored from there. Contacts associated with a deal are skipped; the response message then reports how many were deleted and how many were skipped. When exactly one contact is trashed, data may contain the previous_id and next_id of its neighboring records.

  • ids — array of integers, required. The contact IDs to trash.
POST https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/trash
  • Bash
  • PHP
  • JavaScript
curl -X POST "https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/trash" \
  --user "your-username:YOUR API KEY" \
  -H "Content-Type: application/json" \
  -d '{"ids":[12,15]}'
$ch = curl_init('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/trash');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'your-username:YOUR API KEY',
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode(['ids' => [12, 15]]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.com/wp-json/bit-crm-sales-marketing-automation/v1/contacts/trash', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('your-username:YOUR API KEY'),
  },
  body: JSON.stringify({"ids":[12,15]}),
});
const result = await response.json();

Example response. When some contacts are skipped due to deal associations, message instead reads %1$d contact(s) deleted. %2$d contact(s) skipped due to associated deals. with the counts filled in:

{
  "status": "success",
  "message": "Contact deleted successfully.",
  "code": "SUCCESS",
  "data": []
}
Share this Doc

Bit CRM Contacts API Documentation for Developers

Or copy link

CONTENTS

Subscribe

×
Cancel