Skip to main content

Contacts API

The Contacts module stores all persons and companies your organization interacts with — customers, vendors, partners, and leads. Every contact belongs to your organization (organizationId) and is automatically scoped on every request.


Endpoints

MethodPathDescription
GET/api/contactsList contacts (paginated)
POST/api/contactsCreate a contact
GET/api/contacts/:idGet a single contact
PATCH/api/contacts/:idUpdate a contact
DELETE/api/contacts/:idDelete a contact
POST/api/contacts/mergeMerge two duplicate contacts
POST/api/contacts/importBulk import from CSV
GET/api/contacts/:id/activityContact activity timeline

List Contacts

GET /api/contacts?page=1&limit=20&sortBy=name&sortOrder=asc&search=acme&type=company

Query Parameters

ParameterTypeDescription
pagenumberPage number (default: 1)
limitnumberItems per page (max: 100, default: 20)
sortBystringname, email, createdAt, updatedAt
sortOrderasc | descSort direction (default: desc)
searchstringSearch name and email fields
typeperson | companyFilter by contact type

Response

{
"data": [
{
"id": "018e1234-abcd-7000-8000-000000000001",
"name": "Acme Corporation",
"email": "[email protected]",
"phone": "+1-555-000-1234",
"type": "company",
"website": "https://acme.com",
"address": {
"street": "123 Main St",
"city": "Springfield",
"country": "US"
},
"tags": ["customer", "enterprise"],
"organizationId": "018e0000-0000-7000-8000-000000000001",
"createdAt": "2026-01-15T09:00:00Z",
"updatedAt": "2026-03-01T14:30:00Z"
}
],
"meta": { "total": 342, "page": 1, "limit": 20, "totalPages": 18 }
}

Create a Contact

POST /api/contacts
Content-Type: application/json
Authorization: Bearer eco_live_...

Request Body

{
"name": "Globex Industries",
"email": "[email protected]",
"phone": "+1-555-999-0000",
"type": "company",
"website": "https://globex.com",
"address": {
"street": "742 Evergreen Terrace",
"city": "Springfield",
"state": "IL",
"zip": "62701",
"country": "US"
},
"tags": ["prospect"]
}

Required fields: name, type

Response: 201 Created with the full contact object.


Get a Contact

GET /api/contacts/018e1234-abcd-7000-8000-000000000001

Returns a single contact with its full field set including associated metadata.


Update a Contact

PATCH /api/contacts/018e1234-abcd-7000-8000-000000000001
Content-Type: application/json

{
"phone": "+1-555-111-2222",
"tags": ["customer", "enterprise", "vip"]
}

All fields are optional. Only provided fields are updated.


Delete a Contact

DELETE /api/contacts/018e1234-abcd-7000-8000-000000000001

Response: 204 No Content

Contacts with associated orders or invoices cannot be deleted — archive them instead by setting "archived": true via PATCH.


Merge Contacts

Merge a duplicate contact into a primary contact. The duplicate is deleted and all its related records (orders, invoices, activities) are reassigned to the primary.

POST /api/contacts/merge
Content-Type: application/json

{
"primaryId": "018e1234-abcd-7000-8000-000000000001",
"duplicateId": "018e1234-abcd-7000-8000-000000000099"
}

Response:

{
"merged": true,
"primaryId": "018e1234-abcd-7000-8000-000000000001",
"deletedId": "018e1234-abcd-7000-8000-000000000099",
"reassignedRecords": {
"orders": 3,
"invoices": 5,
"activities": 12
}
}

Bulk Import

Import contacts from a CSV payload. Rows with validation errors are skipped and reported.

POST /api/contacts/import
Content-Type: application/json

{
"contacts": [
{ "name": "Alpha Corp", "email": "[email protected]", "type": "company" },
{ "name": "Jane Doe", "email": "[email protected]", "type": "person" }
]
}

Response:

{
"imported": 2,
"skipped": 0,
"errors": []
}

Activity Timeline

GET /api/contacts/018e1234-abcd-7000-8000-000000000001/activity?limit=20

Returns a chronological list of all events linked to this contact (orders created, invoices sent, emails, notes).


Status Codes

CodeScenario
200List or get succeeded
201Contact created
204Contact deleted
404Contact ID not found in your organization
409Email already exists for another contact
422Validation failure (e.g., invalid email format)