Taifa MailTaifa Mail Docs
API Reference

Emails API

Complete API reference for sending, listing, searching, scheduling, and retrying emails in Taifa Mail.

Base URL: https://govconnect.ke/v1

All endpoints require authentication via API Key or JWT cookie. API keys are passed as Authorization: Bearer tfm_k_....

Using an official SDK? The emails resource wraps every endpoint below. Guides: TypeScript, Python, Go, PHP, Ruby, Rust, Java, .NET, Swift.


Send an email

POST /v1/emails/

Send a single email. Returns 202 Accepted; the email is queued for delivery.

Request body:

{
  "from_": {
    "email": "hello@yourdomain.com",
    "name": "Your Company"
  },
  "to": [
    { "email": "recipient@example.com", "name": "Jane Doe" }
  ],
  "subject": "Welcome aboard",
  "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
  "text": "Welcome! Thanks for signing up.",
  "cc": [{ "email": "cc@example.com" }],
  "bcc": [{ "email": "bcc@example.com" }],
  "reply_to": { "email": "support@yourdomain.com" },
  "headers": { "X-Custom-Header": "value" },
  "tags": ["onboarding"],
  "send_at": "2026-06-01T09:00:00Z"
}
FieldTypeRequiredDescription
from_objectYesSender address object with email and optional name.
from_.emailstringYesSender email address. Must be a registered sender on a verified domain.
from_.namestringNoSender display name.
toarrayYesArray of recipient objects. At least one required.
to[].emailstringYesRecipient email address.
to[].namestringNoRecipient display name.
subjectstringYesEmail subject line.
htmlstringNoHTML body. At least one of html or text is required.
textstringNoPlain-text body.
ccarrayNoArray of CC recipient objects.
bccarrayNoArray of BCC recipient objects.
reply_toobjectNoReply-to address object with email and optional name.
headersobjectNoCustom email headers as a string-to-string map.
tagsstring[]NoTags for filtering in logs and analytics.
send_atstring (ISO 8601)NoSchedule for future delivery. Must be 1 minute to 30 days in the future. Starter plan and above only.
attachmentsarrayNoFile attachments. See below.

Attachment fields:

{
  "attachments": [
    {
      "filename": "invoice.pdf",
      "content_base64": "JVBERi0xLjQ...",
      "content_type": "application/pdf"
    }
  ]
}
FieldTypeRequiredDescription
filenamestringYesFile name. Must not contain path separators.
content_base64stringYesFile body as base64 (no data: prefix).
content_typestringNoMIME type. Defaults to application/octet-stream.

Per-file and combined attachment size are both capped at 24 MiB.

Response (202 Accepted):

{
  "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "status": "queued",
  "message_id": "<uuid@govconnect.ke>",
  "rejection_reason": null
}
curl -X POST https://govconnect.ke/v1/emails/ \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from_": {"email": "hello@yourdomain.com", "name": "Your Company"},
    "to": [{"email": "recipient@example.com"}],
    "subject": "Welcome aboard",
    "html": "<h1>Welcome!</h1>"
  }'

Send batch emails

POST /v1/emails/batch

Send multiple emails in a single request. Requires the Starter plan or above. The request body is a JSON array of email objects, each using the same shape as the single send body.

PlanMax emails per batch
FreeNot available
Starter25
Pro50
Business100

Batch sending requires the Starter plan or above. Free plan accounts receive a 403 error.

Response (202 Accepted):

{
  "total": 2,
  "sent": 2,
  "failed": 0,
  "results": [
    { "id": "a1b2c3d4-...", "status": "queued", "rejection_reason": null },
    { "id": "b2c3d4e5-...", "status": "queued", "rejection_reason": null }
  ]
}

Each email is processed independently. A failed email has "id": null, "status": "error", and a rejection_reason.


List emails

GET /v1/emails/

Returns an array of emails, newest first.

Query parameters:

ParameterTypeDefaultDescription
statusstring--Filter by status.
pageinteger0Zero-based page number.
limitinteger20Results per page (1-100).
curl "https://govconnect.ke/v1/emails/?status=delivered&limit=10" \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY"

Response:

[
  {
    "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
    "from_address": "Your Company <hello@yourdomain.com>",
    "to_addresses": ["recipient@example.com"],
    "subject": "Welcome aboard",
    "status": "delivered",
    "source": "api",
    "opened_count": 1,
    "clicked_count": 0,
    "tags": ["onboarding"],
    "scheduled_at": null,
    "created_at": "2026-04-06T10:00:00Z",
    "sent_at": "2026-04-06T10:00:01Z",
    "delivered_at": "2026-04-06T10:00:03Z",
    "retry_of_id": null
  }
]

Get email updates

GET /v1/emails/updates

Returns up to 50 emails created or updated after a given timestamp. Useful for polling live status changes.

Query parameters:

ParameterTypeRequiredDescription
sincestring (ISO 8601)YesReturn emails updated after this timestamp.
curl "https://govconnect.ke/v1/emails/updates?since=2026-04-06T10:00:00Z" \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY"

Response shape matches List emails.


Search emails

GET /v1/emails/search

Search emails by recipient, sender, subject, status, or tags.

Query parameters:

ParameterTypeDefaultDescription
qstring""Free-text query. Supports inline tokens (see below).
statusstring--Filter by status.
tagstring--Filter by an exact tag.
pageinteger0Zero-based page number.
limitinteger20Results per page (1-100).

The q parameter accepts inline tokens that map to structured filters: to:gmail.com, from:hello@govconnect.ke, status:bounced, domain:govconnect.ke, tag:welcome. Any remaining words are matched as free text across sender, subject, and recipients.

curl "https://govconnect.ke/v1/emails/search?q=welcome+status:delivered" \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY"

Response: an array of email objects with id, from_address, to_addresses, subject, status, tags, source, created_at, and delivered_at.


List scheduled emails

GET /v1/emails/scheduled

Returns all emails scheduled for future delivery that have not yet been sent.

curl https://govconnect.ke/v1/emails/scheduled \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY"

Response:

[
  {
    "id": "b2c3d4e5-6789-01bc-defg-2345678901bc",
    "from_address": "Your Company <hello@yourdomain.com>",
    "to_addresses": ["recipient@example.com"],
    "subject": "Reminder",
    "status": "scheduled",
    "tags": null,
    "scheduled_at": "2026-06-01T09:00:00Z",
    "seconds_until_send": 432000,
    "created_at": "2026-04-06T10:00:00Z"
  }
]

Cancel a scheduled email

DELETE /v1/emails/scheduled/{email_id}

Cancels a scheduled email before it sends. Returns 404 if the email is not scheduled.

curl -X DELETE https://govconnect.ke/v1/emails/scheduled/b2c3d4e5-... \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY"

Response (200 OK):

{ "id": "b2c3d4e5-...", "status": "cancelled" }

Send a scheduled email now

POST /v1/emails/scheduled/{email_id}/send-now

Dispatches a scheduled email immediately instead of waiting for scheduled_at.

curl -X POST https://govconnect.ke/v1/emails/scheduled/b2c3d4e5-.../send-now \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY"

Response (200 OK):

{ "id": "b2c3d4e5-...", "status": "queued" }

Validate an email (dry run)

POST /v1/emails/validate

Checks whether an email would send without actually sending it. Validates the sender address, domain verification, plan limits, and account restrictions. The request body uses the same shape as Send an email.

curl -X POST https://govconnect.ke/v1/emails/validate \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from_": {"email": "hello@yourdomain.com"},
    "to": [{"email": "recipient@example.com"}],
    "subject": "Test",
    "html": "<p>Test</p>"
  }'

Response (200 OK):

{
  "valid": true,
  "can_send": true,
  "issues": [],
  "plan": "starter",
  "usage": {
    "daily": 12,
    "daily_limit": 200,
    "monthly": 340,
    "monthly_limit": 5000
  }
}

When validation fails, valid and can_send are false and issues lists the problems. Each issue is { "field": "...", "error": "..." }. The field is one of account, from, limits, to, or content.

Use the validate endpoint in your CI/CD pipeline to catch sender or configuration errors before they reach production.


Get email detail

GET /v1/emails/{email_id}

Returns full details for a single email, including the body, headers, and event timeline.

curl https://govconnect.ke/v1/emails/a1b2c3d4-... \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY"

Response:

{
  "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "from_address": "Your Company <hello@yourdomain.com>",
  "to_addresses": ["recipient@example.com"],
  "subject": "Welcome aboard",
  "status": "delivered",
  "source": "api",
  "opened_count": 1,
  "clicked_count": 0,
  "tags": ["onboarding"],
  "scheduled_at": null,
  "created_at": "2026-04-06T10:00:00Z",
  "sent_at": "2026-04-06T10:00:01Z",
  "delivered_at": "2026-04-06T10:00:03Z",
  "retry_of_id": null,
  "cc_addresses": null,
  "bcc_addresses": null,
  "text_body": "Welcome! Thanks for signing up.",
  "html_body": "<h1>Welcome!</h1>",
  "headers": {},
  "message_id": "<uuid@govconnect.ke>",
  "events": []
}

Retry an email

POST /v1/emails/{email_id}/retry

Resends a previously failed email. Only emails with status bounced, rejected, or failed can be retried; any other status returns 409 Conflict. A new email row is created, linked to the original via retry_of_id.

curl -X POST https://govconnect.ke/v1/emails/a1b2c3d4-.../retry \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY"

Response (202 Accepted):

{
  "id": "c3d4e5f6-...",
  "status": "queued",
  "message_id": "<uuid@govconnect.ke>",
  "rejection_reason": null
}

Get email events

GET /v1/emails/{email_id}/events

Returns the event timeline for a specific email.

curl https://govconnect.ke/v1/emails/a1b2c3d4-.../events \
  -H "Authorization: Bearer tfm_k_YOUR_API_KEY"

Response:

[
  {
    "id": "e1f2a3b4-...",
    "event_type": "queued",
    "metadata": null,
    "created_at": "2026-04-06T10:00:00Z"
  },
  {
    "id": "e2f3a4b5-...",
    "event_type": "delivered",
    "metadata": { "relay": "mx.example.com", "dsn": "2.0.0" },
    "created_at": "2026-04-06T10:00:03Z"
  }
]

Saved searches

Named filter sets for the email log, stored per user.

List saved searches

GET /v1/emails/saved-searches

Returns { "searches": [...] }.

Replace saved searches

PUT /v1/emails/saved-searches

Replaces the entire saved-search list. Body: { "searches": [...] }, capped at 50 entries. Each entry supports id, name, query, range, status, domain, and source fields.

On this page