Engage

Email campaigns

Templates with merge tags and AI lines, one-off and scheduled campaigns, recurring mailings to lists, previews, tests and real open / click / reply tracking.

Emails leave from your own connected mailboxes (Gmail, Outlook, IMAP), never from a shared server. Opens are filtered — security scanners, Apple Mail privacy pre-loads and your own views don’t count, and a reply always counts as a read. Every send fires email.sent, email.opened, email.clicked or email.failed for workflows and webhooks.

In a chat
Copy a ready promptPaste it in any AI: it reads the docs and follows the rules of the API.
Open in Claude or ChatGPTA new conversation with the prompt already written.
This page as MarkdownFor an AI that cannot open links: paste the text itself.
In your editor
Claude Code or CodexAdd this line to CLAUDE.md or AGENTS.md.Meetzy API reference (read before calling the API): https://www.meetzy.ai/llms-full.txt
CursorSettings › Indexing & Docs › Add Doc, then type @Meetzy in the chat.https://www.meetzy.ai/llms-full.txt
Connect Meetzy as tools (MCP)The AI can then read and change your CRM itself — Claude Code:claude mcp add --transport http meetzy https://meetzy.me/api/mcp/mcp
Same for Codexcodex mcp add meetzy --url https://meetzy.me/api/mcp/mcp
GET/email/mailbox

Sending mailbox status

Whether a mailbox is connected, which address emails go out from, and every connected mailbox. Connecting a mailbox is done in the app (it needs the provider’s sign-in).

Scope: read
Request
curl "https://meetzy.me/api/v1/email/mailbox" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/mailbox", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/email/mailbox",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "connected": false,
  "sending_as": null,
  "mode": "personal",
  "mailboxes": [],
  "all": []
}
GET/email/mailboxes

Team mailboxes

Every mailbox of the team, who owns it, whether it is disconnected, and the sending mode: personal (each person sends from their own) or shared (everyone sends from the team mailbox).

Scope: read
Request
curl "https://meetzy.me/api/v1/email/mailboxes" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/mailboxes", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/email/mailboxes",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "mode": "personal",
  "team_mailbox_id": null,
  "settings_stored": true,
  "can_manage": true,
  "sending_as": null,
  "mailboxes": [],
  "members": [
    {
      "email": "olivia@acme.com",
      "name": "Olivia Martin",
      "memoji": null,
      "sends_from": null,
      "via": null
    }
  ]
}
PUT/email/mailboxes/settings

Choose how the team sends

Workspace owner only.

Scope: write

Body

modestringrequired
personal or shared.
team_mailbox_iduuid
The shared mailbox (one of GET /email/mailboxes).

Returns the same answer as GET /email/mailboxes, with the new mode.

Request
curl -X PUT "https://meetzy.me/api/v1/email/mailboxes/settings" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "shared",
    "team_mailbox_id": "2b7d0a8e-1f3c-4c55-8e2a-9d0b6c4f1e77"
  }'
const res = await fetch("https://meetzy.me/api/v1/email/mailboxes/settings", {
  method: "PUT",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "mode": "shared",
    "team_mailbox_id": "2b7d0a8e-1f3c-4c55-8e2a-9d0b6c4f1e77"
  }),
});
const data = await res.json();
import os, requests

res = requests.put(
    "https://meetzy.me/api/v1/email/mailboxes/settings",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "mode": "shared",
        "team_mailbox_id": "2b7d0a8e-1f3c-4c55-8e2a-9d0b6c4f1e77"
    },
)
data = res.json()
Response200

See the notes on the left.

GET/email/overview

Email performance

Totals (sent, failed, opened, clicked, replied, unsubscribed, automatic opens filtered…) and a day-by-day series.

Scope: read

Query parameters

daysinteger
Window in days. Default 30.
Request
curl "https://meetzy.me/api/v1/email/overview?days=7" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/overview?days=7", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/email/overview?days=7",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "totals": {
    "total": 0,
    "queued": 0,
    "sent": 0,
    "failed": 0,
    "skipped": 0,
    "opened": 0,
    "clicked": 0,
    "replied": 0,
    "unsubscribed": 0,
    "auto_opened": 0,
    "bot_hits": 0,
    "open_rate": 0,
    "click_rate": 0,
    "reply_rate": 0
  },
  "series": [
    {
      "date": "2026-10-01",
      "sent": 0,
      "opened": 0,
      "clicked": 0,
      "replied": 0
    },
    {
      "date": "2026-10-02",
      "sent": 0,
      "opened": 0,
      "clicked": 0,
      "replied": 0
    }
  ],
  "from_workflows": 0,
  "ai_available": false
}
GET/email/templates

List templates

Scope: read
Request
curl "https://meetzy.me/api/v1/email/templates" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/templates", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/email/templates",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "templates": [
    {
      "id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
      "user_from": "acme",
      "name": "Intro",
      "category": null,
      "subject": "Hello {{contact.first_name}}",
      "preheader": null,
      "body": "Hi there",
      "ai_instructions": null,
      "usage_count": 0,
      "last_used_at": null,
      "created_by": "olivia@acme.com",
      "created_at": "2026-10-07T13:23:12.003361+00:00",
      "updated_at": "2026-10-07T13:23:12.003361+00:00"
    }
  ]
}
POST/email/templates

Create a template

Scope: write

Body

namestringrequired
Name.
categorystring
Category (free text).
subjectstring
Subject. Merge tags allowed ({{contact.first_name | there}}).
preheaderstring
Preview text shown after the subject in inboxes.
bodystring
Message — plain text or HTML, with merge tags and {{#if …}}…{{else}}…{{/if}} blocks. See merge tags.
ai_instructionsstring
What the AI should write in {{ai.line}} for each contact.
Request
curl -X POST "https://meetzy.me/api/v1/email/templates" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Intro",
    "subject": "Quick question, {{contact.first_name | there}}",
    "body": "Hi {{contact.first_name | there}},\n\n{{ai.line}}\n\nWorth a 15-minute call?\n\n{{owner.first_name}}",
    "ai_instructions": "One sentence about something recent at {{contact.company}}."
  }'
const res = await fetch("https://meetzy.me/api/v1/email/templates", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "name": "Intro",
    "subject": "Quick question, {{contact.first_name | there}}",
    "body": "Hi {{contact.first_name | there}},\n\n{{ai.line}}\n\nWorth a 15-minute call?\n\n{{owner.first_name}}",
    "ai_instructions": "One sentence about something recent at {{contact.company}}."
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/templates",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "name": "Intro",
        "subject": "Quick question, {{contact.first_name | there}}",
        "body": "Hi {{contact.first_name | there}},\n\n{{ai.line}}\n\nWorth a 15-minute call?\n\n{{owner.first_name}}",
        "ai_instructions": "One sentence about something recent at {{contact.company}}."
    },
)
data = res.json()
Response201
{
  "id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
  "user_from": "acme",
  "name": "Intro",
  "category": null,
  "subject": "Hello {{contact.first_name}}",
  "preheader": null,
  "body": "Hi there",
  "ai_instructions": null,
  "usage_count": 0,
  "last_used_at": null,
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:12.003361+00:00",
  "updated_at": "2026-10-07T13:23:12.003361+00:00"
}
POST/email/templates/install-starters

Install the starter templates

Adds Meetzy’s ready-made templates (intro, follow-up, break-up…) that you don’t have yet.

Scope: write
Request
curl -X POST "https://meetzy.me/api/v1/email/templates/install-starters" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/templates/install-starters", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/templates/install-starters",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response201
{
  "installed": 6
}
GET/email/templates/{id}

Get a template

Scope: read

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl "https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "template": {
    "id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
    "user_from": "acme",
    "name": "Intro",
    "category": null,
    "subject": "Hello {{contact.first_name}}",
    "preheader": null,
    "body": "Hi there",
    "ai_instructions": null,
    "usage_count": 0,
    "last_used_at": null,
    "created_by": "olivia@acme.com",
    "created_at": "2026-10-07T13:23:12.003361+00:00",
    "updated_at": "2026-10-07T13:23:12.003361+00:00"
  }
}
PATCH/email/templates/{id}

Update a template

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).

Body

namestring
Name.
categorystring
Category.
subjectstring
Subject. Merge tags allowed ({{contact.first_name | there}}).
preheaderstring
Preview text shown after the subject in inboxes.
bodystring
Message — plain text or HTML, with merge tags and {{#if …}}…{{else}}…{{/if}} blocks. See merge tags.
ai_instructionsstring
AI instructions.
Request
curl -X PATCH "https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Hi {{contact.first_name}}"
  }'
const res = await fetch("https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc", {
  method: "PATCH",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "subject": "Hi {{contact.first_name}}"
  }),
});
const data = await res.json();
import os, requests

res = requests.patch(
    "https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "subject": "Hi {{contact.first_name}}"
    },
)
data = res.json()
Response200
{
  "id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
  "user_from": "acme",
  "name": "Intro",
  "category": null,
  "subject": "Hi {{contact.first_name}}",
  "preheader": null,
  "body": "Hi there",
  "ai_instructions": null,
  "usage_count": 0,
  "last_used_at": null,
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:12.003361+00:00",
  "updated_at": "2026-10-07T13:23:13.463784+00:00"
}
DELETE/email/templates/{id}

Delete a template

Scope: delete

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X DELETE "https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.delete(
    "https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "deleted": true
}
POST/email/templates/{id}/duplicate

Duplicate a template

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X POST "https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc/duplicate" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc/duplicate", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/templates/e43414d6-f56f-42be-a64c-a836d6015efc/duplicate",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response201
{
  "id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
  "user_from": "acme",
  "name": "Intro (copy)",
  "category": null,
  "subject": "Hello {{contact.first_name}}",
  "preheader": null,
  "body": "Hi there",
  "ai_instructions": null,
  "usage_count": 0,
  "last_used_at": null,
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:12.003361+00:00",
  "updated_at": "2026-10-07T13:23:12.003361+00:00"
}
POST/email/preview

Preview an email for a contact

Renders subject and HTML with a real contact’s data — from a template, a campaign or the content you send. with_ai: true also writes the AI line (uses credits).

Scope: write

Body

contact_iduuid
Contact whose data fills the tags (default: a sample contact).
template_iduuid
Template to render.
campaign_iduuid
Campaign to render.
subjectstring
Subject. Merge tags allowed ({{contact.first_name | there}}).
preheaderstring
Preview text shown after the subject in inboxes.
bodystring
Message — plain text or HTML, with merge tags and {{#if …}}…{{else}}…{{/if}} blocks. See merge tags.
settingsobject
Campaign settings to apply (unsubscribe link, tracking…).
ai_instructionsstring
AI instructions.
with_aiboolean
Generate {{ai.line}}.
Request
curl -X POST "https://meetzy.me/api/v1/email/preview" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "8a1c2e3f-4b5d-4e6f-8a7b-9c0d1e2f3a4b",
    "contact_id": "e43414d6-f56f-42be-a64c-a836d6015efc"
  }'
const res = await fetch("https://meetzy.me/api/v1/email/preview", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "template_id": "8a1c2e3f-4b5d-4e6f-8a7b-9c0d1e2f3a4b",
    "contact_id": "e43414d6-f56f-42be-a64c-a836d6015efc"
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/preview",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "template_id": "8a1c2e3f-4b5d-4e6f-8a7b-9c0d1e2f3a4b",
        "contact_id": "e43414d6-f56f-42be-a64c-a836d6015efc"
    },
)
data = res.json()
Response201
{
  "subject": "Hi Camille",
  "html": "<p>Hi there</p><p style=\"margin:28px 0 0;font-size:11px;line-height:1.5;color:#9A9AA2\">You received this email from Olivia Martin. <a href=\"https://meetzy.me/unsubscribe\" style=\"color:#9A9AA2;text-decoration:underline\">Unsubscribe</a></p>",
  "text": "Hi there",
  "missing": [],
  "to": {
    "id": "8028ff76-1da4-451f-a0e7-dd91db772c20",
    "name": "Camille Laurent",
    "email": "camille@payfit.com",
    "sample": false
  },
  "from": {
    "name": "Olivia Martin",
    "email": "olivia@acme.com"
  },
  "ai_available": false
}
POST/email/test

Send yourself a test

Renders like POST /email/preview and sends it to the key’s user, subject prefixed with [Test].

Scope: write

Body

template_iduuid
Template.
campaign_iduuid
Campaign.
contact_iduuid
Contact whose data fills the tags.
subjectstring
Subject. Merge tags allowed ({{contact.first_name | there}}).
preheaderstring
Preview text shown after the subject in inboxes.
bodystring
Message — plain text or HTML, with merge tags and {{#if …}}…{{else}}…{{/if}} blocks. See merge tags.
with_aiboolean
Generate the AI line.
Request
curl -X POST "https://meetzy.me/api/v1/email/test" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "7f2e9d1c-3b4a-4c5d-9e8f-0a1b2c3d4e5f"
  }'
const res = await fetch("https://meetzy.me/api/v1/email/test", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "campaign_id": "7f2e9d1c-3b4a-4c5d-9e8f-0a1b2c3d4e5f"
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/test",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "campaign_id": "7f2e9d1c-3b4a-4c5d-9e8f-0a1b2c3d4e5f"
    },
)
data = res.json()
Response201
{
  "sent": true,
  "to": "olivia@acme.com",
  "from": "olivia@acme.com"
}
POST/email/ai-draft

Draft an email with AI

Writes a subject and body from a goal, with merge tags. Uses AI credits.

Scope: write

Body

goalstringrequired
What the email should achieve.
tonestring
e.g. friendly (default), formal, direct.
languagestring
auto (same as the goal) or a language name.
lengthstring
short (default), medium, long.
Request
curl -X POST "https://meetzy.me/api/v1/email/ai-draft" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "goal": "Invite customers to our booth at the Paris fair, hall 4",
    "tone": "friendly",
    "language": "French"
  }'
const res = await fetch("https://meetzy.me/api/v1/email/ai-draft", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "goal": "Invite customers to our booth at the Paris fair, hall 4",
    "tone": "friendly",
    "language": "French"
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/ai-draft",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "goal": "Invite customers to our booth at the Paris fair, hall 4",
        "tone": "friendly",
        "language": "French"
    },
)
data = res.json()
Response201
{
  "subject": "On se voit au salon, {{contact.first_name | there}} ?",
  "body": "Bonjour {{contact.first_name | there}},\n\nNous serons au salon de Paris, hall 4…\n\n{{owner.first_name}}"
}
POST/email/audience/preview

Preview an audience

How many people an audience reaches, who is left out and why (no email, unsubscribed, filtered, recently contacted, replied, duplicate), and a sample. Audience — source: filters (default: every contact with an email matching lifecycle[], owners[], tags_any[], tags_none[], min_score, CRM stages[] and temperatures statuses[], plus advanced rules[] with match: all|any — same rules as workflow conditions), contacts (contact_ids[]), or members (a mailing list you fill with POST /email/campaigns/{id}/members, by API or from workflows). Unsubscribed and do-not-contact people are always left out.

Scope: write

Body

audienceobjectrequired
Audience to test.
campaign_iduuid
Campaign (for members audiences).
settingsobject
Settings (e.g. skip_contacted_days).
Request
curl -X POST "https://meetzy.me/api/v1/email/audience/preview" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "audience": {
      "source": "filters",
      "lifecycle": [
        "mql",
        "sql"
      ],
      "tags_any": [
        "webinar"
      ],
      "min_score": 30
    }
  }'
const res = await fetch("https://meetzy.me/api/v1/email/audience/preview", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "audience": {
      "source": "filters",
      "lifecycle": [
        "mql",
        "sql"
      ],
      "tags_any": [
        "webinar"
      ],
      "min_score": 30
    }
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/audience/preview",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "audience": {
            "source": "filters",
            "lifecycle": ["mql", "sql"],
            "tags_any": ["webinar"],
            "min_score": 30
        }
    },
)
data = res.json()
Response201
{
  "count": 1,
  "excluded": {
    "no_email": 0,
    "unsubscribed": 0,
    "filtered": 0,
    "recently_contacted": 0,
    "replied": 0,
    "duplicate": 0
  },
  "sample": [
    {
      "id": "8028ff76-1da4-451f-a0e7-dd91db772c20",
      "name": "Camille Laurent",
      "email": "camille@payfit.com",
      "company": "Payfit",
      "owner": null
    }
  ]
}
POST/email/quick-send

Send an email to a list of contacts now

Creates a campaign for these contacts and launches it in one call — the simplest way to email a selection. Unsubscribe link added automatically when there is more than one recipient.

Scope: write

Body

contact_idsuuid[]required
Recipients.
template_iduuid
Template (or subject + body).
subjectstring
Subject.
bodystring
Body.
namestring
Campaign name.
send_atdatetime
Send later instead of now.
settingsobject
Campaign settings.
Request
curl -X POST "https://meetzy.me/api/v1/email/quick-send" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_ids": [
      "e43414d6-f56f-42be-a64c-a836d6015efc"
    ],
    "template_id": "8a1c2e3f-4b5d-4e6f-8a7b-9c0d1e2f3a4b"
  }'
const res = await fetch("https://meetzy.me/api/v1/email/quick-send", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "contact_ids": [
      "e43414d6-f56f-42be-a64c-a836d6015efc"
    ],
    "template_id": "8a1c2e3f-4b5d-4e6f-8a7b-9c0d1e2f3a4b"
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/quick-send",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "contact_ids": ["e43414d6-f56f-42be-a64c-a836d6015efc"],
        "template_id": "8a1c2e3f-4b5d-4e6f-8a7b-9c0d1e2f3a4b"
    },
)
data = res.json()
Response201
{
  "campaign_id": "7f2e9d1c-3b4a-4c5d-9e8f-0a1b2c3d4e5f",
  "recipients": 1,
  "status": "scheduled"
}
GET/email/campaigns

List campaigns

Campaigns with their status (draft, scheduled, sending, sent, active for recurring mailings, paused, completed) and stats.

Scope: read
Request
curl "https://meetzy.me/api/v1/email/campaigns" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/campaigns", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/email/campaigns",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "campaigns": [
    {
      "id": "f65563d3-30f2-476f-a9df-fc1d802f9483",
      "user_from": "acme",
      "name": "October newsletter",
      "status": "draft",
      "template_id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
      "subject": "Hi {{contact.first_name}}",
      "preheader": null,
      "body": "Hi there",
      "audience": {
        "rules": [],
        "owners": [],
        "source": "filters",
        "tags_any": [],
        "lifecycle": [],
        "tags_none": []
      },
      "schedule": {
        "type": "now"
      },
      "settings": {
        "send_from_owner": true,
        "sender_email": "",
        "daily_limit": 200,
        "skip_contacted_days": 0,
        "unsubscribe_link": true,
        "track": true,
        "stop_on_reply": true,
        "ai": {
          "enabled": false,
          "instructions": ""
        }
      },
      "next_run_at": null,
      "last_run_at": null,
      "run_count": 0,
      "stats": {},
      "created_by": "olivia@acme.com",
      "created_at": "2026-10-07T13:23:15.071498+00:00",
      "updated_at": "2026-10-07T13:23:15.071498+00:00",
      "members_count": 0
    }
  ]
}
POST/email/campaigns

Create a campaign

Created as a draft — launch it with POST /email/campaigns/{id}/launch. A template_id fills subject, body and AI instructions. Audience — source: filters (default: every contact with an email matching lifecycle[], owners[], tags_any[], tags_none[], min_score, CRM stages[] and temperatures statuses[], plus advanced rules[] with match: all|any — same rules as workflow conditions), contacts (contact_ids[]), or members (a mailing list you fill with POST /email/campaigns/{id}/members, by API or from workflows). Unsubscribed and do-not-contact people are always left out. Schedule — { "type": "now" }, { "type": "once", "at": "2026-10-20T08:30:00+02:00" }, or a recurring mailing { "type": "recurring", "frequency": "daily" | "weekdays" | "weekly", "time": "08:30", "weekday": 1, "timezone": "Europe/Paris" } that sends to the audience each time (new people included). Settings — send_from_owner (true: each contact gets it from their owner’s mailbox), sender_email (or always from this mailbox), daily_limit (200), skip_contacted_days (0), unsubscribe_link (true), track (true), stop_on_reply (true, recurring), ai ({ enabled, instructions } — writes {{ai.line}} for each contact).

Scope: write

Body

namestring
Name.
template_iduuid
Template to start from.
subjectstring
Subject. Merge tags allowed ({{contact.first_name | there}}).
preheaderstring
Preview text shown after the subject in inboxes.
bodystring
Message — plain text or HTML, with merge tags and {{#if …}}…{{else}}…{{/if}} blocks. See merge tags.
audienceobject
Who receives it.
scheduleobject
When.
settingsobject
How.
Request
curl -X POST "https://meetzy.me/api/v1/email/campaigns" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Morning briefing",
    "template_id": "8a1c2e3f-4b5d-4e6f-8a7b-9c0d1e2f3a4b",
    "audience": {
      "source": "members"
    },
    "schedule": {
      "type": "recurring",
      "frequency": "weekdays",
      "time": "08:30",
      "timezone": "Europe/Paris"
    },
    "settings": {
      "daily_limit": 150,
      "ai": {
        "enabled": true,
        "instructions": "One line about their company news."
      }
    }
  }'
const res = await fetch("https://meetzy.me/api/v1/email/campaigns", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "name": "Morning briefing",
    "template_id": "8a1c2e3f-4b5d-4e6f-8a7b-9c0d1e2f3a4b",
    "audience": {
      "source": "members"
    },
    "schedule": {
      "type": "recurring",
      "frequency": "weekdays",
      "time": "08:30",
      "timezone": "Europe/Paris"
    },
    "settings": {
      "daily_limit": 150,
      "ai": {
        "enabled": true,
        "instructions": "One line about their company news."
      }
    }
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/campaigns",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "name": "Morning briefing",
        "template_id": "8a1c2e3f-4b5d-4e6f-8a7b-9c0d1e2f3a4b",
        "audience": {
            "source": "members"
        },
        "schedule": {
            "type": "recurring",
            "frequency": "weekdays",
            "time": "08:30",
            "timezone": "Europe/Paris"
        },
        "settings": {
            "daily_limit": 150,
            "ai": {
                "enabled": True,
                "instructions": "One line about their company news."
            }
        }
    },
)
data = res.json()
Response201
{
  "id": "f65563d3-30f2-476f-a9df-fc1d802f9483",
  "user_from": "acme",
  "name": "October newsletter",
  "status": "draft",
  "template_id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
  "subject": "Hi {{contact.first_name}}",
  "preheader": null,
  "body": "Hi there",
  "audience": {
    "rules": [],
    "owners": [],
    "source": "filters",
    "tags_any": [],
    "lifecycle": [],
    "tags_none": []
  },
  "schedule": {
    "type": "now"
  },
  "settings": {
    "ai": {
      "enabled": false,
      "instructions": ""
    },
    "track": true,
    "daily_limit": 200,
    "sender_email": "",
    "stop_on_reply": true,
    "send_from_owner": true,
    "unsubscribe_link": true,
    "skip_contacted_days": 0
  },
  "next_run_at": null,
  "last_run_at": null,
  "run_count": 0,
  "stats": {},
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:15.071498+00:00",
  "updated_at": "2026-10-07T13:23:15.071498+00:00"
}
GET/email/campaigns/{id}

Get a campaign

The campaign with its sends (status, opens, clicks, replies per recipient) and stats.

Scope: read

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "campaign": {
    "id": "f65563d3-30f2-476f-a9df-fc1d802f9483",
    "user_from": "acme",
    "name": "October newsletter",
    "status": "draft",
    "template_id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
    "subject": "Hi {{contact.first_name}}",
    "preheader": null,
    "body": "Hi there",
    "audience": {
      "rules": [],
      "owners": [],
      "source": "filters",
      "tags_any": [],
      "lifecycle": [],
      "tags_none": []
    },
    "schedule": {
      "type": "now"
    },
    "settings": {
      "send_from_owner": true,
      "sender_email": "",
      "daily_limit": 200,
      "skip_contacted_days": 0,
      "unsubscribe_link": true,
      "track": true,
      "stop_on_reply": true,
      "ai": {
        "enabled": false,
        "instructions": ""
      }
    },
    "next_run_at": null,
    "last_run_at": null,
    "run_count": 0,
    "stats": {
      "total": 0,
      "queued": 0,
      "sent": 0,
      "failed": 0,
      "skipped": 0,
      "opened": 0,
      "clicked": 0,
      "replied": 0,
      "unsubscribed": 0,
      "auto_opened": 0,
      "bot_hits": 0,
      "open_rate": 0,
      "click_rate": 0,
      "reply_rate": 0
    },
    "created_by": "olivia@acme.com",
    "created_at": "2026-10-07T13:23:15.071498+00:00",
    "updated_at": "2026-10-07T13:23:15.071498+00:00"
  },
  "sends": [],
  "members_count": 0
}
PATCH/email/campaigns/{id}

Update a campaign

Changing the schedule of a scheduled or active campaign recomputes its next run.

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).

Body

namestring
Name.
template_iduuid
Template.
subjectstring
Subject. Merge tags allowed ({{contact.first_name | there}}).
preheaderstring
Preview text shown after the subject in inboxes.
bodystring
Message — plain text or HTML, with merge tags and {{#if …}}…{{else}}…{{/if}} blocks. See merge tags.
audienceobject
Audience.
scheduleobject
Schedule.
settingsobject
Settings (merged).
Request
curl -X PATCH "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "schedule": {
      "type": "once",
      "at": "2026-10-21T09:00:00+02:00"
    }
  }'
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc", {
  method: "PATCH",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "schedule": {
      "type": "once",
      "at": "2026-10-21T09:00:00+02:00"
    }
  }),
});
const data = await res.json();
import os, requests

res = requests.patch(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "schedule": {
            "type": "once",
            "at": "2026-10-21T09:00:00+02:00"
        }
    },
)
data = res.json()
Response200
{
  "id": "f65563d3-30f2-476f-a9df-fc1d802f9483",
  "user_from": "acme",
  "name": "October newsletter",
  "status": "draft",
  "template_id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
  "subject": "Hi {{contact.first_name}}",
  "preheader": null,
  "body": "Hi there",
  "audience": {
    "rules": [],
    "owners": [],
    "source": "filters",
    "tags_any": [],
    "lifecycle": [],
    "tags_none": []
  },
  "schedule": {
    "type": "now"
  },
  "settings": {
    "ai": {
      "enabled": false,
      "instructions": ""
    },
    "track": true,
    "daily_limit": 200,
    "sender_email": "",
    "stop_on_reply": true,
    "send_from_owner": true,
    "unsubscribe_link": true,
    "skip_contacted_days": 0
  },
  "next_run_at": null,
  "last_run_at": null,
  "run_count": 0,
  "stats": {},
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:15.071498+00:00",
  "updated_at": "2026-10-07T13:23:15.071498+00:00"
}
DELETE/email/campaigns/{id}

Delete a campaign

Scope: delete

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X DELETE "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.delete(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "deleted": true
}
POST/email/campaigns/{id}/duplicate

Duplicate a campaign

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X POST "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/duplicate" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/duplicate", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/duplicate",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response201
{
  "id": "f65563d3-30f2-476f-a9df-fc1d802f9483",
  "user_from": "acme",
  "name": "October newsletter (copy)",
  "status": "draft",
  "template_id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
  "subject": "Hi {{contact.first_name}}",
  "preheader": null,
  "body": "Hi there",
  "audience": {
    "rules": [],
    "owners": [],
    "source": "filters",
    "tags_any": [],
    "lifecycle": [],
    "tags_none": []
  },
  "schedule": {
    "type": "now"
  },
  "settings": {
    "ai": {
      "enabled": false,
      "instructions": ""
    },
    "track": true,
    "daily_limit": 200,
    "sender_email": "",
    "stop_on_reply": true,
    "send_from_owner": true,
    "unsubscribe_link": true,
    "skip_contacted_days": 0
  },
  "next_run_at": null,
  "last_run_at": null,
  "run_count": 0,
  "stats": {},
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:15.071498+00:00",
  "updated_at": "2026-10-07T13:23:15.071498+00:00"
}
POST/email/campaigns/{id}/launch

Launch a campaign

Schedules it (scheduled, or active for a recurring mailing). Fails with 400 when no mailbox is connected, the content is empty, a one-off audience is empty, or a once schedule has no date.

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X POST "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/launch" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/launch", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/launch",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response201
{
  "id": "f65563d3-30f2-476f-a9df-fc1d802f9483",
  "user_from": "acme",
  "name": "October newsletter",
  "status": "scheduled",
  "template_id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
  "subject": "Hi {{contact.first_name}}",
  "preheader": null,
  "body": "Hi there",
  "audience": {
    "rules": [],
    "owners": [],
    "source": "filters",
    "tags_any": [],
    "lifecycle": [],
    "tags_none": []
  },
  "schedule": {
    "type": "now"
  },
  "settings": {
    "ai": {
      "enabled": false,
      "instructions": ""
    },
    "track": true,
    "daily_limit": 200,
    "sender_email": "",
    "stop_on_reply": true,
    "send_from_owner": true,
    "unsubscribe_link": true,
    "skip_contacted_days": 0
  },
  "next_run_at": "2026-10-07T13:30:00.000Z",
  "last_run_at": null,
  "run_count": 0,
  "stats": {},
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:15.071498+00:00",
  "updated_at": "2026-10-07T13:23:15.071498+00:00"
}
POST/email/campaigns/{id}/pause

Pause a campaign

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X POST "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/pause" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/pause", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/pause",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response201
{
  "id": "f65563d3-30f2-476f-a9df-fc1d802f9483",
  "user_from": "acme",
  "name": "October newsletter",
  "status": "paused",
  "template_id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
  "subject": "Hi {{contact.first_name}}",
  "preheader": null,
  "body": "Hi there",
  "audience": {
    "rules": [],
    "owners": [],
    "source": "filters",
    "tags_any": [],
    "lifecycle": [],
    "tags_none": []
  },
  "schedule": {
    "type": "now"
  },
  "settings": {
    "ai": {
      "enabled": false,
      "instructions": ""
    },
    "track": true,
    "daily_limit": 200,
    "sender_email": "",
    "stop_on_reply": true,
    "send_from_owner": true,
    "unsubscribe_link": true,
    "skip_contacted_days": 0
  },
  "next_run_at": null,
  "last_run_at": null,
  "run_count": 0,
  "stats": {},
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:15.071498+00:00",
  "updated_at": "2026-10-07T13:23:15.071498+00:00"
}
POST/email/campaigns/{id}/resume

Resume a campaign

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X POST "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/resume" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/resume", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/resume",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response201
{
  "id": "f65563d3-30f2-476f-a9df-fc1d802f9483",
  "user_from": "acme",
  "name": "October newsletter",
  "status": "scheduled",
  "template_id": "5b8b7a8c-de50-4132-a75a-6ae853bff223",
  "subject": "Hi {{contact.first_name}}",
  "preheader": null,
  "body": "Hi there",
  "audience": {
    "rules": [],
    "owners": [],
    "source": "filters",
    "tags_any": [],
    "lifecycle": [],
    "tags_none": []
  },
  "schedule": {
    "type": "now"
  },
  "settings": {
    "ai": {
      "enabled": false,
      "instructions": ""
    },
    "track": true,
    "daily_limit": 200,
    "sender_email": "",
    "stop_on_reply": true,
    "send_from_owner": true,
    "unsubscribe_link": true,
    "skip_contacted_days": 0
  },
  "next_run_at": null,
  "last_run_at": null,
  "run_count": 0,
  "stats": {},
  "created_by": "olivia@acme.com",
  "created_at": "2026-10-07T13:23:15.071498+00:00",
  "updated_at": "2026-10-07T13:23:15.071498+00:00"
}
GET/email/campaigns/{id}/members

Mailing list members

People on the campaign’s list (audience members), who added them and when.

Scope: read

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/members" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/members", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/members",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "members": [
    {
      "lead_id": "8028ff76-1da4-451f-a0e7-dd91db772c20",
      "added_by": "olivia@acme.com",
      "added_at": "2026-10-07T13:23:17.617691+00:00",
      "id": "8028ff76-1da4-451f-a0e7-dd91db772c20",
      "display_name": "Camille Laurent",
      "primary_email": "camille@payfit.com",
      "company": "Payfit",
      "unsubscribed_at": null
    }
  ]
}
POST/email/campaigns/{id}/members

Add people to a mailing list

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).

Body

contact_idsuuid[]required
Contacts to add.
Request
curl -X POST "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/members" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_ids": [
      "e43414d6-f56f-42be-a64c-a836d6015efc"
    ]
  }'
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/members", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "contact_ids": [
      "e43414d6-f56f-42be-a64c-a836d6015efc"
    ]
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/members",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "contact_ids": ["e43414d6-f56f-42be-a64c-a836d6015efc"]
    },
)
data = res.json()
Response201
{
  "added": 1
}
DELETE/email/campaigns/{id}/members

Remove people from a mailing list

Scope: delete

Path parameters

idstringrequired
Id of the record (UUID).

Body

contact_idsuuid[]required
Contacts to remove.
Request
curl -X DELETE "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/members" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_ids": [
      "e43414d6-f56f-42be-a64c-a836d6015efc"
    ]
  }'
const res = await fetch("https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/members", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "contact_ids": [
      "e43414d6-f56f-42be-a64c-a836d6015efc"
    ]
  }),
});
const data = await res.json();
import os, requests

res = requests.delete(
    "https://meetzy.me/api/v1/email/campaigns/e43414d6-f56f-42be-a64c-a836d6015efc/members",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "contact_ids": ["e43414d6-f56f-42be-a64c-a836d6015efc"]
    },
)
data = res.json()
Response200
{
  "removed": true
}
GET/email/sends/{id}/events

Tracking events of one email

Every open and click of one sent email, oldest first. class says who it was: human, proxy (Gmail / Yahoo image proxy — a reader opened it), inferred, or not a person: scanner (security scanner), bot, sender (your own Sent folder) — with the reason.

Scope: read

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl "https://meetzy.me/api/v1/email/sends/e43414d6-f56f-42be-a64c-a836d6015efc/events" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/email/sends/e43414d6-f56f-42be-a64c-a836d6015efc/events", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://meetzy.me/api/v1/email/sends/e43414d6-f56f-42be-a64c-a836d6015efc/events",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "events": [
    {
      "kind": "open",
      "class": "scanner",
      "reason": "automated client (Barracuda)",
      "url": null,
      "user_agent": "Barracuda…",
      "created_at": "2026-10-07T09:12:02Z"
    },
    {
      "kind": "open",
      "class": "proxy",
      "reason": "Gmail image proxy (reader opened it)",
      "url": null,
      "user_agent": "GoogleImageProxy",
      "created_at": "2026-10-07T09:12:44Z"
    },
    {
      "kind": "click",
      "class": "human",
      "reason": null,
      "url": "https://acme.com/pricing",
      "user_agent": "Mozilla/5.0 …",
      "created_at": "2026-10-07T09:13:02Z"
    }
  ]
}