CRMCRM Contacts

CRM Contacts

Manage CRM contacts with API keys or session cookies, including filtering, deduplication, updates, campaign enrollment, and CSV imports.

curl -X GET "https://api.talkturo.com/api/crm/contacts?search=chen&leadStatus=qualified&hasPhone=true&limit=50&offset=0" \
  -H "Authorization: Bearer tk_test_example_9xmk7q2r"
{
  "success": true,
  "contacts": [
    {
      "id": "8e1f5b9d-1e4b-4db1-92b2-4d93471f1af2",
      "firstName": "Maya",
      "lastName": "Chen",
      "email": "maya.chen@northstarhealth.co",
      "phone": "+14155550187",
      "leadStatus": "qualified",
      "doNotCall": false,
      "groups": [
        {
          "id": "grp_7d2a44",
          "name": "Healthcare prospects"
        }
      ]
    }
  ],
  "count": 1,
  "limit": 50,
  "offset": 0
}
curl -X POST "https://api.talkturo.com/api/crm/contacts" \
  -H "Authorization: Bearer tk_test_example_9xmk7q2r" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Priya",
    "lastName": "Natarajan",
    "phone": "+14155550231",
    "email": "priya.natarajan@lakesidepartners.com",
    "jobTitle": "Operations Director",
    "companyName": "Lakeside Partners",
    "leadStatus": "new",
    "source": "webinar",
    "timezone": "America/Los_Angeles",
    "preferredContactMethod": "phone",
    "customFields": {
      "region": "West"
    },
    "tags": ["webinar", "priority"]
  }'
{
  "success": true,
  "existing": false,
  "contact": {
    "id": "2c7f1c6c-4d67-45f0-bf0e-5c9d3d2f2e41",
    "firstName": "Priya",
    "lastName": "Natarajan",
    "phone": "+14155550231",
    "email": "priya.natarajan@lakesidepartners.com",
    "jobTitle": "Operations Director",
    "companyName": "Lakeside Partners",
    "leadStatus": "new",
    "source": "webinar",
    "customFields": {
      "region": "West"
    },
    "tags": ["webinar", "priority"]
  }
}
curl -X GET "https://api.talkturo.com/api/crm/contacts/8e1f5b9d-1e4b-4db1-92b2-4d93471f1af2" \
  -H "Authorization: Bearer tk_test_example_9xmk7q2r"
{
  "success": true,
  "contact": {
    "id": "8e1f5b9d-1e4b-4db1-92b2-4d93471f1af2",
    "firstName": "Maya",
    "lastName": "Chen",
    "phone": "+14155550187",
    "email": "maya.chen@northstarhealth.co",
    "groups": [
      {
        "id": "grp_7d2a44",
        "name": "Healthcare prospects"
      }
    ],
    "activities": [],
    "opportunities": [],
    "campaign_history": []
  }
}
curl -X PUT "https://api.talkturo.com/api/crm/contacts/8e1f5b9d-1e4b-4db1-92b2-4d93471f1af2" \
  -H "Authorization: Bearer tk_test_example_9xmk7q2r" \
  -H "Content-Type: application/json" \
  -d '{
    "leadStatus": "qualified",
    "jobTitle": "Director of Operations",
    "doNotCall": false,
    "lastContactedAt": "2025-02-14T16:30:00.000Z",
    "customFields": {
      "region": "West",
      "accountTier": "enterprise"
    }
  }'
{
  "success": true,
  "contact": {
    "id": "8e1f5b9d-1e4b-4db1-92b2-4d93471f1af2",
    "firstName": "Maya",
    "lastName": "Chen",
    "phone": "+14155550187",
    "leadStatus": "qualified",
    "jobTitle": "Director of Operations",
    "doNotCall": false,
    "lastContactedAt": "2025-02-14T16:30:00.000Z",
    "customFields": {
      "region": "West",
      "accountTier": "enterprise"
    }
  }
}
curl -X DELETE "https://api.talkturo.com/api/crm/contacts/8e1f5b9d-1e4b-4db1-92b2-4d93471f1af2" \
  -H "Authorization: Bearer tk_test_example_9xmk7q2r"
{
  "success": true,
  "message": "Contact deleted successfully"
}
curl -X POST "https://api.talkturo.com/api/crm/contacts/import" \
  -H "Authorization: Bearer tk_test_example_9xmk7q2r" \
  -F "file=@contacts.csv" \
  -F "teamId=team_4c8d12" \
  -F "groupId=grp_7d2a44" \
  -F "duplicateMode=skip" \
  -F 'columnMapping={"firstName":"first_name","lastName":"last_name","phone":"phone","email":"email"}'
{
  "success": true,
  "imported": 42,
  "updated": 8,
  "skipped": 3,
  "failed": 1,
  "total": 54,
  "errors": [
    {
      "row": 17,
      "message": "Invalid phone number"
    }
  ],
  "groupId": "grp_7d2a44",
  "batchId": "batch_91f3c2"
}
curl -X GET "https://api.talkturo.com/api/crm/import-batches?teamId=team_4c8d12&groupId=grp_7d2a44&limit=50" \
  -H "Authorization: Bearer tk_test_example_9xmk7q2r"
{
  "success": true,
  "batches": [
    {
      "id": "batch_91f3c2",
      "filename": "contacts.csv",
      "created_at": "2025-02-14T16:30:00.000Z",
      "created_count": 42,
      "updated_count": 8,
      "skipped_count": 3,
      "failed_count": 1
    }
  ]
}

CRM contacts endpoints

Use CRM contact endpoints to manage contact records, filter contacts, import CSV files, and review import batches.

CRM contact endpoints support API key authentication and session cookie authentication. API key requests use the account associated with the key, so teamId is optional. Session requests must include teamId in the query string or request body.

Endpoint summary

MethodPathDescription
GET/api/crm/contactsList contacts with pagination and filters
POST/api/crm/contactsCreate or deduplicate a contact
GET/api/crm/contacts/{id}Get an enriched contact by ID
PUT/api/crm/contacts/{id}Update a contact
DELETE/api/crm/contacts/{id}Delete a contact
POST/api/crm/contacts/importImport contacts from a CSV file
GET/api/crm/import-batchesList contact import batches

List contacts

Retrieve contacts with pagination, text search, group filtering, lead status filtering, and phone availability filters.

Query parameters

query
teamIdstring

Team to search. Required for session requests when the team cannot be resolved from authentication. API key requests use the key's associated account.

query
groupIdstring

Restrict results to contacts in the specified group.

query
leadStatusstring

Filter contacts by an exact lead status.

query
doNotCallboolean

Filter by the contact's do-not-call setting. Use the literal values true or false.

Allowed values:truefalse
query
hasPhoneboolean

Filter by phone availability. true returns contacts whose phone is not null. false returns contacts whose phone is null.

Allowed values:truefalse
query
limitinteger

Maximum number of contacts to return. Defaults to 50.

query
offsetinteger

Number of matching contacts to skip before returning results. Defaults to 0.

Response fields

successboolean
Required

Returns true when the request succeeds.

contactsarray
Required

Contacts matching the filters. Each contact includes a groups array containing group id and name values.

countinteger
Required

Number of contacts returned for the current request.

limitinteger
Required

Applied result limit.

offsetinteger
Required

Applied result offset.

Create a contact

Create a contact with camelCase fields. The endpoint deduplicates by phone number before creating a record.

Request body

body
firstNamestring
Required

Non-empty contact first name.

body
lastNamestring
Required

Non-empty contact last name.

body
phonestring
Required

Contact phone number in E.164 format, such as +14155550231. The value must match ^\+[1-9]\d{6,14}$.

body
teamIdstring

Team to associate with the contact. Required for session requests. API key requests use the key's associated account.

body
groupIdstring

Group to associate with the contact. Defaults to the team's default group when omitted.

body
emailstring

Contact email address.

body
phoneSecondarystring

Secondary phone number.

body
jobTitlestring

Contact job title.

body
companyNamestring

Contact company name. Use companyName, not company_id.

body
leadStatusstring

Contact lead status.

body
sourcestring

Contact source. Defaults to api.

body
timezonestring

Contact timezone.

body
preferredContactMethodstring

Preferred contact method.

body
doNotCallboolean

Whether the contact must not be called.

body
notesstring

Notes associated with the contact.

body
customFieldsobject

Custom contact fields as key-value pairs.

body
tagsarray

Array of tags to associate with the contact.

body
campaignIdstring

Campaign in which to enroll the contact after creation.

body
campaignPriorityinteger

Priority to use for the campaign enrollment.

Deduplication and campaign enrollment

The endpoint checks for an existing contact with the same phone number. When a match exists, the endpoint merges supplied non-empty fields into the existing record and returns existing: true instead of creating a duplicate.

When campaignId is supplied, the response also includes campaign_enrollment with the campaign contact ID, enrollment status, and exclusion reason when applicable.

successboolean
Required

Returns true when the request succeeds.

contactobject
Required

Created or updated contact record.

existingboolean
Required

Returns true when the phone number matched an existing contact.

campaign_enrollmentobject

Campaign enrollment result when campaignId is supplied.

campaign_enrollment.campaign_contact_idstring

Identifier for the campaign contact record.

campaign_enrollment.statusstring

Enrollment status: enrolled, already_enrolled, or excluded.

campaign_enrollment.excludedReasonstring or null

Exclusion reason. Possible values include no_phone and do_not_call.

Get a contact

Fetch a contact by ID. The response includes the contact's group memberships, activities, opportunities, and campaign history.

Path parameters

Response fields

successboolean
Required

Returns true when the contact is found.

contactobject
Required

Enriched contact record.

contact.groupsarray
Required

Groups associated with the contact.

contact.activitiesarray
Required

Activities associated with the contact.

contact.opportunitiesarray
Required

Opportunities associated with the contact.

contact.campaign_historyarray
Required

Campaign history for the contact.

Update a contact

Update one or more contact fields with PUT. All request body fields are optional. Use the same camelCase fields as the create endpoint and omit fields that should not change.

Path parameters

Request body

body
teamIdstring

Team associated with the contact. Required for session requests when the team cannot be resolved from authentication.

body
firstNamestring

Updated first name.

body
lastNamestring

Updated last name.

body
phonestring

Updated phone number in E.164 format.

body
emailstring

Updated email address.

body
phoneSecondarystring

Updated secondary phone number.

body
groupIdstring

Updated group association.

body
jobTitlestring

Updated job title.

body
companyNamestring

Updated company name.

body
leadStatusstring

Updated lead status.

body
sourcestring

Updated contact source.

body
timezonestring

Updated contact timezone.

body
preferredContactMethodstring

Updated preferred contact method.

body
doNotCallboolean

Updated do-not-call setting.

body
notesstring

Updated contact notes.

body
customFieldsobject

Custom contact fields to update.

body
tagsarray

Updated contact tags.

body
campaignIdstring

Campaign associated with the contact.

body
campaignPriorityinteger

Updated campaign priority.

body
lastContactedAtstring

Timestamp of the contact's most recent interaction.

Response fields

successboolean
Required

Returns true when the contact is updated.

contactobject
Required

Updated contact record.

Delete a contact

Delete a contact by ID. Contacts that belong to an active campaign cannot be deleted.

Path parameters

Response fields

successboolean
Required

Returns true when the contact is deleted.

messagestring
Required

Deletion result message.

The endpoint rejects deletion when the contact is in an active campaign.

Bulk import contacts

Import contacts from a CSV file with multipart/form-data. The file, teamId, and columnMapping form fields are required.

Form fields

body
filefile
Required

CSV file to import. The first_name column is required. The last_name column is optional for imports.

body
teamIdstring
Required

Team that owns the imported contacts.

body
groupIdstring

Existing group to associate with imported contacts. Use this or newGroupName.

body
newGroupNamestring

Name for a new group. Use this when you are not providing groupId.

body
duplicateModestring

How to handle duplicate contacts. Defaults to skip.

Allowed values:skipupdatereplace
body
columnMappingstring
Required

JSON string that maps contact fields to CSV column names.

Response fields

successboolean
Required

Returns true when the import is processed.

importedinteger
Required

Number of contacts imported as new records.

updatedinteger
Required

Number of existing contacts updated.

skippedinteger
Required

Number of contacts skipped according to duplicateMode.

failedinteger
Required

Number of records that failed to import.

totalinteger
Required

Total number of records processed.

errorsarray
Required

Import errors for records that could not be processed.

groupIdstring
Required

Group that received the imported contacts.

batchIdstring
Required

Identifier for the import batch.

List import batches

Retrieve import batches for a team and group.

Query parameters

query
teamIdstring
Required

Team whose import batches should be returned when the team cannot be resolved from authentication.

query
groupIdstring
Required

Group whose import batches should be returned.

query
limitinteger

Maximum number of batches to return. Defaults to 50 and is clamped between 1 and 200.

Response fields

successboolean
Required

Returns true when the request succeeds.

batchesarray
Required

Import batch records for the requested group.

batches[].idstring
Required

Import batch identifier.

batches[].filenamestring
Required

Name of the imported CSV file.

batches[].created_atstring
Required

Timestamp when the batch was created.

batches[].created_countinteger
Required

Number of contacts created by the batch.

batches[].updated_countinteger
Required

Number of contacts updated by the batch.

batches[].skipped_countinteger
Required

Number of contacts skipped by the batch.

batches[].failed_countinteger
Required

Number of records that failed during the batch.

Notes on custom fields

Contact create, update, and import endpoints accept custom fields in addition to the standard contact properties.

Send custom fields through the camelCase customFields object. Keep field names consistent with your CRM configuration so created, updated, and imported data maps to the expected contact fields.