Developer Docs
The Meisa API
Integrate with an AI assistant
Paste this into Claude, Cursor, or ChatGPT and let it write your integration.
You are integrating my app with Meisa, a behavioral lifecycle email API for SaaS.
Read the full machine-readable spec first: https://meisa.io/llms-full.txt
Core model: my app syncs each user's CURRENT STATE to Meisa, and Meisa automations
(configured in the dashboard) react to changes. My code only needs two endpoints:
1. POST /contacts/upsert/ — push user state (signup, login, plan change, churn)
2. POST /emails/trigger/ — send transactional email (OTP, receipts, invites)
Base URL: https://api.meisa.io/api/v1
Auth: header "X-API-Key: meisa_live_..." on every request. JSON bodies.
Endpoints (path | scope | key fields):
- POST /contacts/upsert/ | contacts:write | email (required), external_id, first_name, last_name, custom_fields (object, merged), tag_names (string[])
- POST /events/track/ | events:track | event_name (required), email|external_id (one required), properties
- POST /contacts/{id}/add_tag/ | contacts:write | tag_name OR tag_id
- POST /contacts/{id}/remove_tag/ | contacts:write | tag_name OR tag_id
- GET /contacts/api/unsubscribed-emails/ | contacts:read | returns {as_of,count,emails[]} to suppress locally
- POST /sequences/enroll/ | sequences:enroll | email (required), sequence_slug (required, active)
- GET /sequences/api/list/ | sequences:read | lists active sequences + slugs
- POST /emails/trigger/ | emails:trigger | trigger_key (required, configured in dashboard), to_email (required), variables, recipient, idempotency_key
- GET /ping/ | (any key) | verify the key works
Map my needs like this:
- transactional/OTP/password-reset/receipt email -> POST /emails/trigger/ with a trigger_key
- start onboarding on signup -> upsert the user; a Meisa automation enrolls them
- tag/segment users by plan/churn/upgrade -> upsert the changed fields; automations tag them
- react to an in-product action -> POST /events/track/ with an event_name
- avoid emailing unsubscribed/bounced -> poll the unsubscribed-emails endpoint and suppress locally
Do NOT use these (they are not in the API): broadcasts/campaigns (dashboard only),
creating templates/triggers/sequences/automations (dashboard only), outbound webhooks.
Now: implement a small, reusable Meisa client for my stack, plus an upsert call on signup/login/
plan-change and an emails/trigger call for my transactional emails. Read my codebase, infer the
right fields for custom_fields from my user model, and add error handling (retry 5xx, not 4xx).The core idea
You don't script email logic in your codebase. You sync state, and Meisa reacts. When you upsert a contact and a field changes (say plan goes from free to pro), the automations your team configured in Meisa run automatically: tags get added, sequences get enrolled, emails go out. Your code stays tiny and stable.
The two endpoints you'll actually use
POST /contacts/upsert/ to push user state, and POST /emails/trigger/ to send transactional email. Everything else is optional.
A complete integration, in two calls
Sync a user when they sign up or their state changes:
curl -X POST "https://api.meisa.io/api/v1/contacts/upsert/" \
-H "X-API-Key: meisa_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"external_id": "usr_12345",
"first_name": "Sarah",
"custom_fields": { "plan": "pro", "signin_count": 27 }
}'Send a transactional email by referencing a trigger you configured in the dashboard:
curl -X POST "https://api.meisa.io/api/v1/emails/trigger/" \
-H "X-API-Key: meisa_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"trigger_key": "verification_code",
"to_email": "[email protected]",
"variables": { "name": "Sarah", "code": "294817" }
}'Explore
Contacts
Sync each user's current state with one upsert call. Email is the key; custom_fields holds your product data.
Events
Record in-product actions. Any event you send can trigger a Meisa automation.
Tags
Add or remove tags. Usually handled for you by automations reacting to synced fields.
Sequences
Enroll contacts in multi-step lifecycle journeys, or let automations enroll them.
Triggered emails
Fire transactional email (OTP, receipts, invites) by referencing a dashboard trigger.
Not part of the API
Broadcasts (one-time campaigns) are managed by humans in the Meisa dashboard, or driven by AI through the Meisa MCP server. There is no broadcasts endpoint for API keys, and outbound webhooks are not currently offered. Stick to the endpoints documented here.