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.
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. |
sender_address_id | UUID | Yes | The sender address to use. 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}}, {{plan}}). |
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. |
403 Forbidden | A plan limit was reached (contact lists, contacts per list). |
404 Not Found | The contact list, contact, or sender address 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. |