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": "billing@acme.com",
"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": "hello@globex.com",
"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": "alpha@example.com", "type": "company" },
{ "name": "Jane Doe", "email": "jane@example.com", "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)