For Coding Agents
Give your AI coding agent this page and it will have everything it needs to build TopMail integrations.
Share this link with your coding agent
Paste this URL into your conversation with Claude, Codex, Gemini, or any AI coding assistant. The agent will read this page and have full context to write TopMail API calls, handle errors, and build multi-step workflows autonomously.
https://api.topmail.so/developers/coding-agentsThat's it. No configuration files, no copy-pasting blocks. Your agent reads the page and does the rest.
API Reference
Complete reference for all TopMail API resources. This is the context your coding agent uses when it reads this page.
# TopMail API Reference
## Base URL
https://api.topmail.so/api/v1
## OpenAPI Spec
https://api.topmail.so/openapi.yaml
## Authentication
All requests require a Bearer token:
Authorization: Bearer tm_live_<your_api_key>
Sandbox/test keys use prefix: tm_test_<key> (skips real email sending, returns mock results)
## TypeScript SDK
npm install @topmail/sdk
import { TopMail } from '@topmail/sdk';
const topmail = new TopMail('tm_live_<your_api_key>');
## Resources
### Contacts
- GET /contacts — List contacts (search, subscribed, limit, offset)
- POST /contacts — Create contact (email*, first_name, last_name, attributes, subscribed, list_id)
- GET /contacts/:id — Get contact with list memberships
- PATCH /contacts/:id — Update contact (partial update, attributes merge)
- DELETE /contacts/:id — Delete contact
Example response (GET /contacts/:id):
{
"data": {
"id": "uuid",
"email": "user@example.com",
"first_name": "Jane",
"last_name": "Doe",
"attributes": { "plan": "pro", "company": "Acme" },
"subscribed": true,
"created_at": "2025-01-15T10:30:00.000Z",
"lists": [{ "id": "uuid", "name": "Newsletter" }]
}
}
### Lists
- GET /lists — List all lists (type, limit, offset)
- POST /lists — Create list (name*, description, type, conditions)
- GET /lists/:id — Get list with member count
- PATCH /lists/:id — Update list
- DELETE /lists/:id — Delete list (members preserved)
- GET /lists/:id/members — List members (limit, offset)
- POST /lists/:id/members — Add members { contact_ids: ["uuid", ...] }
- DELETE /lists/:id/members — Remove members { contact_ids: ["uuid", ...] }
### Segments
- GET /segments — List segments (search, limit, offset)
- POST /segments — Create segment (name*, conditions)
- GET /segments/:id — Get segment
- PATCH /segments/:id — Update segment
- DELETE /segments/:id — Delete segment
- POST /segments/:id/estimate — Estimate matching contacts count
- GET /segments/:id/contacts — List matching contacts (limit, offset)
Example: Create segment with conditions:
POST /segments { "name": "Active Buyers", "conditions": { "match": "all", "rules": [{ "field": "subscribed", "operator": "equals", "value": true }] } }
### Tags
- GET /tags — List tags with contact_count (search, limit, offset)
- POST /tags — Create tag (name*, color, description)
- GET /tags/:id — Get tag
- PATCH /tags/:id — Update tag
- DELETE /tags/:id — Delete tag (cascade removes assignments)
- GET /tags/:id/contacts — List tagged contacts
- POST /tags/:id/contacts — Assign tag { contact_ids: ["uuid", ...] }
- DELETE /tags/:id/contacts — Remove tag { contact_ids: ["uuid", ...] }
### Automations
- GET /automations — List automations (status, limit, offset)
- GET /automations/:id — Get automation with steps and run stats
- PATCH /automations/:id — Update name/status (draft→active, active↔paused)
- POST /automations/:id/trigger — Trigger for contact (contact_id or email, trigger_data)
- GET /automations/:id/runs — List runs (status filter: active|completed|failed|paused, limit, offset)
### Campaigns (read-only)
- GET /campaigns — List campaigns (status, limit, offset)
- GET /campaigns/:id — Get campaign with stats and rates
### Templates (read-only)
- GET /templates — List templates
- GET /templates/:id — Get template with HTML content
### Email
- POST /email/send — Send transactional email (to*, subject*, html*, from, reply_to, tags)
- POST /email/batch — Send batch emails (messages[])
- GET /email/:messageId — Get delivery status
Example: Send email:
POST /email/send { "to": "user@example.com", "subject": "Welcome!", "html": "<h1>Hello</h1>", "from": "hi@yourdomain.com" }
### Suppressions
- GET /suppressions — List suppressed emails (limit, offset)
- POST /suppressions — Add to suppression list (email*, reason)
- DELETE /suppressions — Remove from suppression list (email*)
### Webhooks
- POST /webhooks — Subscribe (url*, events[])
- DELETE /webhooks/:id — Unsubscribe
- POST /webhooks/:id/test — Send test event
Webhook event types: email.sent, email.delivered, email.bounced, email.complained, email.opened, email.clicked, contact.subscribed, contact.unsubscribed
### Tracking
- POST /track/product-view — Track product view (contact_email*, product_id*, product data)
### Conversions
- GET /conversions — List conversions (limit, offset)
- POST /conversions — Create conversion (contact_id*, value*, currency, metadata)
### Health
- GET /health — API health check (no auth required)
## Response Format
Single resource: { "data": { ... } }
List resource: { "data": [...], "pagination": { "total": 150, "limit": 100, "offset": 0, "has_more": true } }
## Error Format
{ "error": { "code": "error_code", "message": "Human-readable message" } }
Common codes: validation_error (400), unauthorized (401), not_found (404), conflict (409), rate_limit_exceeded (429), internal_error (500)
## Pagination
Use limit (default: 100, max: 1000) and offset (default: 0) query parameters.
## Idempotency
POST /email/send and /email/batch support Idempotency-Key header to prevent duplicate sends.
## SDK Methods Quick Reference
topmail.contacts.list/get/create/update/delete
topmail.lists.list/get/create/update/delete + topmail.lists.members.add/remove/list
topmail.segments.list/get/create/update/delete/estimateCount/listContacts
topmail.tags.list/get/create/update/delete + topmail.tags.contacts.assign/remove
topmail.automations.list/get/update/activate/pause/trigger/listRuns
topmail.campaigns.list/get
topmail.templates.list/get
topmail.email.send/sendBatch/getStatus
topmail.suppressions.list/add/remove
topmail.webhooks.create/delete/testExample Workflows
Here are multi-step workflows your coding agent can build using the TopMail SDK.
Create a segment and estimate audience
# Step 1: Create a segmentcurl -X POST https://api.topmail.so/api/v1/segments \-H "Authorization: Bearer tm_live_abc123" \-H "Content-Type: application/json" \-d '{"name": "Active Buyers","conditions": {"match": "all","rules": [{"field": "revenue_potential_score", "operator": "gte", "value": 60},{"field": "subscribed", "operator": "equals", "value": true}]}}'# Step 2: Estimate the audience sizecurl -X POST https://api.topmail.so/api/v1/segments/SEGMENT_ID/estimate \-H "Authorization: Bearer tm_live_abc123"
Tag contacts and trigger an automation
# Step 1: Create a tagcurl -X POST https://api.topmail.so/api/v1/tags \-H "Authorization: Bearer tm_live_abc123" \-H "Content-Type: application/json" \-d '{"name": "Upgrade Candidate", "color": "#f59e0b"}'# Step 2: Assign the tag to contactscurl -X POST https://api.topmail.so/api/v1/tags/TAG_ID/contacts \-H "Authorization: Bearer tm_live_abc123" \-H "Content-Type: application/json" \-d '{"contact_ids": ["CONTACT_ID_1", "CONTACT_ID_2"]}'# Step 3: Trigger an automation for each contactcurl -X POST https://api.topmail.so/api/v1/automations/AUTOMATION_ID/trigger \-H "Authorization: Bearer tm_live_abc123" \-H "Content-Type: application/json" \-d '{"contact_id": "CONTACT_ID_1", "trigger_data": {"reason": "upgrade_candidate"}}'
Using the SDK
We recommend using the official TypeScript SDK for agent integrations. It provides full type safety, built-in error handling, and pagination helpers that make it easier for your coding agent to write correct API calls on the first try.
View SDK Documentation