Contacts API
API reference for managing contact lists, contacts, CSV imports, and bulk sending in Taifa Mail.
Base URL: https://govconnect.ke/v1
All endpoints require authentication via API Key or JWT cookie. API keys use the tfm_k_ prefix.
Create a contact list
Creates a new contact list for organising your recipients.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the contact list. |
description | string | No | Description of the list's purpose. |
icon_seed | string | No | Seed string used to generate a unique list icon in the dashboard. |
Response (201 Created):
List contact lists
Returns all contact lists for the authenticated workspace as a JSON array.
Response:
Get a contact list
Returns a contact list with its contacts, paginated.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 0 | Page number (zero-indexed). |
limit | integer | 50 | Contacts per page (1-200). |
Response:
Update a contact list
Updates a contact list's name, description, or icon seed. Only include the fields you want to change.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | New name for the list. |
description | string | No | New description. |
icon_seed | string | No | New icon seed. |
cURL
Python
Node.js
Delete a contact list
Permanently deletes a contact list and all its contacts.
Response (204 No Content):
No response body.
Deleting a contact list permanently removes all contacts in the list. This action cannot be undone.
Add a contact to a list
Adds a single contact to a list.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
email | string (email) | Yes | Contact email address. |
name | string | No | Contact name. |
metadata | object | No | Arbitrary key-value pairs for segmentation and template variables. |
Response (201 Created):
cURL
Python
Node.js
Remove a contact from a list
Removes a single contact from a list.
Response (204 No Content):
No response body.
Upload contacts via CSV
Imports contacts from a CSV file. The endpoint auto-detects the email column and deduplicates contacts within the list.
Request: multipart/form-data with a file field.
The CSV file should have headers in the first row. The endpoint looks for a column named email (case-insensitive). Additional columns are stored as contact metadata.
Example CSV:
cURL
Python
Node.js
Response:
Duplicate contacts (same email within the list) are skipped, not rejected. The skipped count includes both duplicates and rows with missing email values.
Export contacts as CSV
Streams the contact list as a downloadable CSV file
(Content-Type: text/csv, Content-Disposition: attachment). The
columns are email, name, then one column per distinct custom-field
key found across the contacts' metadata.
Bulk send to a contact list
Sends an email to all contacts in a list. Supports template variables that are replaced per contact.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
contact_list_id | UUID | Yes | The contact list to send to. |
mailbox_id | UUID | Yes | The allocated mailbox to send from. Must be active and on a verified domain. |
subject | string | Yes | Email subject line. Supports template variables. |
html | string | No | HTML body. Supports template variables. |
text | string | No | Plain-text body. Supports template variables. At least one of html or text is required. |
tags | string[] | No | Tags for filtering in logs and analytics. |
Template variables
Use {{variable}} syntax in the subject, HTML body, and text body. The following variables are available per contact:
| Variable | Source |
|---|---|
{{email}} | Contact's email address. |
{{name}} | Contact's name. Falls back to empty string if not set. |
{{metadata_key}} | Any key from the contact's metadata object (e.g. {{city}}, {{department}}). |
cURL
Python
Node.js
Response:
Contacts without a valid email address and contacts that have previously bounced or unsubscribed are automatically skipped.
Errors
| Status | Description |
|---|---|
400 Bad Request | The uploaded CSV is empty, has no data rows, or has no detectable email column; or contact_list_id in a bulk-send body does not match the URL; or the contact list is empty. |
401 Unauthorized | Missing or invalid authentication. |
404 Not Found | The contact list, contact, or mailbox does not exist or is not visible to your workspace. |
409 Conflict | A contact with this email already exists in the list. |
422 Unprocessable Entity | Request body validation failed. |