Contacts
Manage contacts within your workspace. Contacts store customer or lead information including phone numbers, emails, and custom metadata. They can be organized into Address Books.
Data Scoping
Agents can only see contacts within Address Books they have access to (books owned by them owner_type: agent, books owned by teams they belong to owner_type: team, or shared books owner_type: everyone).
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /call-center/contacts | List all contacts |
GET | /call-center/contacts/lookup | Look up contact by phone number |
GET | /call-center/contacts/:id | Get contact details |
POST | /call-center/contacts | Create a new contact |
POST | /call-center/contacts/assign-list | Batch assign contacts to a list |
PUT | /call-center/contacts/:id | Update a contact |
DELETE | /call-center/contacts/:id | Delete a contact |
Authentication
All endpoints require Bearer JWT with agent-api audience.
Contact Object
| Field | Type | Description |
|---|---|---|
id | string | Unique contact ID (prefixed with ct_) |
workspace_id | string | Workspace identifier |
address_book_id | string | ID of the address book this contact belongs to (defaults to Default book if omitted) |
first_name | string | Contact first name |
last_name | string | Contact last name |
company | string | Company name |
title | string | Job title |
emails | object[] | List of email addresses (see Email Object) |
phone_numbers | object[] | List of phone numbers (see Phone Number Object) |
tags | string[] | Tags for categorization |
notes | string | Free-text notes (max 1000 chars) |
timezone | string | Contact timezone (e.g., "Asia/Ho_Chi_Minh") |
language | string | Preferred language (e.g., "vi", "en") |
country_code | string | ISO 3166-1 alpha-2 country code (e.g., "VN") |
assigned_agent_id | string | Optional ID of the assigned agent responsible for this contact |
source | string | Origin of this contact (e.g., "manual", "import", "call") |
custom_fields | object | Key-value pairs for custom data |
created_at | string | ISO 8601 creation timestamp |
updated_at | string | ISO 8601 last update timestamp |
Phone Number Object
| Field | Type | Description |
|---|---|---|
phone_number | string | Phone number string (e.g., "+84901234567") |
type | string | Type label: mobile, work, home, fax, etc. |
is_primary | boolean | Whether this is the primary phone number |
Email Object
| Field | Type | Description |
|---|---|---|
email | string | Email address |
type | string | Type label: work, personal, etc. |
is_primary | boolean | Whether this is the primary email |
List Contacts
GET /call-center/contacts
Retrieve a paginated list of all contacts in the workspace.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number (min: 1) |
limit | number | 20 | Items per page (min: 1, max: 100) |
search | string | — | Search by name, phone number, or email (text search) |
sort_field | string | — | Sort by: created_at, first_name, last_name, company |
sort_order | string | desc | Sort order: asc or desc |
Request
curl -X GET "https://{workspace_id}.firetell.app/api/v1/call-center/contacts?page=1&limit=10&search=john" \
-H "Authorization: Bearer YOUR_AGENT_JWT"
Response 200 OK
{
"data": [
{
"id": "ct_a1b2c3d4e5f6g7h8i9j0k1",
"workspace_id": "my_workspace",
"address_book_id": "ab_x1y2z3w4v5u6t7s8",
"first_name": "John",
"last_name": "Doe",
"company": "Acme Corp",
"title": "CTO",
"emails": [
{ "email": "john@acme.com", "type": "work", "is_primary": true }
],
"phone_numbers": [
{ "phone_number": "+84901234567", "type": "mobile", "is_primary": true }
],
"tags": ["vip", "enterprise"],
"notes": "Key decision maker",
"timezone": "Asia/Ho_Chi_Minh",
"language": "en",
"country_code": "VN",
"owner_id": "ag_abc123",
"owner_type": "agent",
"source": "manual",
"custom_fields": { "deal_size": "50000" },
"created_at": "2026-01-15T08:30:00.000Z",
"updated_at": "2026-07-13T09:00:00.000Z"
}
],
"meta": {
"total": 1,
"page": 1,
"limit": 10,
"total_pages": 1
}
}
Lookup Contact by Phone Number
GET /call-center/contacts/lookup
Find a contact by their phone number. The phone number is automatically normalized for matching, so formats like +84901234567, 0901234567, or 84901234567 all match the same contact.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
number | string | ✅ | Phone number to look up |
Request
curl -X GET "https://{workspace_id}.firetell.app/api/v1/call-center/contacts/lookup?number=84901234567" \
-H "Authorization: Bearer YOUR_AGENT_JWT"
Response 200 OK
Returns the matching contact object, or null if no contact is found.
{
"id": "ct_a1b2c3d4e5f6g7h8i9j0k1",
"first_name": "John",
"last_name": "Doe",
"company": "Acme Corp",
"phone_numbers": [
{ "phone_number": "+84901234567", "type": "mobile", "is_primary": true }
]
}
This endpoint is commonly used during incoming calls to display caller information. The call flow engine also uses it internally for the Contact Lookup node.
Get Contact Details
GET /call-center/contacts/:id
Retrieve detailed information about a specific contact.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Contact ID (e.g., ct_a1b2c3...) |
Request
curl -X GET "https://{workspace_id}.firetell.app/api/v1/call-center/contacts/ct_a1b2c3d4e5f6g7h8i9j0k1" \
-H "Authorization: Bearer YOUR_AGENT_JWT"
Response 200 OK
Returns the full contact object.
Error Responses
| Status | Description |
|---|---|
404 | Contact not found |
Create a Contact
POST /call-center/contacts
Create a new contact in the workspace. All fields except the basic identity fields are optional.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
first_name | string | First name (max 100 chars) | |
last_name | string | Last name (max 100 chars) | |
company | string | Company name (max 100 chars) | |
title | string | Job title (max 100 chars) | |
emails | object[] | Email addresses (see Email Object) | |
phone_numbers | object[] | Phone numbers (see Phone Number Object) | |
tags | string[] | Tags for categorization | |
notes | string | Free-text notes (max 1000 chars) | |
timezone | string | Timezone identifier (max 50 chars) | |
language | string | Language code (max 10 chars) | |
country_code | string | ISO country code (max 10 chars) | |
address_book_id | string | Assign to an address book (defaults to Default book if omitted) | |
assigned_agent_id | string | Optional assigned agent responsible for this contact | |
source | string | Origin label (max 50 chars) | |
custom_fields | object | Key-value pairs for custom data |
Request
curl -X POST "https://{workspace_id}.firetell.app/api/v1/call-center/contacts" \
-H "Authorization: Bearer YOUR_AGENT_JWT" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"last_name": "Smith",
"company": "TechStart Inc.",
"title": "Product Manager",
"emails": [
{ "email": "jane@techstart.io", "type": "work", "is_primary": true }
],
"phone_numbers": [
{ "phone_number": "+84912345678", "type": "mobile", "is_primary": true },
{ "phone_number": "+84281234567", "type": "work" }
],
"tags": ["lead", "tech"],
"notes": "Met at TechConf 2026",
"timezone": "Asia/Ho_Chi_Minh",
"language": "vi",
"country_code": "VN",
"address_book_id": "ab_x1y2z3w4v5u6t7s8",
"owner_type": "agent",
"source": "manual"
}'
Response 201 Created
Returns the created contact object.
{
"id": "ct_n3w1d2e3f4g5h6i7j8k9l0",
"workspace_id": "my_workspace",
"first_name": "Jane",
"last_name": "Smith",
"company": "TechStart Inc.",
"title": "Product Manager",
"emails": [
{ "email": "jane@techstart.io", "type": "work", "is_primary": true }
],
"phone_numbers": [
{
"phone_number": "+84912345678",
"type": "mobile",
"is_primary": true,
"normalized_number": "84912345678"
},
{
"phone_number": "+84281234567",
"type": "work",
"normalized_number": "84281234567"
}
],
"tags": ["lead", "tech"],
"notes": "Met at TechConf 2026",
"address_book_id": "ab_x1y2z3w4v5u6t7s8",
"owner_type": "agent",
"source": "manual",
"created_at": "2026-07-21T08:00:00.000Z",
"updated_at": "2026-07-21T08:00:00.000Z"
}
Error Responses
| Status | Description |
|---|---|
400 | Validation error or address book does not exist |
Phone numbers are automatically normalized for consistent lookup. The normalized_number field is generated server-side and used for the Lookup endpoint.
Update a Contact
PUT /call-center/contacts/:id
Update an existing contact. All fields are optional — only include the fields you want to change.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Contact ID |
Request Body
Same fields as Create a Contact. All fields are optional.
Request
curl -X PUT "https://{workspace_id}.firetell.app/api/v1/call-center/contacts/ct_a1b2c3d4e5f6g7h8i9j0k1" \
-H "Authorization: Bearer YOUR_AGENT_JWT" \
-H "Content-Type: application/json" \
-d '{
"company": "TechStart Global",
"title": "VP of Product",
"tags": ["vip", "enterprise", "tech"]
}'
Response 200 OK
Returns the updated contact object.
Error Responses
| Status | Description |
|---|---|
400 | Validation error or address book does not exist |
404 | Contact not found |
Delete a Contact
DELETE /call-center/contacts/:id
Permanently delete a contact from the workspace. This action cannot be undone.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Contact ID |
Request
curl -X DELETE "https://{workspace_id}.firetell.app/api/v1/call-center/contacts/ct_a1b2c3d4e5f6g7h8i9j0k1" \
-H "Authorization: Bearer YOUR_AGENT_JWT"
Response 200 OK
Returns the deleted contact object.
Error Responses
| Status | Description |
|---|---|
404 | Contact not found |
Deleting a contact is irreversible. Consider updating the contact's tags or moving it to a different address book instead if you need to archive it.
Assign Contacts to an Address Book
POST /call-center/contacts/assign-list
Batch assign multiple contacts to an address book (or unassign by passing null). You can assign up to 50 contacts per request.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
address_book_id | string | null | ✅ | Target address book ID. Pass null to unassign contacts from their book |
contact_ids | string[] | ✅ | Array of contact IDs to assign (min: 1, max: 50) |
Request
curl -X POST "https://{workspace_id}.firetell.app/api/v1/call-center/contacts/assign-list" \
-H "Authorization: Bearer YOUR_AGENT_JWT" \
-H "Content-Type: application/json" \
-d '{
"address_book_id": "ab_x1y2z3w4v5u6t7s8",
"contact_ids": [
"ct_a1b2c3d4e5f6g7h8i9j0k1",
"ct_n3w1d2e3f4g5h6i7j8k9l0",
"ct_z9y8x7w6v5u4t3s2r1q0p9"
]
}'
Response 200 OK
{
"matched": 3,
"modified": 3
}
| Field | Type | Description |
|---|---|---|
matched | number | Number of contacts found that you have access to |
modified | number | Number of contacts actually updated (excludes no-ops) |
If matched is less than the number of contact_ids you sent, it means some contacts don't exist or you don't have access to them.
Unassign Contacts
To remove contacts from their current address book, pass null as the address_book_id:
curl -X POST "https://{workspace_id}.firetell.app/api/v1/call-center/contacts/assign-list" \
-H "Authorization: Bearer YOUR_AGENT_JWT" \
-H "Content-Type: application/json" \
-d '{
"address_book_id": null,
"contact_ids": ["ct_a1b2c3d4e5f6g7h8i9j0k1"]
}'
Error Responses
| Status | Description |
|---|---|
400 | Validation error or address book not found |