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"
curl -X GET "https://api.talkturo.com/api/crm/contacts?teamId=team_4c8d12&groupId=grp_7d2a44&search=chen&leadStatus=qualified&hasPhone=true&limit=50&offset=0" \
-H "Cookie: sb-access-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example"
{
"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"]
}'
curl -X POST "https://api.talkturo.com/api/crm/contacts" \
-H "Cookie: sb-access-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example" \
-H "Content-Type: application/json" \
-d '{
"teamId": "team_4c8d12",
"groupId": "grp_7d2a44",
"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"
curl -X GET "https://api.talkturo.com/api/crm/contacts/8e1f5b9d-1e4b-4db1-92b2-4d93471f1af2?teamId=team_4c8d12" \
-H "Cookie: sb-access-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example"
{
"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"
}
}'
curl -X PUT "https://api.talkturo.com/api/crm/contacts/8e1f5b9d-1e4b-4db1-92b2-4d93471f1af2" \
-H "Cookie: sb-access-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example" \
-H "Content-Type: application/json" \
-d '{
"teamId": "team_4c8d12",
"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"
curl -X DELETE "https://api.talkturo.com/api/crm/contacts/8e1f5b9d-1e4b-4db1-92b2-4d93471f1af2?teamId=team_4c8d12" \
-H "Cookie: sb-access-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example"
{
"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"}'
curl -X POST "https://api.talkturo.com/api/crm/contacts/import" \
-H "Cookie: sb-access-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example" \
-F "file=@contacts.csv" \
-F "teamId=team_4c8d12" \
-F "newGroupName=Healthcare prospects" \
-F "duplicateMode=update" \
-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"
curl -X GET "https://api.talkturo.com/api/crm/import-batches?teamId=team_4c8d12&groupId=grp_7d2a44&limit=50" \
-H "Cookie: sb-access-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example"
{
"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
| Method | Path | Description |
|---|---|---|
GET | /api/crm/contacts | List contacts with pagination and filters |
POST | /api/crm/contacts | Create 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/import | Import contacts from a CSV file |
GET | /api/crm/import-batches | List contact import batches |
List contacts
Retrieve contacts with pagination, text search, group filtering, lead status filtering, and phone availability filters.
Query parameters
Team to search. Required for session requests when the team cannot be resolved from authentication. API key requests use the key's associated account.
Restrict results to contacts in the specified group.
Case-insensitive partial search across first_name, last_name, email, and phone.
Filter contacts by an exact lead status.
Filter by the contact's do-not-call setting. Use the literal values true or false.
truefalseFilter by phone availability. true returns contacts whose phone is not null. false returns contacts whose phone is null.
truefalseMaximum number of contacts to return. Defaults to 50.
Number of matching contacts to skip before returning results. Defaults to 0.
Response fields
Returns true when the request succeeds.
Contacts matching the filters. Each contact includes a groups array containing group id and name values.
Number of contacts returned for the current request.
Applied result limit.
Applied result offset.
Create a contact
Create a contact with camelCase fields. The endpoint deduplicates by phone number before creating a record.
Request body
Non-empty contact first name.
Non-empty contact last name.
Contact phone number in E.164 format, such as +14155550231. The value must match ^\+[1-9]\d{6,14}$.
Team to associate with the contact. Required for session requests. API key requests use the key's associated account.
Group to associate with the contact. Defaults to the team's default group when omitted.
Contact email address.
Secondary phone number.
Contact job title.
Contact company name. Use companyName, not company_id.
Contact lead status.
Contact source. Defaults to api.
Contact timezone.
Preferred contact method.
Whether the contact must not be called.
Notes associated with the contact.
Custom contact fields as key-value pairs.
Campaign in which to enroll the contact after creation.
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.
Returns true when the request succeeds.
Created or updated contact record.
Returns true when the phone number matched an existing contact.
Campaign enrollment result when campaignId is supplied.
Identifier for the campaign contact record.
Enrollment status: enrolled, already_enrolled, or excluded.
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
Contact ID.
Response fields
Returns true when the contact is found.
Enriched contact record.
Groups associated with the contact.
Activities associated with the contact.
Opportunities associated with the contact.
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
Contact ID.
Request body
Team associated with the contact. Required for session requests when the team cannot be resolved from authentication.
Updated first name.
Updated last name.
Updated phone number in E.164 format.
Updated email address.
Updated secondary phone number.
Updated group association.
Updated job title.
Updated company name.
Updated lead status.
Updated contact source.
Updated contact timezone.
Updated preferred contact method.
Updated do-not-call setting.
Updated contact notes.
Custom contact fields to update.
Campaign associated with the contact.
Updated campaign priority.
Timestamp of the contact's most recent interaction.
Response fields
Returns true when the contact is updated.
Updated contact record.
Delete a contact
Delete a contact by ID. Contacts that belong to an active campaign cannot be deleted.
Path parameters
Contact ID.
Response fields
Returns true when the contact is deleted.
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
CSV file to import. The first_name column is required. The last_name column is optional for imports.
Team that owns the imported contacts.
Existing group to associate with imported contacts. Use this or newGroupName.
Name for a new group. Use this when you are not providing groupId.
How to handle duplicate contacts. Defaults to skip.
skipupdatereplaceJSON string that maps contact fields to CSV column names.
Response fields
Returns true when the import is processed.
Number of contacts imported as new records.
Number of existing contacts updated.
Number of contacts skipped according to duplicateMode.
Number of records that failed to import.
Total number of records processed.
Import errors for records that could not be processed.
Group that received the imported contacts.
Identifier for the import batch.
List import batches
Retrieve import batches for a team and group.
Query parameters
Team whose import batches should be returned when the team cannot be resolved from authentication.
Group whose import batches should be returned.
Maximum number of batches to return. Defaults to 50 and is clamped between 1 and 200.
Response fields
Returns true when the request succeeds.
Import batch records for the requested group.
Import batch identifier.
Name of the imported CSV file.
Timestamp when the batch was created.
Number of contacts created by the batch.
Number of contacts updated by the batch.
Number of contacts skipped by the batch.
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.