Contacts API
This content is not available in your language yet.
Manage customer contact records and their associated companies.
Contacts
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /contacts | List contacts |
| POST | /contacts | Create contact |
| GET | /contacts/:id | Get contact |
| PATCH | /contacts/:id | Update contact |
| DELETE | /contacts/:id | Delete contact |
List Contacts
GET /api/v1/contactsQuery Parameters
| Parameter | Type | Description |
|---|---|---|
search | string | Search name or email |
company_id | uuid | Filter by company |
page | integer | Page number |
per_page | integer | Items per page |
Response
{ "data": [ { "id": "contact-uuid", "name": "John Doe", "email": "john@example.com", "phone": "+1234567890", "company": { "id": "company-uuid", "name": "Acme Corp" }, "ticket_count": 12, "created_at": "2024-01-10T09:00:00Z" } ], "meta": { "total": 250, "page": 1, "per_page": 20 }}Create Contact
POST /api/v1/contacts{ "name": "John Doe", "email": "john@example.com", "phone": "+1234567890", "company_id": "company-uuid", "notes": "VIP customer, handle with care"}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Contact name |
email | string | Yes | Email address (unique) |
phone | string | No | Phone number |
company_id | uuid | No | Associated company |
notes | string | No | Internal notes |
Get Contact
GET /api/v1/contacts/:idReturns contact with recent tickets:
{ "data": { "id": "contact-uuid", "name": "John Doe", "email": "john@example.com", "phone": "+1234567890", "company": { ... }, "notes": "VIP customer", "recent_tickets": [ { "id": "...", "code": "ACME-42", "subject": "..." } ], "total_tickets": 12, "created_at": "2024-01-10T09:00:00Z", "updated_at": "2024-01-15T14:30:00Z" }}Update Contact
PATCH /api/v1/contacts/:id{ "name": "John Smith", "phone": "+1987654321"}Delete Contact
DELETE /api/v1/contacts/:idCompanies
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /companies | List companies |
| POST | /companies | Create company |
| GET | /companies/:id | Get company |
| PATCH | /companies/:id | Update company |
| DELETE | /companies/:id | Delete company |
List Companies
GET /api/v1/companiesResponse
{ "data": [ { "id": "company-uuid", "name": "Acme Corp", "domains": ["acme.com", "acme.co.uk"], "hourly_rate": 150.00, "currency": "USD", "contact_count": 5, "ticket_count": 42 } ]}Create Company
POST /api/v1/companies{ "name": "Acme Corp", "domains": ["acme.com"], "hourly_rate": 150.00, "currency": "USD", "ticket_prefix": "ACME", "notes": "Enterprise customer since 2020"}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Company name |
domains | string[] | No | Email domains for auto-linking |
hourly_rate | decimal | No | Billing rate |
currency | string | No | USD, EUR, GBP, etc. |
ticket_prefix | string | No | Override default prefix |
notes | string | No | Internal notes |
Domain Auto-Linking
When you set domains on a company:
- New contacts with matching email domains are auto-linked
- Existing contacts can be batch-updated
{ "domains": ["acme.com", "acme.co.uk", "acme.eu"]}Any contact with @acme.com, @acme.co.uk, or @acme.eu email will be linked.
Get Company
GET /api/v1/companies/:idReturns company with contacts and recent tickets:
{ "data": { "id": "company-uuid", "name": "Acme Corp", "domains": ["acme.com"], "hourly_rate": 150.00, "currency": "USD", "ticket_prefix": "ACME", "contacts": [ { "id": "...", "name": "John Doe", "email": "john@acme.com" } ], "recent_tickets": [ ... ], "total_tickets": 42, "total_time_minutes": 1250 }}Update Company
PATCH /api/v1/companies/:id{ "hourly_rate": 175.00, "domains": ["acme.com", "acme.io"]}Delete Company
DELETE /api/v1/companies/:idContacts remain but are unlinked from the company.
Error Codes
| Code | Description |
|---|---|
CONTACT_NOT_FOUND | Contact doesn’t exist |
COMPANY_NOT_FOUND | Company doesn’t exist |
EMAIL_ALREADY_EXISTS | Email address is already used |
INVALID_EMAIL | Email format is invalid |
INVALID_DOMAIN | Domain format is invalid |