Contacts
Manage contacts, segments, and bulk import via CSV/JSON
Contacts
Contacts are the recipients in your email lists. Each contact belongs to the authenticated user and is isolated from other users' contacts.
Endpoints
| Method | Path | Description |
|--------|------|-------------|
| GET | /api/v1/contacts | List contacts (paginated) |
| POST | /api/v1/contacts | Create a contact |
| PATCH | /api/v1/contacts/:id | Update a contact |
| DELETE | /api/v1/contacts/:id | Delete a contact |
| POST | /api/v1/contacts/import | Bulk import from CSV or JSON |
Auth: API key with contacts scope.
GET /api/v1/contacts
List contacts with optional filtering and pagination.
Query Parameters
| Param | Type | Default | Description |
|-------|------|---------|-------------|
| page | integer | 1 | Page number |
| limit | integer | 50 | Results per page (max 100) |
| status | string | — | Filter: subscribed, unsubscribed, bounced, complained |
| segment_id | UUID | — | Filter by segment membership |
| search | string | — | Search by email or name |
Response
{
"success": true,
"contacts": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"status": "subscribed",
"tags": ["customer", "vip"],
"customFields": { "plan": "pro" },
"created_at": "2026-01-15T10:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 1234,
"total_pages": 25
}
}
POST /api/v1/contacts
Create a single contact. Plan limits apply.
Request Body
{
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"phone": "+1234567890",
"tags": ["customer"],
"customFields": { "plan": "pro", "signup_source": "website" },
"status": "subscribed"
}
| Field | Type | Required | Notes |
|-------|------|----------|-------|
| email | string | ✓ | Must be valid email |
| firstName | string | — | |
| lastName | string | — | |
| phone | string | — | |
| tags | string[] | — | Up to 50 tags |
| customFields | object | — | Custom key-value data |
| status | string | — | subscribed (default), unsubscribed, bounced, complained |
Response
{
"success": true,
"contact": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]"
}
}
Errors
403— Contact limit reached for your plan409— Email already exists in your contacts
PATCH /api/v1/contacts/:id
Update a contact. Only provided fields are updated.
Request Body
{
"firstName": "Jane",
"tags": ["customer", "vip"],
"status": "unsubscribed"
}
DELETE /api/v1/contacts/:id
Permanently delete a contact. This also removes them from all segments.
Response
{ "success": true }
POST /api/v1/contacts/import
Bulk import contacts from CSV or JSON. Available on Pro plan and above.
Request (JSON)
{
"contacts": [
{ "email": "[email protected]", "firstName": "Alice", "tags": ["newsletter"] },
{ "email": "[email protected]", "firstName": "Bob" }
],
"update_existing": true
}
Request (CSV)
Send Content-Type: text/csv with a CSV body:
email,firstName,lastName,tags
[email protected],Alice,Smith,newsletter
[email protected],Bob,Jones,
Response
{
"success": true,
"imported": 1842,
"updated": 143,
"skipped": 15,
"errors": [
{ "row": 3, "email": "invalid-email", "error": "Invalid email format" }
]
}
Errors
403— Bulk import not available on Free plan403— Contact limit would be exceeded by this import400— Invalid CSV format or missingemailcolumn