@sequenzy/mcp 0.0.160 → 0.0.162
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1641 -0
- package/dist/index.js +5 -5
- package/dist/runtime.js +1 -1
- package/dist/server.js +5 -5
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,1641 @@
|
|
|
1
|
+
# Sequenzy MCP Server
|
|
2
|
+
|
|
3
|
+
Official MCP server for [Sequenzy](https://sequenzy.com), the AI-powered email marketing platform.
|
|
4
|
+
|
|
5
|
+
Connect Sequenzy to Claude Desktop, Claude Code, Codex, Cursor, Windsurf, VS Code Copilot, OpenClaw, and other MCP clients so your AI assistant can manage email operations with structured tools instead of hand-written API calls.
|
|
6
|
+
|
|
7
|
+
## What You Can Do
|
|
8
|
+
|
|
9
|
+
- Manage subscribers, tags, lists, and dynamic segments, including bulk tag reconciliation and synthetic event testing.
|
|
10
|
+
- Sync segments to Meta custom audiences for Facebook and Instagram retargeting.
|
|
11
|
+
- Manage products and attach digital delivery files for purchase automations.
|
|
12
|
+
- Upload hosted email images with alt text and reusable responsive crop settings.
|
|
13
|
+
- Draft, update, schedule, and inspect campaigns, including resolved audience previews, persisted conversion goals, and From, Reply-To, CC, and BCC identities.
|
|
14
|
+
- Render campaigns, sequence steps, and templates to their exact email-safe HTML without sending.
|
|
15
|
+
- Add one-click Poll and NPS survey blocks to emails and inspect campaign response summaries.
|
|
16
|
+
- Create and edit email sequences, including multi-list/tag triggers, entry-audience and property-filtered stop conditions, sending identity overrides, existing graph restructuring, and direct step test sends to internal reviewers.
|
|
17
|
+
- Cancel, pause, resume, duplicate, or delete campaigns and enroll contacts into sequences.
|
|
18
|
+
- Manage transactional email templates and send transactional emails to shared To, Cc, and Bcc recipient lists.
|
|
19
|
+
- Supply localized template variants or queue AI translation for enabled locales.
|
|
20
|
+
- Create, preview, edit, publish, unpublish, and delete landing pages.
|
|
21
|
+
- Create list-scoped saved signup forms with responsive stack, row, grid, and
|
|
22
|
+
single-image overlay block groups (including foreground gap controls), then
|
|
23
|
+
return client-safe static-site embeds.
|
|
24
|
+
- Create, target, publish, duplicate, and deploy saved signup popups with the
|
|
25
|
+
same recursive block layouts.
|
|
26
|
+
- Connect and verify custom domains for published landing pages.
|
|
27
|
+
- Manage team invitations, inbox conversations, and outbound webhook endpoints.
|
|
28
|
+
- Generate email copy, subject lines, and multi-step sequences.
|
|
29
|
+
- Inspect analytics, subscriber activity, deliverability health, company-level sending pauses, integrations, published event payload schemas, sending identities, tracking settings, and dashboard URLs.
|
|
30
|
+
- Inspect whether "Sent with Sequenzy" is visible for a workspace, why the owner subscription does or does not remove it, and open the canonical subscription page for an upgrade or renewal. Entitlement changes apply to future sends from existing live sequences without editing their blocks.
|
|
31
|
+
- Diagnose why sending is paused and restore eligible hard-bounce pauses after confirming list cleanup.
|
|
32
|
+
- Inspect exact-recipient bounce, complaint, and email-hygiene suppression, and clean up eligible stale bounces without exposing the shared SES suppression list.
|
|
33
|
+
- Configure company product info, account-wide sending identity defaults, rename individual sender and reply-to profiles, manage sender domains, and inspect integration examples for common frameworks.
|
|
34
|
+
|
|
35
|
+
Every published MCP tool includes explicit `readOnlyHint`, `destructiveHint`, and `openWorldHint` annotations so compatible clients can display accurate tool-use affordances. Tools also publish `outputSchema` definitions and return `structuredContent`, giving clients and models machine-readable result shapes for follow-up calls.
|
|
36
|
+
|
|
37
|
+
## Quick Setup
|
|
38
|
+
|
|
39
|
+
The easiest setup path is the Sequenzy wizard:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx @sequenzy/setup
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The wizard opens the browser login flow, creates a personal API key, detects supported AI clients, and configures them automatically when possible.
|
|
46
|
+
|
|
47
|
+
## Hosted Remote MCP
|
|
48
|
+
|
|
49
|
+
For clients that support Streamable HTTP MCP, use Sequenzy's hosted endpoint instead of running a local stdio process:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
https://api.sequenzy.com/v1/mcp
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
ChatGPT and the OpenAI plugin directory use the reviewed hosted surface:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
https://api.sequenzy.com/v1/mcp/openai
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
That surface shares the same implementation and keeps the standard tool set
|
|
62
|
+
except for six operations: `connect_integration`, `create_api_key`,
|
|
63
|
+
`create_webhook`, `list_webhook_deliveries`, `replay_webhook_delivery`, and
|
|
64
|
+
`rotate_sequence_inbound_webhook_secret`. Feedback stays available with a
|
|
65
|
+
reduced schema for generalized, explicitly requested product feedback.
|
|
66
|
+
|
|
67
|
+
Remote clients should authenticate with the Sequenzy OAuth flow when supported. Local and automation clients can still use the stdio package below with `SEQUENZY_API_KEY`.
|
|
68
|
+
|
|
69
|
+
The hosted endpoint and the stdio package support MCP specification
|
|
70
|
+
`2026-07-28` while remaining compatible with 2025-era clients. Modern HTTP
|
|
71
|
+
clients use per-request discovery and method headers; existing clients keep
|
|
72
|
+
working through the same endpoint and package command.
|
|
73
|
+
|
|
74
|
+
Machine-readable discovery files:
|
|
75
|
+
|
|
76
|
+
- MCP server manifest: [`server.json`](server.json)
|
|
77
|
+
- Agent card: [`.well-known/agent-card.json`](https://github.com/Sequenzy/mcp/blob/main/.well-known/agent-card.json)
|
|
78
|
+
- Agent capability manifest: [`agent-capability.json`](https://github.com/Sequenzy/mcp/blob/main/agent-capability.json)
|
|
79
|
+
- OpenClaw skill metadata: [`openclaw/skill.json`](https://github.com/Sequenzy/mcp/blob/main/openclaw/skill.json)
|
|
80
|
+
|
|
81
|
+
### Data and privacy
|
|
82
|
+
|
|
83
|
+
Sequenzy sends an MCP client only the data needed for the tool the user asks it
|
|
84
|
+
to run, within the selected workspace and the key or OAuth scopes granted to
|
|
85
|
+
that client. Depending on the requested tool, this can include workspace names
|
|
86
|
+
and IDs; subscriber contact, consent, audience, attribute, event, engagement,
|
|
87
|
+
reply, survey, and commerce data; campaign and automation content; delivery
|
|
88
|
+
analytics; and integration or webhook status. See the
|
|
89
|
+
[Sequenzy Privacy Policy](https://sequenzy.com/privacy) for the full categories,
|
|
90
|
+
purposes, recipients, retention periods, and user controls.
|
|
91
|
+
|
|
92
|
+
Do not use open-ended custom attributes, events, notes, forms, webhook samples,
|
|
93
|
+
email variables, or feedback to submit payment-card data, health or medical
|
|
94
|
+
data, government identifiers, biometric or genetic data, authentication
|
|
95
|
+
credentials, sensitive demographic data, or precise geolocation.
|
|
96
|
+
|
|
97
|
+
The OpenAI-reviewed route states and enforces those restrictions on relevant
|
|
98
|
+
open-ended inputs, including nested attribute paths such as `profile.ssn`,
|
|
99
|
+
coordinate pairs such as `lat`/`lng`, and labelled prose such as
|
|
100
|
+
`Religion: ...` or `GPS coordinates: ...`. It rejects a credential-bearing URL
|
|
101
|
+
in any argument, whether the credential sits in the userinfo, path, query, or
|
|
102
|
+
fragment, such as a form or popup `redirectUrl` with an access token or URL
|
|
103
|
+
signature. Restricted attribute selectors inside merge tags are rejected
|
|
104
|
+
without blocking ordinary authored copy about the same topic. On this surface,
|
|
105
|
+
`render_email` accepts sample data or a policy-checked inline `subscriber`, but
|
|
106
|
+
not `subscriberId`, so it cannot resolve uninspected stored custom attributes.
|
|
107
|
+
Its results remove restricted fields, raw API errors, debug payloads, internal
|
|
108
|
+
request/trace/session identifiers, unnecessary account or credential
|
|
109
|
+
identifiers, stored credential-bearing URLs, and inbound-webhook URLs. Standard
|
|
110
|
+
remote MCP and the local stdio package retain the complete contract for trusted
|
|
111
|
+
clients, including credential-based integration setup, one-time API-key and
|
|
112
|
+
webhook secrets, inbound-webhook URLs, and detailed API errors. Prefer the
|
|
113
|
+
dashboard or local CLI when secrets should stay outside an AI conversation.
|
|
114
|
+
`submit_feedback` runs only when the user explicitly asks; its OpenAI schema is
|
|
115
|
+
limited to a generalized message, category, and optional workflow context, and
|
|
116
|
+
the route rejects feedback text that contains an email address or resource ID.
|
|
117
|
+
|
|
118
|
+
What the reviewed surface guarantees is bounded. It recognizes restricted data
|
|
119
|
+
by shape: English field-name words such as `passport_id`, `user.ssn`, or
|
|
120
|
+
`api_secret` at any nesting depth, labelled prose such as `Diagnosis: ...`,
|
|
121
|
+
known credential shapes, decimal coordinate pairs, and credential-bearing URLs
|
|
122
|
+
inside any string, including HTML. It does not interpret unlabelled prose,
|
|
123
|
+
non-English field names, or values a client deliberately obfuscates; those
|
|
124
|
+
remain covered by the usage restriction above rather than by the filter.
|
|
125
|
+
|
|
126
|
+
## Manual Setup
|
|
127
|
+
|
|
128
|
+
All stdio MCP clients use the same command:
|
|
129
|
+
|
|
130
|
+
- Command: `npx`
|
|
131
|
+
- Args: `-y @sequenzy/mcp`
|
|
132
|
+
- Required env: `SEQUENZY_API_KEY=seq_user_your_key_here`
|
|
133
|
+
|
|
134
|
+
Optional environment variables:
|
|
135
|
+
|
|
136
|
+
- `SEQUENZY_API_URL` - Sequenzy API base URL. Defaults to `https://api.sequenzy.com`.
|
|
137
|
+
- `SEQUENZY_APP_URL` - Sequenzy dashboard base URL used by app URL helpers. Defaults to `https://sequenzy.com`.
|
|
138
|
+
|
|
139
|
+
### Claude Desktop
|
|
140
|
+
|
|
141
|
+
Add this to your Claude Desktop config:
|
|
142
|
+
|
|
143
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
144
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"mcpServers": {
|
|
149
|
+
"sequenzy": {
|
|
150
|
+
"command": "npx",
|
|
151
|
+
"args": ["-y", "@sequenzy/mcp"],
|
|
152
|
+
"env": {
|
|
153
|
+
"SEQUENZY_API_KEY": "seq_user_your_key_here"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Restart Claude Desktop after editing the config.
|
|
161
|
+
|
|
162
|
+
### Claude Code
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
claude mcp add --scope user --env=SEQUENZY_API_KEY=seq_user_your_key_here sequenzy -- npx -y @sequenzy/mcp
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
On native Windows, wrap `npx` with `cmd /c`:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
claude mcp add --scope user --env=SEQUENZY_API_KEY=seq_user_your_key_here sequenzy -- cmd /c npx -y @sequenzy/mcp
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
For a shared project config, use `.mcp.json`:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"mcpServers": {
|
|
179
|
+
"sequenzy": {
|
|
180
|
+
"command": "npx",
|
|
181
|
+
"args": ["-y", "@sequenzy/mcp"],
|
|
182
|
+
"env": {
|
|
183
|
+
"SEQUENZY_API_KEY": "seq_user_your_key_here"
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Codex
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
codex mcp add sequenzy --env SEQUENZY_API_KEY=seq_user_your_key_here -- npx -y @sequenzy/mcp
|
|
194
|
+
codex mcp list
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Manual Codex config in `~/.codex/config.toml`:
|
|
198
|
+
|
|
199
|
+
```toml
|
|
200
|
+
[mcp_servers.sequenzy]
|
|
201
|
+
command = "npx"
|
|
202
|
+
args = ["-y", "@sequenzy/mcp"]
|
|
203
|
+
|
|
204
|
+
[mcp_servers.sequenzy.env]
|
|
205
|
+
SEQUENZY_API_KEY = "seq_user_your_key_here"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Cursor
|
|
209
|
+
|
|
210
|
+
Install **Sequenzy** from the Cursor Marketplace for a hosted connection with Sequenzy OAuth. The plugin connects to:
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
https://api.sequenzy.com/v1/mcp
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
After installing, complete the browser sign-in flow. Cursor's agent can then use Sequenzy tools from chat, including when Grok is the selected model.
|
|
217
|
+
|
|
218
|
+
For a manual local stdio setup instead, add this to `~/.cursor/mcp.json`:
|
|
219
|
+
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"mcpServers": {
|
|
223
|
+
"sequenzy": {
|
|
224
|
+
"command": "npx",
|
|
225
|
+
"args": ["-y", "@sequenzy/mcp"],
|
|
226
|
+
"env": {
|
|
227
|
+
"SEQUENZY_API_KEY": "seq_user_your_key_here"
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Windsurf
|
|
235
|
+
|
|
236
|
+
Use the same JSON shape as Cursor.
|
|
237
|
+
|
|
238
|
+
- macOS: `~/Library/Application Support/Windsurf/mcp.json`
|
|
239
|
+
- Windows: `%APPDATA%\Windsurf\mcp.json`
|
|
240
|
+
|
|
241
|
+
### VS Code Copilot
|
|
242
|
+
|
|
243
|
+
VS Code uses a `servers` object:
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"servers": {
|
|
248
|
+
"sequenzy": {
|
|
249
|
+
"type": "stdio",
|
|
250
|
+
"command": "npx",
|
|
251
|
+
"args": ["-y", "@sequenzy/mcp"],
|
|
252
|
+
"env": {
|
|
253
|
+
"SEQUENZY_API_KEY": "seq_user_your_key_here"
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Other MCP Clients
|
|
261
|
+
|
|
262
|
+
For OpenClaw, Hermes, and other MCP-compatible clients, point the client at `npx -y @sequenzy/mcp` and set `SEQUENZY_API_KEY`.
|
|
263
|
+
|
|
264
|
+
## Getting an API Key
|
|
265
|
+
|
|
266
|
+
1. Open [the Sequenzy dashboard](https://sequenzy.com/dashboard).
|
|
267
|
+
2. Use the **MCP** setup flow to create a personal key, or open **Settings ->
|
|
268
|
+
API Keys** to create a company key.
|
|
269
|
+
3. Choose a permission preset or the exact custom scopes the integration needs.
|
|
270
|
+
4. Add the key to your MCP client config.
|
|
271
|
+
|
|
272
|
+
Personal keys start with `seq_user_`. You can revoke them any time in the dashboard.
|
|
273
|
+
|
|
274
|
+
Company keys can also be cleaned up without exposing secrets. Call
|
|
275
|
+
`list_api_keys` to compare the key ID, name, non-secret prefix, permissions,
|
|
276
|
+
last-use timestamp, and `isCurrent` marker, then pass the exact ID to
|
|
277
|
+
`revoke_api_key`. `delete_api_key` is a compatibility alias for the same
|
|
278
|
+
permanent operation. List and revoke responses never contain the plain key or
|
|
279
|
+
stored key hash.
|
|
280
|
+
|
|
281
|
+
### Recover from missing API key permissions
|
|
282
|
+
|
|
283
|
+
If a tool reports a missing scope such as `campaigns:read` or
|
|
284
|
+
`templates:write`, call `get_account`. Its `apiKeyPermissions` field lists the
|
|
285
|
+
current key identity and type, scopes, common missing marketing read scopes, and
|
|
286
|
+
a direct `manageUrl`. The OpenAI-reviewed route returns the same permissions
|
|
287
|
+
without the user's account ID or the active key's identity. Personal keys open
|
|
288
|
+
Account API Keys; company keys open the selected workspace's API Keys settings.
|
|
289
|
+
If the key does not include
|
|
290
|
+
`account:read`, open the
|
|
291
|
+
[Sequenzy dashboard](https://sequenzy.com/dashboard) directly and choose the
|
|
292
|
+
matching API Keys page.
|
|
293
|
+
|
|
294
|
+
Permissions are editable in place, so open `manageUrl`. For a company key, use
|
|
295
|
+
`list_api_keys` and its `isCurrent` flag to identify the active key before
|
|
296
|
+
editing it, then retry the failed tool without replacing the credential or
|
|
297
|
+
restarting the client. An agent using a company key with `api_keys:manage` can
|
|
298
|
+
instead call `update_api_key`; personal keys must be edited on the account-level
|
|
299
|
+
page because that tool only manages company keys. Its `scopes` and `preset`
|
|
300
|
+
inputs replace the whole permission selection rather than merging, so preserve
|
|
301
|
+
every existing scope that is still needed. Hosted OAuth connections can
|
|
302
|
+
alternatively disconnect and reauthorize with broader permissions.
|
|
303
|
+
|
|
304
|
+
When the active key itself lacks `api_keys:manage`, call
|
|
305
|
+
`request_api_key_handoff` instead of retrying `update_api_key`. It requires
|
|
306
|
+
`account:read` and returns an owner-review URL with the requested key name,
|
|
307
|
+
permissions, and optional predecessor prefilled. It never creates or returns a
|
|
308
|
+
key; the workspace owner reviews the form, creates the replacement in the
|
|
309
|
+
browser, and copies it into the client. Pass `replaceApiKeyId: "current"` to
|
|
310
|
+
offer revocation of the active key after the replacement is created. If the
|
|
311
|
+
active key also lacks `account:read`, use the dashboard directly.
|
|
312
|
+
|
|
313
|
+
The default **Safer agent access** preset includes `lists:write` and
|
|
314
|
+
`tags:write`, so agents can create and update list and tag definitions, and it
|
|
315
|
+
includes `subscribers:tag` for applying tags to existing contacts. It also
|
|
316
|
+
includes `ab_tests:read`, `ab_tests:write`, and `sequences:write`, so agents can
|
|
317
|
+
audit and edit sequence A/B variant copy, including cart and browse abandonment
|
|
318
|
+
messages. It does not include `subscribers:write`, so it cannot add contacts to
|
|
319
|
+
lists or remove them from lists. Deleting a list or tag still requires the
|
|
320
|
+
matching `lists:delete` or `tags:delete` permission.
|
|
321
|
+
|
|
322
|
+
The AI drafting preset includes `subscribers:write`, so drafting agents can
|
|
323
|
+
build a list as well as create it. Imports that apply `listIds` also need
|
|
324
|
+
`lists:write`; sequence enrollment or double-opt-in delivery additionally needs
|
|
325
|
+
`automations:trigger`.
|
|
326
|
+
|
|
327
|
+
## Tools
|
|
328
|
+
|
|
329
|
+
The standard surface currently exposes 243 MCP tools. The OpenAI-reviewed
|
|
330
|
+
surface exposes 237; only the six operations listed above are omitted.
|
|
331
|
+
|
|
332
|
+
Tools reject arguments they do not declare instead of silently ignoring them.
|
|
333
|
+
Errors name the unsupported fields, list the supported arguments, and provide
|
|
334
|
+
focused guidance for common mistakes such as invented subscriber filters or
|
|
335
|
+
sort options.
|
|
336
|
+
|
|
337
|
+
### Account, Companies, Setup
|
|
338
|
+
|
|
339
|
+
| Tool | Description |
|
|
340
|
+
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
341
|
+
| `get_account` | Get account info, available companies, current key permissions, and the API Keys management URL. |
|
|
342
|
+
| `select_company` | Set the active company for future tool calls. |
|
|
343
|
+
| `get_app_urls` | Build dashboard URLs for campaigns, landing pages, sequences, emails, settings, subscription management, domains, and sent email details. `settingsTab: "billing"` resolves to Account -> Subscription. |
|
|
344
|
+
| `create_company` | Create a new company or brand. |
|
|
345
|
+
| `get_company` | Read company details, product info, brand context, localization, reply-tracking settings, current From/Reply-To defaults, and the effective read-only `emailBranding` entitlement with plan/status reason and subscription URL; STO is explicitly identified as campaign-only. |
|
|
346
|
+
| `update_company` | Edit product info, brand context, email theme, reply tracking, and account-wide From/Reply-To profile defaults or names. |
|
|
347
|
+
| `get_sync_rules` | Read the company's event-to-tag rules and whether it uses the inherited platform preset. |
|
|
348
|
+
| `update_sync_rules` | Replace all sync rules; pass `[]` to disable them or `null` to opt into the SaaS/ecommerce platform preset. |
|
|
349
|
+
| `get_shopify_automation_settings` | Read browse-abandonment, cart-abandonment, and price-drop settings for the connected Shopify store. |
|
|
350
|
+
| `update_shopify_automation_settings` | Partially update Shopify automation settings or reset an individual section to its platform defaults. |
|
|
351
|
+
| `create_api_key` | Create a company API key and return its one-time secret on standard MCP; omitted from the OpenAI-reviewed route. |
|
|
352
|
+
| `request_api_key_handoff` | Prepare an owner-reviewed create/rotation URL when the active key cannot manage API keys itself. |
|
|
353
|
+
| `list_api_keys` | List company API keys as non-secret metadata for safe identification and cleanup. |
|
|
354
|
+
| `update_api_key` | Rename a company API key or replace its permission preset or scopes without changing the key value. |
|
|
355
|
+
| `revoke_api_key` | Permanently revoke an exact company API key by ID after checking it with `list_api_keys`. |
|
|
356
|
+
| `delete_api_key` | Compatibility alias for `revoke_api_key`. |
|
|
357
|
+
| `list_websites` | List sending domains with stored aggregate, SPF, DKIM, and MAIL FROM status. |
|
|
358
|
+
| `add_sending_domain` | Add a sending domain and return its cohort-specific DNS setup records. |
|
|
359
|
+
| `add_website` | Compatibility alias for `add_sending_domain`. |
|
|
360
|
+
| `check_website` | Read a sending domain's stored SPF, DKIM, MAIL FROM, and aggregate verification details. |
|
|
361
|
+
| `verify_sending_domain` | Run a fresh sending-domain DNS/provider verification and return current status and diagnostics. |
|
|
362
|
+
| `list_integrations` | List connected integrations with connection and sync health, without returning credentials. |
|
|
363
|
+
| `get_sending_status` | Diagnose active, paused, or suspended sending, including enforcement denominators, review gates, and remediation steps. |
|
|
364
|
+
| `resume_sending` | Restore an eligible hard-bounce pause after explicitly confirming the list has been sanitized. |
|
|
365
|
+
| `get_tracking_settings` | Read account-wide and Transactional API open/click defaults, unsubscribe, attribution, UTM, click-domain, reply-tracking, and double-opt-in settings. |
|
|
366
|
+
| `update_tracking_settings` | Update account-wide and Transactional API tracking defaults, attribution, UTM, and account-wide double opt-in. |
|
|
367
|
+
| `get_integration_guide` | Get framework-specific integration examples. |
|
|
368
|
+
| `get_integration` | Inspect one connected integration, its event wiring, list targeting, recent activity, and recommendations. |
|
|
369
|
+
| `list_integration_capabilities` | Compare provider capabilities whether or not they are connected. |
|
|
370
|
+
| `connect_integration` | Connect supported API-key or webhook-secret providers on standard MCP; omitted from the OpenAI-reviewed route. |
|
|
371
|
+
| `get_event_schema` | Inspect published event payload examples, property paths, types, and merge tags by provider. |
|
|
372
|
+
| `list_integration_activity` | Read the retained integration-specific webhook and sync activity log. |
|
|
373
|
+
| `set_integration_sync_enabled` | Enable or disable bulk imports and backfills while leaving live webhooks connected. |
|
|
374
|
+
| `set_integration_list_targeting` | Choose which lists contacts created by a supported integration join on future provider writes. |
|
|
375
|
+
| `sync_integration` | Queue payment revenue, Supabase users, or a PostHog/Segment event-history import using the saved integration configuration. |
|
|
376
|
+
| `get_integration_pixel` | Read Shopify's live pixel/configuration state and distinguish confirmed dark events from an unknown read. |
|
|
377
|
+
| `activate_integration_pixel` | Install or repoint Shopify's storefront pixel; idempotent when it is already current. |
|
|
378
|
+
| `list_web_tracking_keys` | List publishable website-tracking keys, origin restrictions, usage state, and install snippets. |
|
|
379
|
+
| `get_web_tracking_key` | Get one website-tracking key with its exact install snippet and ingest endpoint. |
|
|
380
|
+
| `create_web_tracking_key` | Create a publishable tracking key for a non-Shopify storefront or website. |
|
|
381
|
+
| `update_web_tracking_key` | Rename, restrict, revoke, or re-enable a website-tracking key. |
|
|
382
|
+
| `delete_web_tracking_key` | Permanently delete a website-tracking key after its snippet has been removed. |
|
|
383
|
+
| `list_sender_profiles` | List sender and reply-to profiles, defaults, and sending-domain readiness. |
|
|
384
|
+
| `update_sender_profile` | Rename one sender or reply-to profile without changing the account defaults. |
|
|
385
|
+
| `delete_sender_profile` | Permanently delete an unused sender profile, with guards for live sending surfaces and the last remaining sender. |
|
|
386
|
+
| `get_notification_preferences` | Read the current user's per-company account notification settings and supported modes, including the Monday weekly report. |
|
|
387
|
+
| `update_notification_preferences` | Update the current user's account notification delivery modes, including weekly-report opt-out, without affecting teammates. |
|
|
388
|
+
| `render_email` | Render final email-safe HTML and diagnose unresolved merge tags, including typos hidden by defaults. The OpenAI-reviewed route accepts sample data or a policy-checked inline subscriber, not a stored subscriber ID. |
|
|
389
|
+
|
|
390
|
+
`get_sending_status` keeps the Postgres-backed pause state, review gates, and
|
|
391
|
+
remediation available when sender-health analytics are temporarily unavailable;
|
|
392
|
+
in that degraded case `senderHealth` is `null`.
|
|
393
|
+
|
|
394
|
+
`render_email` returns `unresolvedMergeTags` so callers can distinguish an
|
|
395
|
+
unknown name from a recognized tag that is merely blank for the previewed
|
|
396
|
+
contact. Unknown names are reported even when a `default` filter supplied text:
|
|
397
|
+
for example, `{{ subscriber.frstName | default: "there" }}` renders a plausible
|
|
398
|
+
greeting for every contact while bypassing stored first names. A recognized
|
|
399
|
+
name that is blank for one contact is not reported when its default is used.
|
|
400
|
+
The OpenAI-reviewed route rejects restricted custom-attribute selectors inside
|
|
401
|
+
merge tags. It also omits the `subscriberId` argument; use a policy-checked
|
|
402
|
+
inline `subscriber`, or omit subscriber data for a sample preview.
|
|
403
|
+
|
|
404
|
+
To render a sequence step whose `nodeType` is `action_ab_test`, pass the
|
|
405
|
+
step's `sequenceId` and `nodeId` together with a `variantId` from
|
|
406
|
+
`get_sequence.sequence.emails[].abTest.variants`. These steps have no email of
|
|
407
|
+
their own, so the variant is required; reading and rendering their competing
|
|
408
|
+
copy also requires the `ab_tests:read` scope.
|
|
409
|
+
|
|
410
|
+
For Supabase, `sync_integration` reuses the project, schema, table, list
|
|
411
|
+
selection, and consent mappings saved in the dashboard. It cannot target an
|
|
412
|
+
arbitrary table. Run it after installing the live database trigger to import
|
|
413
|
+
users who existed before the trigger was installed, then poll `get_integration`
|
|
414
|
+
and `list_integration_activity` for progress and row-level outcomes.
|
|
415
|
+
|
|
416
|
+
`set_integration_sync_enabled` controls bulk imports and backfills only; it
|
|
417
|
+
does not stop a provider's live webhook from creating contacts. Use
|
|
418
|
+
`set_integration_list_targeting` to choose their future list memberships:
|
|
419
|
+
`null` follows workspace defaults, `[]` joins no list, and a populated array
|
|
420
|
+
targets those lists. The change is not retroactive and never removes existing
|
|
421
|
+
memberships. It also does not stop default `any_contact` sequences, which
|
|
422
|
+
enroll list-less contacts; explicit `any_list` and specific-list sequences
|
|
423
|
+
require a matching membership. Pair list targeting with
|
|
424
|
+
`pause_sequence_enrollments` when those default enrollments must stop too.
|
|
425
|
+
Supabase, Stripe, Shopify, Wix, and Webflow support this control.
|
|
426
|
+
|
|
427
|
+
For PostHog, `sync_integration` restarts the event-history import from the
|
|
428
|
+
beginning with the stored personal API key. Imported events are deduplicated, so
|
|
429
|
+
retrying a failed import does not create duplicates.
|
|
430
|
+
|
|
431
|
+
For Segment, `connect_integration` on standard MCP can optionally import recent
|
|
432
|
+
event history from Unify after the live webhook is connected. The import walks
|
|
433
|
+
existing contacts through the Profile API, covers the API's most recent 14 days,
|
|
434
|
+
skips contacts without a matching profile, and safely deduplicates retries and
|
|
435
|
+
live webhook overlap. New connections skip automatic page/screen calls unless
|
|
436
|
+
those names are explicitly allowlisted. Segment webhook secrets must be 16-153
|
|
437
|
+
UTF-8 bytes. On the OpenAI-reviewed route, which omits `connect_integration`,
|
|
438
|
+
connect Segment in the dashboard or local CLI instead. Use `sync_integration`
|
|
439
|
+
to retry with the saved credentials.
|
|
440
|
+
|
|
441
|
+
For Attio, `connect_integration` on standard MCP accepts a workspace access
|
|
442
|
+
token without a webhook secret, with optional `settings.listMap` as a map of
|
|
443
|
+
Sequenzy list IDs to Attio people-list UUIDs or API slugs, plus
|
|
444
|
+
`syncCompanyFromDomain` to control company matching from non-free-mail domains.
|
|
445
|
+
On the OpenAI-reviewed route, connect Attio in the dashboard or local CLI, then
|
|
446
|
+
use `update_attio_settings` for the same settings. The integration is
|
|
447
|
+
outbound-only:
|
|
448
|
+
new joins to mapped Sequenzy lists upsert the person and add them to the Attio
|
|
449
|
+
list; list removals do not remove records from Attio.
|
|
450
|
+
|
|
451
|
+
Call `get_event_schema` before writing an `{{event.*}}` merge tag or an event
|
|
452
|
+
property filter. Omit `eventName` to list documented built-in events; provide
|
|
453
|
+
an event name to receive provider-specific example payloads and property paths,
|
|
454
|
+
and optionally filter by `provider`. Custom event names remain valid even when
|
|
455
|
+
the result reports `documented: false`; that only means no reference sample is
|
|
456
|
+
published. Use integration activity or sequence enrollments for actual delivery
|
|
457
|
+
data because this tool returns static reference data.
|
|
458
|
+
|
|
459
|
+
For a new sending domain, call `add_sending_domain`, publish the DNS records in
|
|
460
|
+
the returned `website.dnsRecords`, wait for DNS propagation, and then call
|
|
461
|
+
`verify_sending_domain`. Publish every returned record instead of assuming a
|
|
462
|
+
fixed provider or record count: unified domains include required DMARC, while
|
|
463
|
+
legacy domains can return Amazon SES MAIL FROM and inbound-reply records. If
|
|
464
|
+
verification is attempted before creation, the error points back to
|
|
465
|
+
`add_sending_domain` with the requested domain.
|
|
466
|
+
|
|
467
|
+
For Shopify, call `get_integration_pixel` before relying on product views,
|
|
468
|
+
cart activity, or browse-abandonment triggers. The result is read live from
|
|
469
|
+
Shopify because merchants can remove the pixel independently. If
|
|
470
|
+
`pixel.healthy` is false, `dependentEvents` names the triggers that cannot
|
|
471
|
+
arrive; call `activate_integration_pixel` to install or repoint the pixel.
|
|
472
|
+
Activation is idempotent, and events begin on the next storefront visit rather
|
|
473
|
+
than being backfilled.
|
|
474
|
+
|
|
475
|
+
For custom, headless, ticketing, or SaaS websites, use
|
|
476
|
+
`list_web_tracking_keys` before relying on product-view or cart triggers. Create
|
|
477
|
+
a key with an explicit origin allowlist, install the returned `installSnippet`,
|
|
478
|
+
then have the customer's authenticated backend mint a short-lived proof through
|
|
479
|
+
`POST /api/v1/web-tracking-identities` and call
|
|
480
|
+
`sequenzy.identify(email, identityToken)` at sign-in or checkout. A publishable
|
|
481
|
+
key alone only records anonymous activity and cannot trigger subscriber
|
|
482
|
+
automation. The returned snippet installs synchronous method stubs before its
|
|
483
|
+
async loader, so identity and event calls made during page bootstrap are queued
|
|
484
|
+
until the SDK is ready. Prefer revoking a key with `update_web_tracking_key`
|
|
485
|
+
before permanently deleting it.
|
|
486
|
+
|
|
487
|
+
New companies start with no sync rules. The inherited preset remains available
|
|
488
|
+
for SaaS/ecommerce companies by passing `null` to `update_sync_rules`; services
|
|
489
|
+
and consulting companies should normally keep `[]` or define explicit rules.
|
|
490
|
+
|
|
491
|
+
Use `list_sender_profiles` to find the profile ID, then call
|
|
492
|
+
`update_sender_profile` to change only its display name. Pass `type: "reply"`
|
|
493
|
+
for a reply-to profile; sender is the default. The address, sending domain, and
|
|
494
|
+
account-wide default From/Reply-To selections remain unchanged. Renaming
|
|
495
|
+
requires the `companies:manage` scope.
|
|
496
|
+
|
|
497
|
+
Use `delete_sender_profile` to permanently remove an obsolete From identity.
|
|
498
|
+
It refuses the last sender and any profile used by a live campaign, active
|
|
499
|
+
sequence (including a step override), or transactional email. Eligible drafts
|
|
500
|
+
and account defaults move to the returned `fallbackSenderProfileId`; review it
|
|
501
|
+
before sending. Reply-to profiles are not supported by this delete tool.
|
|
502
|
+
|
|
503
|
+
Shopify cart abandonment is enabled by default. It fires
|
|
504
|
+
`ecommerce.cart_abandoned` after one hour of cart inactivity, with a 24-hour
|
|
505
|
+
per-subscriber cooldown. Use `update_shopify_automation_settings` to change the
|
|
506
|
+
`cartAbandonment.enabled`, `delayHours`, or `cooldownHours` fields; pass
|
|
507
|
+
`cartAbandonment: null` to restore those defaults without changing browse
|
|
508
|
+
abandonment or price-drop settings. Timing values must be positive;
|
|
509
|
+
`delayHours` is capped at 168 and `cooldownHours` at 720.
|
|
510
|
+
|
|
511
|
+
### Subscribers
|
|
512
|
+
|
|
513
|
+
| Tool | Description |
|
|
514
|
+
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
515
|
+
| `add_subscriber` | Add one subscriber; status is creation-only, so use `update_subscriber` for an existing contact. |
|
|
516
|
+
| `create_subscriber_import` | Queue up to 5,000 full CRM records with an optional retry-safe `idempotencyKey`; enabled email-hygiene checks continue separately after ingestion. |
|
|
517
|
+
| `get_subscriber_import` | Read progress, row outcome counts, and failure summaries for a queued import. |
|
|
518
|
+
| `update_subscriber` | Update native profile and phone fields, SMS consent, attributes, tags, or global status. |
|
|
519
|
+
| `remove_subscriber` | Unsubscribe while preserving suppression history, or permanently delete only with `hardDelete: true`. |
|
|
520
|
+
| `get_subscriber` | Fetch subscriber details by email or external ID. |
|
|
521
|
+
| `search_subscribers` | Search by query, tags, list, status, segment, or one custom attribute, with automatic or resumable pagination. |
|
|
522
|
+
| `trigger_subscriber_event` | Emit one custom event exactly as an integration would, applying sync rules and matching sequence triggers. |
|
|
523
|
+
| `trigger_subscriber_events` | Emit several ordered custom events for one subscriber. |
|
|
524
|
+
| `import_subscriber_events` | Import up to 25 source-identified events across contacts; silent history requires every row for a contact to be over an hour old. |
|
|
525
|
+
| `bulk_add_subscriber_tags` | Add tags to up to 500 existing subscribers; requires `subscribers:tag` and may also require `tags:write`. |
|
|
526
|
+
| `bulk_remove_subscriber_tags` | Remove tags from up to 500 existing subscribers; requires `subscribers:tag` or `subscribers:write`. |
|
|
527
|
+
|
|
528
|
+
Use `create_subscriber_import` for CRM onboarding instead of looping over
|
|
529
|
+
`add_subscriber`. One call accepts 5,000 full records and returns an asynchronous
|
|
530
|
+
import ID; poll it with `get_subscriber_import`. A `completed` import can still
|
|
531
|
+
contain row failures, so inspect `failedCount` and `failedReasons`. Every
|
|
532
|
+
excluded row is accounted for: `skippedReasons` sums to `skippedCount`, and
|
|
533
|
+
`failedReasons` sums to `failedCount`. Report any shortfall with the import ID
|
|
534
|
+
instead of guessing which rows were omitted. When email hygiene is enabled,
|
|
535
|
+
deliverability checks continue separately after ingestion and results appear
|
|
536
|
+
in List health; import status does not wait for or include those verdicts.
|
|
537
|
+
Invalid verdicts are suppressed from later sends. Use `optInMode: "confirmed"`
|
|
538
|
+
only when consent was already verified.
|
|
539
|
+
|
|
540
|
+
For `import_subscriber_events`, email is required when a row may create a new
|
|
541
|
+
contact; `externalId` can stand alone only for an existing contact. Supply a
|
|
542
|
+
stable `eventId` on every row. Retrying reuses the original receipt and
|
|
543
|
+
idempotently re-attempts downstream recovery. Historical classification is per
|
|
544
|
+
contact: if any row for a contact is recent, that contact's whole group uses
|
|
545
|
+
the live side-effect path.
|
|
546
|
+
|
|
547
|
+
For compliance suppression, call `update_subscriber` with
|
|
548
|
+
`status: "unsubscribed"` (or use `remove_subscriber` without `hardDelete`). Do
|
|
549
|
+
not retry `add_subscriber` with a different status: status on that tool applies
|
|
550
|
+
only when the contact is first created, and a mismatched skipped result is
|
|
551
|
+
reported as an error.
|
|
552
|
+
|
|
553
|
+
When `add_subscriber` omits `listIds`, a contact created by the call follows
|
|
554
|
+
the workspace default lists while an existing contact keeps its current list
|
|
555
|
+
memberships. Pass list IDs explicitly when an existing contact should join
|
|
556
|
+
specific lists; pass `[]` to target no lists.
|
|
557
|
+
|
|
558
|
+
`update_subscriber.phone` writes the native phone field shown on the contact,
|
|
559
|
+
not a custom attribute. Pass `smsConsent: true` only after verifying express
|
|
560
|
+
written consent, or `false` to opt the contact out. Changing the phone without
|
|
561
|
+
`smsConsent` resets SMS consent because consent belongs to the old number.
|
|
562
|
+
|
|
563
|
+
`add_subscriber`, `update_subscriber`, and `create_subscriber_import` accept an
|
|
564
|
+
IANA `timezone` such as `America/New_York`. The value is stored on the native
|
|
565
|
+
contact profile and enables recipient-local campaign delivery. Pass an empty
|
|
566
|
+
timezone to `update_subscriber` to clear it; invalid import-row values are
|
|
567
|
+
ignored without rejecting the rest of the import.
|
|
568
|
+
|
|
569
|
+
### Products & Digital Delivery
|
|
570
|
+
|
|
571
|
+
| Tool | Description |
|
|
572
|
+
| --------------------- | ------------------------------------------------------------------------------------- |
|
|
573
|
+
| `list_products` | List synced products from Stripe, Shopify, WooCommerce, manual, or Commerce API data. |
|
|
574
|
+
| `upsert_products` | Create or update up to 100 Commerce API products keyed by your product ID. |
|
|
575
|
+
| `delete_product` | Delete a product previously pushed through the Commerce API. |
|
|
576
|
+
| `attach_product_file` | Attach a hosted or locally uploaded delivery file to a product. |
|
|
577
|
+
| `remove_product_file` | Remove an attached product delivery file. |
|
|
578
|
+
| `sync_products` | Queue a Stripe product catalog sync, optionally selecting an integration by ID. |
|
|
579
|
+
|
|
580
|
+
After a product delivery file is attached, matching purchase events include `download.url` and `download.name`, so purchase-triggered emails can use merge tags like `{{event.download.url}}`.
|
|
581
|
+
|
|
582
|
+
For Stripe products, `list_products` returns every active price as a variant, with the Stripe price ID in `variantId`. Use that ID to target an exact price in a purchase sequence even when it is not the product's default price.
|
|
583
|
+
|
|
584
|
+
### Image Assets
|
|
585
|
+
|
|
586
|
+
| Tool | Description |
|
|
587
|
+
| -------------------- | -------------------------------------------------------------------------------------------- |
|
|
588
|
+
| `upload_image_asset` | Upload an email image and return its hosted media record plus a ready-to-insert image block. |
|
|
589
|
+
|
|
590
|
+
The tool accepts PNG, JPEG, GIF, and WebP images up to 5MB. Local stdio clients
|
|
591
|
+
can pass `filePath`. Hosted/remote clients that can access attachment bytes can
|
|
592
|
+
pass `imageBase64` with `filename`. Provide `altText` for accessibility, then
|
|
593
|
+
use `displayWidthPercent`, `cropHeight`, `objectFit` (`cover` or `contain`), and
|
|
594
|
+
`align` to standardize screenshot presentation. The returned `imageBlock` can
|
|
595
|
+
be copied directly into the block array accepted by campaign, sequence,
|
|
596
|
+
template, and transactional-email tools.
|
|
597
|
+
|
|
598
|
+
Authenticated image bytes are always uploaded to the origin configured by
|
|
599
|
+
`SEQUENZY_API_URL`, even if a reverse proxy returns an equivalent upload URL
|
|
600
|
+
under another host. API credentials are never forwarded to that alternate
|
|
601
|
+
origin.
|
|
602
|
+
|
|
603
|
+
```json
|
|
604
|
+
{
|
|
605
|
+
"filePath": "/Users/me/Desktop/product-results.png",
|
|
606
|
+
"altText": "Product results dashboard",
|
|
607
|
+
"displayWidthPercent": 100,
|
|
608
|
+
"cropHeight": 320,
|
|
609
|
+
"objectFit": "cover",
|
|
610
|
+
"align": "center"
|
|
611
|
+
}
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Lists, Tags, Segments
|
|
615
|
+
|
|
616
|
+
| Tool | Description |
|
|
617
|
+
| ------------------------------ | ----------------------------------------------------------- |
|
|
618
|
+
| `list_tags` | List all tags. |
|
|
619
|
+
| `create_tag` | Create a tag definition with an optional color. |
|
|
620
|
+
| `update_tag` | Update a tag color. |
|
|
621
|
+
| `delete_tag` | Delete a tag and remove it from subscribers. |
|
|
622
|
+
| `list_lists` | List subscriber lists. |
|
|
623
|
+
| `create_list` | Create a subscriber list. |
|
|
624
|
+
| `update_list` | Rename or describe a subscriber list. |
|
|
625
|
+
| `delete_list` | Delete a subscriber list. |
|
|
626
|
+
| `add_subscribers_to_list` | Add up to 500 subscribers to a list from an email array. |
|
|
627
|
+
| `remove_subscribers_from_list` | Remove up to 500 subscribers from a list. |
|
|
628
|
+
| `list_segments` | List saved segments and counts. |
|
|
629
|
+
| `create_segment` | Create nested or same-element array-filtered segments. |
|
|
630
|
+
| `update_segment` | Update segment name, filters, root group, or join operator. |
|
|
631
|
+
| `delete_segment` | Delete a segment (requires `segments:delete`). |
|
|
632
|
+
| `get_segment_count` | Preview the active subscriber count for a segment. |
|
|
633
|
+
|
|
634
|
+
For subscriber exports, `search_subscribers` accepts `listId`, exact `listName`,
|
|
635
|
+
or `list` (ID first, then exact name). It also accepts `attribute` plus
|
|
636
|
+
`attributeValue`, with `attributeOperator` for `contains`, numeric comparisons,
|
|
637
|
+
or `is_not_empty`; the combined `"attributeName:value"` form remains supported.
|
|
638
|
+
Filters combine with AND; use a saved segment for OR logic, nested groups,
|
|
639
|
+
exclusions, engagement, or event conditions. If `limit` is omitted, the tool
|
|
640
|
+
fetches every matching page automatically. For chunked reads, pass `limit` and
|
|
641
|
+
follow `pagination.nextCursor` (or `pagination.nextOffset`) while `hasMore` is
|
|
642
|
+
true. `offset` and `page` are supported below 1,000,000 skipped matches; use the
|
|
643
|
+
cursor for deeper audiences.
|
|
644
|
+
|
|
645
|
+
For bulk list population, use `add_subscribers_to_list`; the backing API endpoint is `POST /api/v1/lists/{listId}/subscribers` with no `/bulk` suffix:
|
|
646
|
+
|
|
647
|
+
```json
|
|
648
|
+
{
|
|
649
|
+
"emails": ["ada@example.com", "grace@example.com"],
|
|
650
|
+
"duplicateStrategy": "skip",
|
|
651
|
+
"enrollInSequences": false,
|
|
652
|
+
"optInMode": "default"
|
|
653
|
+
}
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
Send at most 500 emails per request. Standard API rate limits still apply: 100 requests per minute per API key and 20 requests per second burst. For CSV-driven CLI imports, accepted email headers include `email`, `e-mail`, `email address`, and `mail`; if no recognized header exists, the CLI reads the first column.
|
|
657
|
+
|
|
658
|
+
Segment filters support attributes, events, saved segment membership, engagement events, Stripe product purchase rules, and commerce product purchase rules. Use `filterJoinOperator: "or"` for match-any segments, or pass a v2 `root` group for nested logic.
|
|
659
|
+
|
|
660
|
+
For array-of-object attributes, use wildcard paths such as
|
|
661
|
+
`history_events[].eventvenue_id:2103`. When an AND group also filters
|
|
662
|
+
`history_events[].showing_date`, both conditions must match one shared
|
|
663
|
+
`history_events[]` element; values from unrelated history entries are not
|
|
664
|
+
combined. Deleting a segment requires `segments:delete`; `segments:write` is
|
|
665
|
+
not sufficient.
|
|
666
|
+
|
|
667
|
+
Each segment filter field validates its own operators:
|
|
668
|
+
|
|
669
|
+
- `status`, `segment`: `is`, `is_not`
|
|
670
|
+
- `tag`: `contains`, `not_contains`, `is_empty`, `is_not_empty`
|
|
671
|
+
- `email`: `contains`, `not_contains`
|
|
672
|
+
- `emailProvider`, `list`: `is`, `is_not`, `is_empty`, `is_not_empty`
|
|
673
|
+
- `firstName`, `lastName`: `contains`, `not_contains`, `is_empty`, `is_not_empty`
|
|
674
|
+
- `added`: `less_than`, `more_than`
|
|
675
|
+
- `attribute`: `is`, `is_not`, `is_empty`, `is_not_empty`, `gte`, `lte`, `gt`, `lt`, `contains`, `not_contains`
|
|
676
|
+
- `event`, email engagement fields: `is`, `is_not`, `at_least`, `less_than_count`
|
|
677
|
+
- `emailBounced`: also supports `is_temporary_bounce`, `is_permanent_bounce`
|
|
678
|
+
- `stripeProduct`: `is`, `is_not`, `at_least`, `less_than_count`
|
|
679
|
+
- `stripeCurrentProduct`, `stripeTrialProduct`: `is`, `is_not`, `gte`, `lte`, `gt`, `lt`
|
|
680
|
+
- `commerceProduct`: `is`, `is_not`, `at_least`, `less_than_count`
|
|
681
|
+
|
|
682
|
+
Stripe product filter examples:
|
|
683
|
+
|
|
684
|
+
```json
|
|
685
|
+
{ "field": "stripeProduct", "operator": "is", "value": "prod_pro" }
|
|
686
|
+
{ "field": "stripeProduct", "operator": "is_not", "value": "prod_pro" }
|
|
687
|
+
{ "field": "stripeProduct", "operator": "at_least", "value": "prod_pro:3" }
|
|
688
|
+
{ "field": "stripeProduct", "operator": "less_than_count", "value": "prod_pro:3" }
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
Commerce product filters match products purchased through commerce orders. Values can be `provider:productId` for provider-scoped IDs (`shopify`, `woocommerce`, or `api`), a bare product ID to match any provider, or `provider:productId:count` for threshold operators:
|
|
692
|
+
|
|
693
|
+
```json
|
|
694
|
+
{ "field": "commerceProduct", "operator": "is", "value": "api:starter-kit" }
|
|
695
|
+
{ "field": "commerceProduct", "operator": "at_least", "value": "shopify:42:2" }
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
Engagement fields such as `emailSent`, `emailDelivered`, `emailOpened`, `emailClicked`, `emailBounced`, and `emailComplained` accept rolling windows like `7d`, `30d`, `90d`, `180d`, or `all`. Presence operators can scope by delivery policy with `marketing:<timeRange>` (marketing-policy campaign, automation, and Send API traffic) or `transactional:<timeRange>` (transactional-policy sends); policy scopes require a send-time policy snapshot, so ambiguous older automation and Send API events remain available only through unscoped filters. `emailBounced` also supports scoped values with `is_temporary_bounce` and `is_permanent_bounce`. With `at_least` and `less_than_count`, use `count:timeRange`, such as `10:30d` or `10:all`. Presence operators can instead use a campaign scope like `campaign:cmp_123`; campaign and email-type scopes cannot be combined with count operators.
|
|
699
|
+
|
|
700
|
+
### Audience Syncs (Meta Ads)
|
|
701
|
+
|
|
702
|
+
| Tool | Description |
|
|
703
|
+
| ---------------------- | -------------------------------------------------------------------- |
|
|
704
|
+
| `list_audience_syncs` | List segment-to-audience syncs with schedule and last sync status. |
|
|
705
|
+
| `list_ad_accounts` | List the Meta ad accounts available for syncing. |
|
|
706
|
+
| `create_audience_sync` | Push a segment to a Meta custom audience on a schedule. |
|
|
707
|
+
| `update_audience_sync` | Change sync frequency (`hourly`, `daily`, `weekly`) or pause/resume. |
|
|
708
|
+
| `delete_audience_sync` | Remove a sync mapping; the Meta audience itself is kept. |
|
|
709
|
+
| `sync_audience_now` | Trigger an immediate upload outside the regular schedule. |
|
|
710
|
+
|
|
711
|
+
Requires the Meta Ads integration to be connected in the Sequenzy dashboard (Settings -> Integrations). `create_audience_sync` accepts an existing segment (`segmentId`) or a ready-made template (`predefinedSegmentId`, for example `zero-ltv`, `no-purchase-1y`, `recent-buyers`, `high-spenders-ecom`, `non-buyers`, `engaged`) - the template segment is created automatically on first use, and the first upload runs immediately.
|
|
712
|
+
|
|
713
|
+
Audiences are add-only: subscribers who later leave the segment stay in the Meta audience. Meta requires 100+ matched people before an audience can be used for ad delivery.
|
|
714
|
+
|
|
715
|
+
### Templates
|
|
716
|
+
|
|
717
|
+
| Tool | Description |
|
|
718
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
719
|
+
| `list_templates` | List templates with localization status, label and `isTemplate` filtering, and pagination. |
|
|
720
|
+
| `get_template` | Read template details, content, and localized variants. |
|
|
721
|
+
| `create_template` | Create templates from a prompt, HTML, or Sequenzy blocks; use `isTemplate: true` to save a reusable master design. |
|
|
722
|
+
| `update_template` | Update template metadata, inbox preview text, labels, HTML, or blocks; mark or unmark a master with `isTemplate`. |
|
|
723
|
+
| `set_template_localization` | Create or replace a caller-supplied localized variant. |
|
|
724
|
+
| `sync_template_localizations` | Queue AI translation for selected or all enabled non-primary locales. |
|
|
725
|
+
| `delete_template` | Delete a template. |
|
|
726
|
+
|
|
727
|
+
`list_templates` returns 50 email bodies newest first by default and accepts a
|
|
728
|
+
`limit` up to 100. Advance `offset` by `pagination.count` while
|
|
729
|
+
`pagination.hasMore` is true; `pagination.total` reports the full matching
|
|
730
|
+
count, including campaign and transactional-email bodies.
|
|
731
|
+
|
|
732
|
+
Set `isTemplate: true` on `list_templates` to return only saved master designs,
|
|
733
|
+
or `false` to return ordinary email bodies. Marked masters are offered as
|
|
734
|
+
starting points for dashboard sequence steps and campaigns; starting from one creates
|
|
735
|
+
an independent copy so edits leave the master intact.
|
|
736
|
+
|
|
737
|
+
Standalone/sequence source-design copying and AI rewriting within a selected layout are currently
|
|
738
|
+
dashboard-only. This release intentionally keeps those workflows in interactive
|
|
739
|
+
authoring, where users can review the source, translations, and any fallback copy
|
|
740
|
+
before saving a sequence step. REST, CLI, and MCP expose no equivalent standalone/sequence source-design
|
|
741
|
+
operation. `create_template` with `prompt` generates new content without preserving
|
|
742
|
+
an existing layout; supplied HTML or blocks create a new body without automatically
|
|
743
|
+
copying localized variants. See the [interface availability documentation](https://docs.sequenzy.com/concepts/email-templates#availability-across-interfaces).
|
|
744
|
+
|
|
745
|
+
Campaign copies already work through REST `POST /api/v1/campaigns` and MCP
|
|
746
|
+
`create_campaign` with `templateId`; it cannot be combined with `prompt` for an AI rewrite.
|
|
747
|
+
|
|
748
|
+
For net-new content requested in natural language, pass `prompt` so Sequenzy
|
|
749
|
+
generates branded native blocks server-side. Use `blocks` only for finished
|
|
750
|
+
caller-supplied Sequenzy content, and use `html` only when preserving supplied
|
|
751
|
+
or explicitly requested markup. `prompt`, `blocks`, and `html` are mutually
|
|
752
|
+
exclusive; `style` and `tone` are valid only with `prompt`.
|
|
753
|
+
|
|
754
|
+
Use `set_template_localization` when translated copy comes from your own
|
|
755
|
+
localization workflow. It requires an enabled non-primary `locale`, a localized
|
|
756
|
+
`subject`, and exactly one of `html` or `blocks`. Use
|
|
757
|
+
`sync_template_localizations` to ask Sequenzy to translate selected locales;
|
|
758
|
+
omit `locales` to sync every enabled non-primary locale. Explicit sync works
|
|
759
|
+
even when automatic on-save localization is disabled.
|
|
760
|
+
|
|
761
|
+
### Reusable Email Components
|
|
762
|
+
|
|
763
|
+
| Tool | Description |
|
|
764
|
+
| ----------------------------- | ------------------------------------------------------------------------------ |
|
|
765
|
+
| `list_email_components` | List saved sections and footers, optionally limited to pinned defaults. |
|
|
766
|
+
| `get_email_component` | Read one component's blocks, metadata, version, and default-slot state. |
|
|
767
|
+
| `get_default_email_component` | Read the component currently pinned to a default slot such as `footer`. |
|
|
768
|
+
| `set_default_email_component` | Create or replace the company default footer used by newly built block emails. |
|
|
769
|
+
| `create_email_component` | Save a reusable section or footer from a block list. |
|
|
770
|
+
| `update_email_component` | Update component metadata or replace its blocks and increment its version. |
|
|
771
|
+
| `delete_email_component` | Delete a component without changing emails that already copied its blocks. |
|
|
772
|
+
|
|
773
|
+
Components are copied into emails when those emails are built, so later edits
|
|
774
|
+
affect newly built emails rather than rewriting existing content. The default
|
|
775
|
+
footer keeps its unsubscribe link enabled, while transactional rendering hides
|
|
776
|
+
that link. Raw HTML emails keep their own markup and do not receive block
|
|
777
|
+
components; their send-time unsubscribe handling remains unchanged.
|
|
778
|
+
|
|
779
|
+
### A/B Tests
|
|
780
|
+
|
|
781
|
+
| Tool | Description |
|
|
782
|
+
| ------------------------ | ------------------------------------------------------------------------------ |
|
|
783
|
+
| `list_ab_tests` | List A/B tests and variants, optionally scoped by sequence. |
|
|
784
|
+
| `get_ab_test` | Get effective settings, variants, localization status, and sequence-step copy. |
|
|
785
|
+
| `get_ab_test_stats` | Get aggregate and per-variant stats. |
|
|
786
|
+
| `restart_ab_test` | Restart a stopped or completed A/B test. |
|
|
787
|
+
| `select_ab_test_winner` | Select a campaign test winner and queue remaining delivery. |
|
|
788
|
+
| `update_ab_test` | Update campaign or sequence winner-selection settings. |
|
|
789
|
+
| `update_ab_test_variant` | Update campaign draft or sequence variant copy. |
|
|
790
|
+
| `create_ab_test` | Create a campaign test or convert a sequence email step. |
|
|
791
|
+
| `add_ab_test_variant` | Add a variant to an existing A/B test. |
|
|
792
|
+
| `delete_ab_test_variant` | Delete a draft A/B test variant. |
|
|
793
|
+
| `delete_ab_test` | Delete an A/B test. |
|
|
794
|
+
|
|
795
|
+
Use `get_sequence.sequence.emails[].abTest.variants` to discover sequence variant IDs, subjects, preview text, and block counts; call `get_ab_test` to audit every variant's full `blocks`, effective `settings`, localization status, or stats. Campaign settings use `testPercentage`, `testDurationMinutes`, and `winnerCriteria`; sequence settings use `testType`, `winnerThreshold`, and `winnerCriteria`. The legacy sequence values `testPercentage: 100` and `testDurationMinutes: 0` are compatibility sentinels, not runtime settings. `select_ab_test_winner` applies only to a campaign test that is currently testing and immediately queues the winning variant for the remaining audience. `update_ab_test` changes the appropriate settings model and requires `confirmLiveChange: true` when sequence settings affect an active or already-used test. Variant updates accept either `html` or `blocks`, not both.
|
|
796
|
+
|
|
797
|
+
`create_ab_test` accepts exactly one of `campaignId` or `automationNodeId`; the latter requires one to four extra variants and converts a sequence email node into `action_ab_test`. The conversion moves the step's subject, preview text, and blocks onto independent variant emails. Get the test and variant IDs from `get_sequence`, read every variant's copy with `get_ab_test`, and edit each one with `update_ab_test_variant`; `update_sequence_node` and `update_template` cannot edit variant copy, and a change intended for the whole step must be repeated for every variant. If `update_ab_test_variant` is not in the MCP tool list, enable it on the Sequenzy connector rather than writing through another email tool. The full workflow requires `ab_tests:read`, `ab_tests:write`, and `sequences:write`, all included in **Safer agent access**. With only `sequences:read`, `get_sequence` keeps the A/B step and control copy visible but redacts test-record fields and returns an empty variant list. An explicit sequence `winnerCriteria` overrides the `testType` default, so content variants can still be judged by opens. Pass `confirmLiveChange: true` when converting a node in an active sequence. Together with control A, an A/B test supports at most five variants. Sequence variants receive independent email templates and can be edited after creation; once the sequence is active or the test has activity, `update_ab_test_variant` requires `confirmLiveChange: true`. Variants can only be added or removed while the test is a draft, and live-sequence changes also require confirmation because they immediately change the rotation.
|
|
798
|
+
|
|
799
|
+
### Campaigns
|
|
800
|
+
|
|
801
|
+
| Tool | Description |
|
|
802
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
803
|
+
| `list_campaigns` | List paginated campaigns by status or label, including reviewer feedback and delivery-pacing fields for account-wide STO audits. |
|
|
804
|
+
| `get_campaign` | Get details, stats, reviewer feedback, and recorded delivery pacing for a campaign. |
|
|
805
|
+
| `get_campaign_audience` | Resolve saved targeting, missing references, a plain-language summary, and live recipient count. |
|
|
806
|
+
| `list_campaign_goals` | List the conversion goals persisted for one email campaign (SMS is unsupported). |
|
|
807
|
+
| `create_campaign_goal` | Add an event, subscriber-attribute, or tag-applied email-campaign conversion goal. |
|
|
808
|
+
| `update_campaign_goal` | Update a persisted email-campaign conversion goal. |
|
|
809
|
+
| `delete_campaign_goal` | Delete a persisted email-campaign conversion goal. |
|
|
810
|
+
| `list_email_sends` | Search recent delivery history with resource IDs and URLs, optionally scoped to one sequence step. Successful live-test sends are omitted. |
|
|
811
|
+
| `get_email_send` | Inspect a queued, test, sent, suppressed, or failed delivery by durable email-send ID. |
|
|
812
|
+
| `list_recipient_suppressions` | List associated suppressed recipients, including protected global invalid addresses and complaints. |
|
|
813
|
+
| `get_recipient_suppression` | Check local bounce, complaint, email-hygiene, and regional SES suppression for one exact recipient. |
|
|
814
|
+
| `remove_recipient_suppression` | Remove a workspace soft-bounce escalation while preserving global, hard-bounce, and complaint protections. |
|
|
815
|
+
| `create_campaign` | Create a campaign with content, data, and optional From/Reply-To identity overrides. |
|
|
816
|
+
| `update_campaign` | Update a draft campaign, including content, data, identities, audience, and persisted STO configuration. |
|
|
817
|
+
| `schedule_campaign` | Schedule or reschedule a campaign, optionally overriding STO and its 1-24 hour delivery window. |
|
|
818
|
+
| `send_test_email` | Send a test email to one address. |
|
|
819
|
+
| `render_email` | Render exact email-safe HTML and report unresolved tags, including typos hidden by defaults. |
|
|
820
|
+
| `cancel_campaign` | Cancel a scheduled or sending campaign. |
|
|
821
|
+
| `pause_campaign` | Pause a sending campaign. |
|
|
822
|
+
| `resume_campaign` | Resume a paused campaign, optionally spreading delivery over time. |
|
|
823
|
+
| `delete_campaign` | Delete a campaign. |
|
|
824
|
+
| `duplicate_campaign` | Duplicate a campaign into a new draft. |
|
|
825
|
+
| `resend_campaign_to_non_openers` | Create a draft resend for the original audience members who did not open a sent campaign. |
|
|
826
|
+
|
|
827
|
+
Prompt-created campaigns are generated and persisted in one API request and
|
|
828
|
+
remain drafts. Use `templateId`, `blocks`, or `html` only when copying or
|
|
829
|
+
preserving existing content rather than asking the agent to author it. Omit all
|
|
830
|
+
content fields to create an empty draft for later editing.
|
|
831
|
+
|
|
832
|
+
Campaign goals credit recipients who were actually sent that campaign within
|
|
833
|
+
the configured attribution window; an open or click remains the stronger
|
|
834
|
+
last-touch signal when one exists. Event goals require `triggerEventName`,
|
|
835
|
+
subscriber-attribute goals require `attributePath`, and tag-applied goals
|
|
836
|
+
require `triggerTagName`. The campaign attribution window defaults to 168
|
|
837
|
+
hours when omitted.
|
|
838
|
+
|
|
839
|
+
To deliver at the same wall-clock time in every recipient's own timezone, call
|
|
840
|
+
`schedule_campaign` with `sendInRecipientTimezone: true` and an IANA
|
|
841
|
+
`scheduledTimezone` that identifies the wall clock represented by
|
|
842
|
+
`scheduledAt`. Contacts without a stored timezone receive the campaign at the
|
|
843
|
+
`scheduledAt` instant. This mode cannot be combined with recurring or spread
|
|
844
|
+
delivery.
|
|
845
|
+
|
|
846
|
+
Send Time Optimization is configured per campaign, not at the company or
|
|
847
|
+
sequence level. Audit it across campaigns with `list_campaigns`, or inspect one
|
|
848
|
+
campaign with `get_campaign`. Set `sendTimeOptimization` and
|
|
849
|
+
`sendTimeWindowHours` (1-24, default 12) on a draft with `update_campaign`, or
|
|
850
|
+
override them while scheduling with `schedule_campaign`. `spreadOverHours`
|
|
851
|
+
takes precedence and disables STO, as does recipient-timezone delivery.
|
|
852
|
+
Sequences instead use `sendingWindow`, a shared allowed-hours/days gate rather
|
|
853
|
+
than per-recipient predicted send times.
|
|
854
|
+
|
|
855
|
+
For campaign- and sequence-level identities, `fromEmail` plus `fromName`
|
|
856
|
+
selects the sender identity with that display name on the mailbox, creating it
|
|
857
|
+
when needed without renaming other same-address identities. A Reply-To address
|
|
858
|
+
instead has one company-wide saved name: when `replyToName` differs from that
|
|
859
|
+
name, the saved name is kept and the successful response includes recovery
|
|
860
|
+
guidance in `warnings`.
|
|
861
|
+
|
|
862
|
+
`send_email` and `send_test_email` return a durable `emailSendId`. Use
|
|
863
|
+
`list_email_sends` to discover recent IDs by subject/title, recipient, delivery
|
|
864
|
+
status, type, bounce type, or source; pass an ID to `get_email_send` to inspect
|
|
865
|
+
`status`, `errorMessage`, the stored body, and delivery events. Delivery-list
|
|
866
|
+
rows are retained for 14 days. Successful live-test and other test sends are
|
|
867
|
+
omitted so they do not bury real deliveries. Replies to those test sends show
|
|
868
|
+
in `list_conversations` only when inbound reply capture is enabled. Queue jobs
|
|
869
|
+
are internal execution details and
|
|
870
|
+
are not exposed through the MCP contract. Every returned delivery has a direct
|
|
871
|
+
dashboard `url`. Use `list_recipient_suppressions` to distinguish protected
|
|
872
|
+
global invalid-recipient, protected company hard-bounce, and complaint rows from removable company soft-bounce
|
|
873
|
+
escalations, and use `get_recipient_suppression` for the exact regional status.
|
|
874
|
+
`remove_recipient_suppression` removes only the company escalation; global and
|
|
875
|
+
Amazon SES account-level suppressions, complaints, unsubscribes, and email-hygiene
|
|
876
|
+
protections remain intact. A local hygiene result uses the `bounced` reason with
|
|
877
|
+
`email_hygiene` as its source without changing the subscriber's consent status.
|
|
878
|
+
|
|
879
|
+
Agents should pass a caller-owned `idempotencyKey` to `send_email` before the
|
|
880
|
+
first attempt and reuse it for every retry of that same logical email. Sequenzy
|
|
881
|
+
returns the original `emailSendId` for 14 days instead of creating another
|
|
882
|
+
delivery. Reusing the key with different send arguments is rejected, so do not
|
|
883
|
+
generate a fresh key inside a retry loop.
|
|
884
|
+
|
|
885
|
+
Email blocks may use conditional display rules or `conditional-group` branches.
|
|
886
|
+
Conditions support render-time variables and subscriber attributes plus live
|
|
887
|
+
subscriber data such as segment/list membership, tags, events, engagement,
|
|
888
|
+
subscription/SMS status, and Stripe or commerce purchases. Live-data
|
|
889
|
+
conditions use the same field values and operators as segment filters;
|
|
890
|
+
recipients without a stored subscriber match use the OTHERWISE branch.
|
|
891
|
+
|
|
892
|
+
Core block shapes are `{ "type": "heading", "content": "Title", "level": 1
|
|
893
|
+
}`, `{ "type": "text", "content": "<p>Copy</p>" }`, `{ "type": "button",
|
|
894
|
+
"text": "Book a call", "url": "https://example.com", "variant": "primary" }
|
|
895
|
+
`, and `{ "type": "image", "src": "https://...", "alt": "Description",
|
|
896
|
+
"width": 100, "widthType": "percent" }`. Buttons also accept `content` as an
|
|
897
|
+
alias for `text` and default to the `primary` variant. Image `widthType` accepts
|
|
898
|
+
`percent` or `px`.
|
|
899
|
+
|
|
900
|
+
YouTube video blocks accept an optional custom cover: `{ "type": "video",
|
|
901
|
+
"videoUrl": "https://www.youtube.com/watch?v=...", "thumbnailUrl":
|
|
902
|
+
"https://cdn.example.com/cover.jpg", "alt": "Watch the product tour" }`.
|
|
903
|
+
Replacing blocks without `thumbnailUrl` restores YouTube's own still while
|
|
904
|
+
keeping `videoUrl` as the click destination.
|
|
905
|
+
|
|
906
|
+
Raw `html` is stored as one opaque block. It preserves supplied markup but does
|
|
907
|
+
not add a company logo, native branded sections, or theme-driven block design.
|
|
908
|
+
Use `prompt` for a new branded draft or `blocks` for editor-native design; MCP
|
|
909
|
+
authoring results include a warning when raw HTML is used.
|
|
910
|
+
|
|
911
|
+
Use `update_company` with `fromEmail` and/or `replyTo` to set account-wide
|
|
912
|
+
defaults. `fromEmail` must use a configured, verified sending domain; `replyTo`
|
|
913
|
+
may be any valid mailbox. `create_campaign`, `update_campaign`,
|
|
914
|
+
`create_sequence`, and `update_sequence` accept the same direct-address fields
|
|
915
|
+
for resource-specific overrides and create the backing profile when needed.
|
|
916
|
+
Send `fromName` or `replyToName` alone to rename the existing default profile
|
|
917
|
+
without changing its address. When an address has multiple display names, use
|
|
918
|
+
`senderProfileId` or `replyProfileId` from `list_sender_profiles` to select the
|
|
919
|
+
exact profile to make default and rename.
|
|
920
|
+
|
|
921
|
+
`update_company` also manages the company's default email theme through
|
|
922
|
+
`emailTheme` (`presetId`, `colors`, `typography`, `layout`). Theme updates are
|
|
923
|
+
partial - omitted fields keep their current value (or the preset default) and
|
|
924
|
+
numeric values are clamped to supported ranges. Pass `emailTheme: null` to
|
|
925
|
+
reset the company to the platform default theme. Layout settings can control
|
|
926
|
+
the shared `baseRadius` and a separate `buttonRadius`. Within `colors`,
|
|
927
|
+
`background` paints the outer canvas, `content` paints the inner content card,
|
|
928
|
+
and `surface` paints nested cards or tinted tiles. Omitting `content` preserves
|
|
929
|
+
its current value; when no content color is stored, the card follows
|
|
930
|
+
`background`.
|
|
931
|
+
|
|
932
|
+
Reply tracking is available on the same company tools. Use
|
|
933
|
+
`replyTrackingEnabled`, `replyTrackingDomainMode` (`sequenzy` or `custom`), and
|
|
934
|
+
`forwardReplies` with `update_company`. Company reads also return the current
|
|
935
|
+
read-only `replyRetentionDays` value.
|
|
936
|
+
|
|
937
|
+
Polls and NPS surveys are native email blocks, so they work anywhere an email
|
|
938
|
+
tool accepts `blocks`, including campaigns, templates, A/B variants,
|
|
939
|
+
transactional templates, and sequence email steps. Transactional poll sends
|
|
940
|
+
must resolve to exactly one effective recipient after suppression filtering and
|
|
941
|
+
recipient deduplication, and that recipient must already exist as a subscriber;
|
|
942
|
+
otherwise Sequenzy rejects the send because the answer link cannot be safely
|
|
943
|
+
attributed. Use an answer-button poll:
|
|
944
|
+
|
|
945
|
+
```json
|
|
946
|
+
{
|
|
947
|
+
"type": "poll",
|
|
948
|
+
"variant": "options",
|
|
949
|
+
"question": "What did you think of this email?",
|
|
950
|
+
"options": [
|
|
951
|
+
{ "label": "Loved it", "value": "loved" },
|
|
952
|
+
{ "label": "Not for me", "value": "not_for_me" }
|
|
953
|
+
],
|
|
954
|
+
"attributeKey": "email_feedback"
|
|
955
|
+
}
|
|
956
|
+
```
|
|
957
|
+
|
|
958
|
+
For NPS, use `"variant": "nps"`, an empty `options` array, and an attribute
|
|
959
|
+
such as `nps_score`. The scale is always 0-10; optional `npsLowLabel` and
|
|
960
|
+
`npsHighLabel` customize its captions. Each answer updates the subscriber
|
|
961
|
+
attribute and fires `poll.answered` for automations and outbound webhooks.
|
|
962
|
+
|
|
963
|
+
Set `"allowMultiple": true` on a text-only options poll to open a hosted page
|
|
964
|
+
where recipients can check several answers and save the whole selection at
|
|
965
|
+
once. The subscriber attribute stores the selected-value list, so attribute
|
|
966
|
+
segments should use `contains`. Multi-select polls cannot use option images or
|
|
967
|
+
configurations whose encoded signed links exceed the delivery-safe size limit.
|
|
968
|
+
Campaign poll summaries set `allowMultiple: true`, use respondent count for
|
|
969
|
+
`totalResponses`, and can report answer percentages that add up past 100%.
|
|
970
|
+
|
|
971
|
+
Poll blocks also support brand-specific styling. `accentColor` recolors every
|
|
972
|
+
appearance, including `"brutal"`; `optionRadius` sets answer-button corners in
|
|
973
|
+
pixels (`0` is square), independently of the container's
|
|
974
|
+
`styles.borderRadius`; and `questionColor` recolors only the question.
|
|
975
|
+
`fontFamily` applies to the poll. Use the `optionFontSize`,
|
|
976
|
+
`optionFontWeight`, `optionLetterSpacing`, and `optionTextTransform` fields for
|
|
977
|
+
answers, or the matching `question*` fields for the question. Sizes and
|
|
978
|
+
spacing are pixels, weights range from 100 to 900, and text transforms are
|
|
979
|
+
`"none"` or `"uppercase"`.
|
|
980
|
+
|
|
981
|
+
### Saved Forms
|
|
982
|
+
|
|
983
|
+
| Tool | Description |
|
|
984
|
+
| ---------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
985
|
+
| `list_forms` | List saved forms with their server-managed audience settings, content blocks, and public action URLs. |
|
|
986
|
+
| `create_form` | Create and publish a saved form with standard email/name fields, audience settings, theme, and success behavior. |
|
|
987
|
+
| `update_form` | Update a saved form, including its complete ordered block array and typed custom fields. |
|
|
988
|
+
| `get_form_embed` | Return the public action URL, hosted JavaScript, minimal native form, and fetch example for a saved form. |
|
|
989
|
+
|
|
990
|
+
For Astro, Hugo, Jekyll, Cloudflare Pages, Netlify, GitHub Pages, or any other
|
|
991
|
+
static site, call `list_forms`, use `create_form` if a suitable form does not
|
|
992
|
+
exist, then call `get_form_embed`. The returned opaque `formId` is the public
|
|
993
|
+
capability: lists, tags, duplicate behavior, and success handling remain
|
|
994
|
+
server-side, so the deployed browser code never contains a Sequenzy API key.
|
|
995
|
+
Generated native and standalone markup includes "Powered by Sequenzy" for free
|
|
996
|
+
workspaces; paid workspaces receive unbranded markup. The API resolves that
|
|
997
|
+
entitlement server-side, so callers should use the returned snippet unchanged.
|
|
998
|
+
When updating a form, omitted fields remain unchanged and theme fields merge
|
|
999
|
+
into the current theme. Pass an empty `tagIds` array to clear tags or an empty
|
|
1000
|
+
`redirectUrl` to restore confirmation-message behavior. The `blocks` field is
|
|
1001
|
+
a complete replacement, so read the current content with `list_forms` first
|
|
1002
|
+
and retain exactly one required email field and one submit button. Add custom
|
|
1003
|
+
inputs as `form-field` blocks with a supported `fieldType`; select, radio, and
|
|
1004
|
+
checkbox fields require options, while hidden defaults are enforced server-side.
|
|
1005
|
+
|
|
1006
|
+
### Saved Popups
|
|
1007
|
+
|
|
1008
|
+
| Tool | Description |
|
|
1009
|
+
| ----------------- | ------------------------------------------------------------------------------------------------- |
|
|
1010
|
+
| `list_popups` | List saved popups with status and engagement stats, optionally including full content. |
|
|
1011
|
+
| `get_popup` | Get one popup's blocks, trigger, targeting, schedule, frequency, theme, and published embed code. |
|
|
1012
|
+
| `create_popup` | Create a popup from a starting template, published by default, and return its deployment script. |
|
|
1013
|
+
| `update_popup` | Partially update popup copy, audience, behavior, theme, blocks, or publication status. |
|
|
1014
|
+
| `get_popup_embed` | Return secret-free HTML, React/Next.js, WordPress, and Shopify embed snippets. |
|
|
1015
|
+
| `duplicate_popup` | Copy a popup into a draft with independent engagement counters. |
|
|
1016
|
+
| `delete_popup` | Permanently delete a popup and its engagement counters. |
|
|
1017
|
+
|
|
1018
|
+
Popup deployment uses one public script tag; API keys, audience settings,
|
|
1019
|
+
triggering, targeting, scheduling, and frequency rules remain server-side.
|
|
1020
|
+
Popups capture into every list by default unless `listIds` is provided. When
|
|
1021
|
+
updating blocks, read the popup first and send the complete replacement array,
|
|
1022
|
+
retaining exactly one required email field and one submit button. Setting
|
|
1023
|
+
`status` to `draft` stops a popup without invalidating its existing embed code.
|
|
1024
|
+
|
|
1025
|
+
### Landing Pages
|
|
1026
|
+
|
|
1027
|
+
| Tool | Description |
|
|
1028
|
+
| ------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
1029
|
+
| `list_landing_pages` | List landing pages with status, metrics, content, and URLs. |
|
|
1030
|
+
| `get_landing_page` | Get landing page details, builder content, metrics, and published URLs. |
|
|
1031
|
+
| `render_landing_page` | Return a signed 24-hour visitor preview without publishing, counting views, or collecting signups. |
|
|
1032
|
+
| `create_landing_page` | Create a draft landing page from default template content or JSON. |
|
|
1033
|
+
| `update_landing_page` | Edit a landing page name, slug, or full editor-compatible content. |
|
|
1034
|
+
| `publish_landing_page` | Publish a landing page, optionally saving edits first. |
|
|
1035
|
+
| `unpublish_landing_page` | Return a landing page to draft status, optionally saving edits first. |
|
|
1036
|
+
| `duplicate_landing_page` | Duplicate a landing page into a new draft with a unique slug. |
|
|
1037
|
+
| `delete_landing_page` | Delete an unpublished landing page. |
|
|
1038
|
+
| `connect_landing_page_domain` | Connect a custom landing page domain and return DNS setup details. |
|
|
1039
|
+
| `update_landing_page_domain_settings` | Replace or verify landing page custom domain settings. |
|
|
1040
|
+
|
|
1041
|
+
Landing page content uses Sequenzy's editor-compatible JSON schema with
|
|
1042
|
+
`version`, `template`, `seo`, `theme`, and `blocks`. SEO settings include
|
|
1043
|
+
`faviconUrl` and `hideFromSearchEngines`; hidden pages publish a `noindex`
|
|
1044
|
+
directive. Use `render_landing_page` to review the current visitor-facing page
|
|
1045
|
+
before publishing. Its signed `previewUrl` expires after 24 hours, is unlisted,
|
|
1046
|
+
is not indexed, and does not increment page views; forms remain visible but do
|
|
1047
|
+
not collect contacts. Blocks render in slot order:
|
|
1048
|
+
`top`, `hero`, `form`, `body`, then
|
|
1049
|
+
`footer`; use `top` for a full-width announcement or banner above the hero.
|
|
1050
|
+
Button and pricing CTA URLs accept external HTTPS destinations or in-page
|
|
1051
|
+
anchors such as `#form`, `#section-<sectionId>`, `#block-<blockId>`, and
|
|
1052
|
+
`#top`. Set `theme.sectionAnimation` to `none`, `fade`, `slide-up`, or
|
|
1053
|
+
`zoom-in`, with `theme.sectionAnimationSpeed` set to `slow`, `normal`, or
|
|
1054
|
+
`fast`, to control published scroll reveals. Custom landing page subdomains
|
|
1055
|
+
require a CNAME record pointing to `pages.sequenzydns.com`; root domains use an
|
|
1056
|
+
A record pointing to `76.76.21.21`, and their `www` host redirects to the root
|
|
1057
|
+
when its CNAME points to `pages.sequenzydns.com`. Call
|
|
1058
|
+
`update_landing_page_domain_settings` with `verify: true` after DNS changes
|
|
1059
|
+
propagate.
|
|
1060
|
+
|
|
1061
|
+
### Sequences
|
|
1062
|
+
|
|
1063
|
+
| Tool | Description |
|
|
1064
|
+
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1065
|
+
| `list_sequences` | List sequences with dashboard status, search, label, limit, and offset filters. |
|
|
1066
|
+
| `get_sequence` | Get sequence details, A/B variant IDs and block counts with `ab_tests:read`, nodes, edges, linked copy, and the sequence sending window. |
|
|
1067
|
+
| `list_sequence_enrollments` | List contact enrollments with pagination and accurate list/tag/event/time-based entry attribution. Live sequence tests do not create enrollments. |
|
|
1068
|
+
| `send_sequence_test_email` | Send one saved action_email step to 1-10 reviewers; A/B steps are inspected per variant. |
|
|
1069
|
+
| `create_sequence` | Create a blank dashboard draft or an AI-generated/explicit-step sequence. |
|
|
1070
|
+
| `update_sequence` | Update identity, settings, enrollment, existing steps, branch logic, or insert linear steps. |
|
|
1071
|
+
| `update_sequence_node` | Type-aware patch of one existing sequence node. |
|
|
1072
|
+
| `update_sequence_nodes` | Atomically patch multiple existing sequence nodes. |
|
|
1073
|
+
| `insert_sequence_step` | Insert any typed dashboard step, including AI generation, outbound webhooks, waits, and wired branches. |
|
|
1074
|
+
| `edit_sequence_graph` | Move, reconnect, delete, or duplicate graph nodes; reports recipients moved or completed. |
|
|
1075
|
+
| `simulate_sequence` | Dry-run current matches, activation readiness, and an optional contact's branch path without enrolling or sending. |
|
|
1076
|
+
| `enable_sequence` | Activate a sequence. |
|
|
1077
|
+
| `disable_sequence` | Freeze a sequence, blocking new enrollments and holding current recipients. |
|
|
1078
|
+
| `duplicate_sequence` | Create an independent draft copy of the graph, emails, and sequence A/B tests. |
|
|
1079
|
+
| `archive_sequence` | Move a sequence into the dashboard archive and stop new enrollments. |
|
|
1080
|
+
| `unarchive_sequence` | Restore an archived sequence as a disabled draft. |
|
|
1081
|
+
| `list_sequence_goals` | List the event, subscriber-attribute, and tag-applied conversion goals persisted for a sequence. |
|
|
1082
|
+
| `create_sequence_goal` | Add an event, subscriber-attribute, or tag-applied conversion goal. |
|
|
1083
|
+
| `update_sequence_goal` | Update a persisted sequence conversion goal. |
|
|
1084
|
+
| `delete_sequence_goal` | Delete a persisted sequence conversion goal. |
|
|
1085
|
+
| `get_sequence_inbound_webhook` | Read the inbound URL, setup state, sample, and mapping on standard MCP; the OpenAI route removes the credential-bearing URL. |
|
|
1086
|
+
| `configure_sequence_inbound_webhook` | Configure the endpoint, field mapping, and sample; the OpenAI route removes the credential-bearing URL from its result. |
|
|
1087
|
+
| `rotate_sequence_inbound_webhook_secret` | Rotate an inbound sequence endpoint's secret and return its replacement URL on standard MCP; omitted from the OpenAI-reviewed route. |
|
|
1088
|
+
| `pause_sequence_enrollments` | Stop new enrollments for an active sequence while current recipients continue. |
|
|
1089
|
+
| `resume_sequence_enrollments` | Reopen new enrollments for an active sequence without changing current recipients. |
|
|
1090
|
+
| `enroll_subscribers_in_sequence` | Enroll up to 500 subscribers by email, subscriber ID, or both, with retry-safe idempotency. |
|
|
1091
|
+
| `cancel_sequence_enrollments` | Stop active or waiting enrollments by subscriber or entry-event field values. |
|
|
1092
|
+
| `realign_sequence_enrollments` | Preview or queue moving live waits earlier to their sending-window opening. |
|
|
1093
|
+
| `get_sequence_enrollment_realignment` | Poll an applied realignment job and read its completed result or continuation cursor. |
|
|
1094
|
+
| `delete_sequence` | Delete a sequence. |
|
|
1095
|
+
|
|
1096
|
+
Sequence creation supports:
|
|
1097
|
+
|
|
1098
|
+
- Name-only creation for a blank, disabled trigger-to-completion draft matching the dashboard.
|
|
1099
|
+
- Dashboard metadata and delivery settings: `description`, `labels`, `userCancellable`, sequence BCC, and From/Reply-To identity.
|
|
1100
|
+
- `trigger: "contact_added"` with `listId`, several `listIds`, or `listScope`:
|
|
1101
|
+
`any_contact` (the default) enrolls every added contact, including contacts
|
|
1102
|
+
that join no list, while `any_list` waits for an actual list membership.
|
|
1103
|
+
- `trigger: "tag_added"` with `tagName` or several `tagNames`; any configured
|
|
1104
|
+
tag enrolls the contact.
|
|
1105
|
+
- `trigger: "segment_entered"` plus `segmentId` for saved-segment entry automations.
|
|
1106
|
+
- `trigger: "event_received"` plus `{{event.*}}` merge tags in subjects or body content.
|
|
1107
|
+
- `trigger: "inbound_webhook"` plus integration metadata for dashboard-compatible webhook entry nodes.
|
|
1108
|
+
- `trigger: "inactivity"` plus `eventName`, `inactiveDays`, and optional `inactivityBaseline` (`sequence_created_at` or `subscriber_created_at`).
|
|
1109
|
+
- `goal` for AI-generated email content.
|
|
1110
|
+
- `emailStyle: "visual"` or `"plain"` to choose the presentation of goal-based AI-generated emails; when omitted, the company's saved preference is used.
|
|
1111
|
+
- Explicit `steps` with Sequenzy `blocks`.
|
|
1112
|
+
- Explicit `steps` with HTML, which Sequenzy converts into editable blocks.
|
|
1113
|
+
- Explicit Update Subscriber steps that copy trigger-event properties into
|
|
1114
|
+
profile fields or typed custom attributes.
|
|
1115
|
+
- Fixed waits via `delay` / `delayMs`, dynamic date-field waits via `waitUntil`, or calendar gates via `waitUntilWeekday`. A weekday gate such as `{ "day": "sunday", "startTime": "09:00", "endTime": "12:00", "timezone": "America/Los_Angeles" }` holds the flow until the next matching window. Place it immediately before an email to keep that send inside the window; any intervening step can shift delivery outside it. Queue recovery rechecks the window before releasing a delayed contact.
|
|
1116
|
+
- Dynamic Stripe or Shopify discount action steps. A `create_discount` step creates a fresh provider code when each subscriber reaches it; later emails can use merge tags like `{{discount.code}}`, `{{discount.percentOff}}`, and `{{discount.expiresAt}}`.
|
|
1117
|
+
- `enrollmentMode: "matching_field"` and a scalar `enrollmentFieldPath` for product-, variant-, order-, or subscription-specific event automations. Array traversal with `[]` belongs in `propertyFilters`, not the enrollment key.
|
|
1118
|
+
|
|
1119
|
+
For a custom event trigger, the successful `create_sequence` result includes
|
|
1120
|
+
`eventTrackingCode` and a structured `eventTracking` object. The object contains
|
|
1121
|
+
the event endpoint, identity and payload contract, any property path required by
|
|
1122
|
+
`matching_field` enrollment, normalized trigger `propertyFilters`, an example
|
|
1123
|
+
payload, `examplePayloadMatchesFilters`, the direct event API docs URL, and
|
|
1124
|
+
ready-to-use arguments for `get_integration_guide`. If the match status is
|
|
1125
|
+
false, adapt the example using `examplePayloadNote` and the payload contract.
|
|
1126
|
+
Add this event feed and verify its required properties before enabling the draft
|
|
1127
|
+
sequence.
|
|
1128
|
+
|
|
1129
|
+
`list_sequence_enrollments` returns `enteredVia` for each row. List and segment
|
|
1130
|
+
sources keep their stable ID in `value` and resolve a display `name`; tag and
|
|
1131
|
+
event sources retain their names in `value`. Time-based triggers report
|
|
1132
|
+
`inactivity` or `frequency` rather than being misidentified as ordinary
|
|
1133
|
+
received-event enrollments. Live sequence tests do not create enrollments;
|
|
1134
|
+
they send isolated test emails and record activity on the sequence test run
|
|
1135
|
+
instead.
|
|
1136
|
+
|
|
1137
|
+
For a confirmed manual enrollment batch, generate `idempotencyKey` once and
|
|
1138
|
+
reuse that exact key only with identical ordered targets and `targetNodeId`.
|
|
1139
|
+
Receipts last 14 days. A retry returns the original `enrolled`, `skipped`,
|
|
1140
|
+
`notFound`, `targetNodeId`, and `scheduledFor` values with
|
|
1141
|
+
`idempotentReplay: true`; it does not create tokens or queue the batch again.
|
|
1142
|
+
|
|
1143
|
+
Example dynamic Shopify discount step:
|
|
1144
|
+
|
|
1145
|
+
```json
|
|
1146
|
+
{
|
|
1147
|
+
"type": "create_discount",
|
|
1148
|
+
"discount": {
|
|
1149
|
+
"provider": "shopify",
|
|
1150
|
+
"discountType": "percent",
|
|
1151
|
+
"percentOff": 20,
|
|
1152
|
+
"duration": "once",
|
|
1153
|
+
"appliesToAllPlans": true,
|
|
1154
|
+
"maxRedemptions": 1,
|
|
1155
|
+
"codePrefix": "WINBACK"
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
Example Update Subscriber step:
|
|
1161
|
+
|
|
1162
|
+
```json
|
|
1163
|
+
{
|
|
1164
|
+
"type": "update_subscriber",
|
|
1165
|
+
"nodeType": "action_update_attributes",
|
|
1166
|
+
"config": {
|
|
1167
|
+
"firstName": "{{event.firstName}}",
|
|
1168
|
+
"customAttributeUpdates": [
|
|
1169
|
+
{ "name": "plan", "value": "{{event.plan}}", "valueType": "text" },
|
|
1170
|
+
{ "name": "mrr", "value": "{{event.amount}}", "valueType": "number" },
|
|
1171
|
+
{ "name": "active", "value": "{{event.active}}", "valueType": "boolean" }
|
|
1172
|
+
]
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
```
|
|
1176
|
+
|
|
1177
|
+
Number and boolean values must be literals or one standalone merge tag. Use
|
|
1178
|
+
`update_sequence.subscriberUpdateSteps` with an `action_update_attributes`
|
|
1179
|
+
node ID from `get_sequence` to replace an existing step's config.
|
|
1180
|
+
|
|
1181
|
+
Sequence updates support `insertSteps` for adding new linear steps after a `nodeId` returned by `get_sequence`. Omit `afterNodeId` only when appending to a sequence with exactly one linear tail. `insertSteps` supports addable steps that do not require companion records, such as email, delay, tag/list actions, attribute updates, discounts, conditions, wait-for-event steps, outbound webhooks, and AI steps. An `action_ai` step requires a merge-tag `prompt`, unique `resultKey`, and one or more `outputFields`; later steps read generated or fallback text with `{{ai.KEY.field}}`. Combined output-field limits must fit the step's 2000-token response budget. Use `includeTags`, `includeEventProperties`, or `includeAttributes` to opt specific contact context into generation, and `onError` (`continue`, `exit`, or `fail`) to choose failure behavior. Use `branch` for multi-path if/else branches; provide either `branch` or `insertSteps`, not both. Branch conditions support tag presence and absence checks with `has_tag` and `does_not_have_tag`, plus lists, saved segments, events, clicked links, and field comparisons. Each branch path may provide new `steps`, an existing `targetNodeId`, or both; the fallback uses `elseSteps` and/or `elseTargetNodeId`. A target can be the completion node returned by `get_sequence`, so one atomic request can route replies to completion and Else to an existing follow-up. The `emails` and `steps` arrays edit ordinary `action_email` steps by `nodeId`, `emailId`, or array order. `get_sequence.sequence.emails` also includes `action_ab_test` entries; with `ab_tests:read`, each `abTest.variants[]` entry contains the variant ID, subject, preview text, and block count. Call `get_ab_test` for full variant bodies before auditing or rewriting copy. A positional update landing on one is rejected, and its copy must be changed per variant with `update_ab_test_variant`; do not retry through `update_template` or `update_sequence_node`. Use `insertSteps` to create new steps and include a step-level `delay`, `delayMs`, `waitUntil`, or `waitUntilWeekday` when the inserted email needs a timer. `waitUntil` accepts a date field from the trigger event plus optional `offset`, `direction` (`before` or `after`), and `missingAction` (`continue` or `exit`). `waitUntilWeekday` accepts `day` or `days`, `startTime`, optional `endTime` (default `24:00`), and an IANA `timezone`; contacts already inside the window continue immediately. For active sequences, pass `confirmStructuralChange: true` with `insertSteps` or `branch` only after confirming the live-flow impact.
|
|
1182
|
+
|
|
1183
|
+
`insert_sequence_step` exposes every companion-record-free dashboard step directly: email, SMS, delay, discount, subscriber update, tag/list action, outbound webhook, AI generation, condition, wait, and branch. Set `type: "ai"` with `prompt`, `resultKey`, and `outputFields` to generate per-contact text for later `{{ai.KEY.field}}` merge tags. Outbound webhooks accept `url`, `method` (`POST` or `GET`), and string-valued `headers`. Email steps support transactional mode, per-step identity, and CC/BCC delivery settings. For a wait gate, set
|
|
1184
|
+
`type: "logic_wait_for_event"` with `eventName`, optional `timeoutDays` (1-365),
|
|
1185
|
+
and `timeoutAction` (`continue` or `exit`). For a branch, set
|
|
1186
|
+
`type: "logic_branch"`, provide typed `branches`, and wire their targets:
|
|
1187
|
+
|
|
1188
|
+
```json
|
|
1189
|
+
{
|
|
1190
|
+
"sequenceId": "seq_123",
|
|
1191
|
+
"type": "logic_branch",
|
|
1192
|
+
"afterNodeId": "node_email_1",
|
|
1193
|
+
"branches": [
|
|
1194
|
+
{
|
|
1195
|
+
"id": "replied",
|
|
1196
|
+
"conditionType": "event_received",
|
|
1197
|
+
"eventName": "email.replied",
|
|
1198
|
+
"activityScope": "this_sequence",
|
|
1199
|
+
"targetNodeId": "node_complete"
|
|
1200
|
+
}
|
|
1201
|
+
],
|
|
1202
|
+
"elseTargetNodeId": "node_email_2"
|
|
1203
|
+
}
|
|
1204
|
+
```
|
|
1205
|
+
|
|
1206
|
+
Each linked email returned by `get_sequence` includes its effective
|
|
1207
|
+
`emailPreset` (`branded` or `minimal`), matching **Style > Format** in the
|
|
1208
|
+
dashboard. Set `emailPreset` on an `emails`/`steps` item, or in an
|
|
1209
|
+
`action_email` node's `changes`, to change only that linked email without
|
|
1210
|
+
changing the company theme. This applies the same format transformation as the
|
|
1211
|
+
dashboard to native Sequenzy blocks, including emails that contain supported
|
|
1212
|
+
custom HTML blocks. Emails stored entirely as one standalone raw HTML block
|
|
1213
|
+
return `null` for `emailPreset` and do not support format changes.
|
|
1214
|
+
`emailPreset` cannot be combined with `html` or `htmlContent` because those
|
|
1215
|
+
fields replace the entire email with standalone raw HTML.
|
|
1216
|
+
|
|
1217
|
+
For sequence position, prefer `structuralStepNumber` on linked emails and the
|
|
1218
|
+
top level of email nodes. It is derived from the current graph and matches the
|
|
1219
|
+
step badge shown in the dashboard. Parallel branch emails intentionally share
|
|
1220
|
+
the same structural depth, and an unequal branch merge continues from the
|
|
1221
|
+
longer incoming path. The older `stepNumber` field in linked emails and node
|
|
1222
|
+
configs remains a stored ordinal for backward compatibility and may be stale
|
|
1223
|
+
after graph edits.
|
|
1224
|
+
|
|
1225
|
+
Each linked email also returns its stored `emailTheme` override, or `null` when
|
|
1226
|
+
it follows the company theme. Set `emailTheme` on an `emails`/`steps` item or in
|
|
1227
|
+
an `action_email` node's `changes` to restyle only that step. Theme updates are
|
|
1228
|
+
partial patches, so `changes: { "emailTheme": { "colors": {
|
|
1229
|
+
"background": "#f3f4f6", "content": "#ffffff" } } }` gives that email a gray
|
|
1230
|
+
outer canvas and white content card while retaining its other colors,
|
|
1231
|
+
typography, and layout. Omitting either color preserves its current value. Pass
|
|
1232
|
+
`emailTheme: null` to drop the override and follow the company theme again. Use
|
|
1233
|
+
`update_company` only when the account-wide default should change.
|
|
1234
|
+
|
|
1235
|
+
Use `update_sequence_node` for a focused in-place edit, or
|
|
1236
|
+
`update_sequence_nodes` when several node patches must commit atomically. Call
|
|
1237
|
+
`get_sequence` first: every item in `sequence.nodes` includes the node `id`,
|
|
1238
|
+
`nodeType`, current `config`, `updatedAt`, and `updateHints` with editable and
|
|
1239
|
+
managed fields plus the exact concurrency token to return. Pass that token as
|
|
1240
|
+
`expectedUpdatedAt` to reject stale writes. The tools support every stored node
|
|
1241
|
+
type, including delays, email/SMS content, actions, conditions, webhooks,
|
|
1242
|
+
branch configuration without topology changes, and triggers. To change a
|
|
1243
|
+
5-minute delay to 7 days, send `changes: { "delay": { "days": 7 } }` for its
|
|
1244
|
+
`logic_delay` node. To make several founder-style notes Minimal, patch their
|
|
1245
|
+
`action_email` nodes with `changes: { "emailPreset": "minimal" }`. Node-type
|
|
1246
|
+
conversion and edge/path changes belong in `edit_sequence_graph`. Active
|
|
1247
|
+
sequences require `confirmLiveChange: true` after the user confirms the impact;
|
|
1248
|
+
recipients already waiting retain their existing scheduled timestamp.
|
|
1249
|
+
|
|
1250
|
+
Existing and newly inserted email steps can set their own From identity with
|
|
1251
|
+
`senderProfileId` or `fromEmail` plus optional `fromName`, and their Reply-To
|
|
1252
|
+
identity with `replyProfileId` or `replyTo` plus optional `replyToName`. A
|
|
1253
|
+
`fromName` on its own changes only that step's visible sender name. A step-level
|
|
1254
|
+
`replyToName` similarly overrides the visible Reply-To name for that step
|
|
1255
|
+
without renaming the company-wide reply profile. New email steps without
|
|
1256
|
+
explicit identity fields inherit the effective identity of the nearest
|
|
1257
|
+
sequence email. After a branch merge, only identity fields shared by every
|
|
1258
|
+
incoming path are inherited; conflicting fields use the sequence or company
|
|
1259
|
+
defaults.
|
|
1260
|
+
|
|
1261
|
+
Use `edit_sequence_graph` with the latest `graphRevision` from `get_sequence` to restructure an existing sequence atomically. It can move a node before or after another node, reuse the normalized `sequence.edges` array for explicit reconnection or multi-node reordering, delete a node, or deep-copy a node. A/B test duplication creates independent test, variant, email, and localization records with reset statistics. Moving a node before the shared node below a branch reconnects every converging branch path through that node. Deleting a node immediately moves parked recipients to its unique surviving successor, or completes them when no successor remains; inspect `sequence.migratedRecipientCount` and `sequence.completedRecipientCount` in the result. Deletion is refused when parked recipients would have multiple surviving continuations. Stale revisions, invalid branch lanes, cycles, and unreachable nodes are also rejected. Active sequences require `confirmStructuralChange: true`.
|
|
1262
|
+
|
|
1263
|
+
Run `cancel_sequence_enrollments` with `dryRun: true` before applying bulk cancellation.
|
|
1264
|
+
|
|
1265
|
+
Run `realign_sequence_enrollments` after changing a live sequence's sending
|
|
1266
|
+
window when existing email-bound waits should move earlier to the new opening.
|
|
1267
|
+
It defaults to `dryRun: true`. Passing `dryRun: false` queues a background job
|
|
1268
|
+
and returns `jobId`; poll it with `get_sequence_enrollment_realignment`. When a
|
|
1269
|
+
completed result has `hasMore: true`, queue the next bounded apply with its
|
|
1270
|
+
`nextCursor`. Applied realignment changes live delivery times and should only be
|
|
1271
|
+
used after the user confirms the preview.
|
|
1272
|
+
|
|
1273
|
+
### Email Blocks
|
|
1274
|
+
|
|
1275
|
+
| Tool | Description |
|
|
1276
|
+
| ------------------------ | --------------------------------------------------------------------------------------------------------- |
|
|
1277
|
+
| `get_email_block_schema` | List every email block type or inspect one type's required fields, enum values, item shapes, and example. |
|
|
1278
|
+
|
|
1279
|
+
Call `get_email_block_schema` before hand-authoring a block type you have not
|
|
1280
|
+
used before. Omit `blockType` to list every type, pass a type such as `list` or
|
|
1281
|
+
`steps` for its complete reference, or pass `creatableOnly: true` to hide types
|
|
1282
|
+
managed by the editor. Persisted `group` blocks are structural editor content:
|
|
1283
|
+
they recursively wrap child blocks in Stack, Row, Grid, or single-image Overlay
|
|
1284
|
+
layouts, but AI generation and `creatableOnly` intentionally omit them. Request
|
|
1285
|
+
`blockType: "group"` to inspect their fields when reading or updating existing
|
|
1286
|
+
grouped content. Lists are their own block type rather than a `text`
|
|
1287
|
+
variant: `list` items use `content`, while `steps` items use `title` and an
|
|
1288
|
+
optional `description`.
|
|
1289
|
+
|
|
1290
|
+
Tools that accept `blocks` persist per-block visual styling under a block's `styles` object:
|
|
1291
|
+
|
|
1292
|
+
```json
|
|
1293
|
+
{
|
|
1294
|
+
"type": "card",
|
|
1295
|
+
"title": "Your update",
|
|
1296
|
+
"content": "Everything is ready.",
|
|
1297
|
+
"variant": "default",
|
|
1298
|
+
"styles": {
|
|
1299
|
+
"backgroundColor": "#f8fafc",
|
|
1300
|
+
"backgroundOpacity": 85,
|
|
1301
|
+
"borderColor": "#cbd5e1",
|
|
1302
|
+
"borderWidth": 1,
|
|
1303
|
+
"borderRadius": 12
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
```
|
|
1307
|
+
|
|
1308
|
+
For compatibility with older agent prompts, top-level style keys such as `backgroundColor`, `backgroundOpacity`, `borderColor`, `borderWidth`, and `borderRadius` are also accepted and saved under `styles`.
|
|
1309
|
+
|
|
1310
|
+
### Transactional Email
|
|
1311
|
+
|
|
1312
|
+
| Tool | Description |
|
|
1313
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------ |
|
|
1314
|
+
| `list_transactional_emails` | Search/filter templates and sort by delivery metrics; returns subjects and dashboard URLs. |
|
|
1315
|
+
| `get_transactional_email` | Read a transactional email by ID or slug. |
|
|
1316
|
+
| `create_transactional_email` | Create a transactional template from a prompt, HTML, or blocks. |
|
|
1317
|
+
| `update_transactional_email` | Update transactional metadata or body content. |
|
|
1318
|
+
| `send_email` | Send one email by template or HTML to shared To, Cc, and Bcc recipients. |
|
|
1319
|
+
|
|
1320
|
+
Prompt-created transactional templates are generated server-side and default
|
|
1321
|
+
to disabled for review. Explicit HTML or block templates retain the
|
|
1322
|
+
compatibility default of enabled; pass `enabled` explicitly to override either
|
|
1323
|
+
default.
|
|
1324
|
+
|
|
1325
|
+
For a direct send, pass `to`, `subject`, and `html`; the MCP server maps `html`
|
|
1326
|
+
to the transactional API's `body` field. For a saved transactional email, pass
|
|
1327
|
+
its API slug through the compatibility-named `templateId` field instead.
|
|
1328
|
+
For transactional sends, `to`, `cc`, and `bcc` each accept one address or an
|
|
1329
|
+
array of up to 50. The API sends one email with a shared recipient list and
|
|
1330
|
+
removes cross-field duplicates in `to`, then `cc`, then `bcc` priority order.
|
|
1331
|
+
Marketing sends still require exactly one accepted `to` address and do not
|
|
1332
|
+
support additional recipients.
|
|
1333
|
+
`send_email` variables support nested arrays for repeat blocks, such as
|
|
1334
|
+
`{ "event": { "items": [...] } }`. When the recipient matches a stored
|
|
1335
|
+
subscriber by external ID or email, saved first and last names fill omitted name
|
|
1336
|
+
variables automatically. Explicit values, including blanks, take precedence.
|
|
1337
|
+
The optional `attachments` array accepts up to 10 files / 7MB total. Each item
|
|
1338
|
+
needs `filename` and exactly one of Base64 `content` or a public HTTP(S) `path`.
|
|
1339
|
+
Set `contentId` to embed a CID image referenced from the HTML and optionally set
|
|
1340
|
+
`contentType` to override MIME detection.
|
|
1341
|
+
When `trackingSettings` is omitted, the company's Transactional API tracking
|
|
1342
|
+
defaults apply. Use `trackingSettings.clickTracking: false` or
|
|
1343
|
+
`trackingSettings.openTracking: false` to disable link rewriting or the open
|
|
1344
|
+
pixel for one send. These per-send options only opt out; they cannot enable
|
|
1345
|
+
tracking disabled by an account-wide or Transactional API default. Use
|
|
1346
|
+
`get_tracking_settings` and `update_tracking_settings` to inspect or change
|
|
1347
|
+
those defaults.
|
|
1348
|
+
|
|
1349
|
+
For agent and workflow retries, include a stable `idempotencyKey` (up to 255
|
|
1350
|
+
characters) in `send_email`. Use one key per logical email and send the same
|
|
1351
|
+
arguments when retrying; the key remains valid for 14 days.
|
|
1352
|
+
|
|
1353
|
+
### Analytics
|
|
1354
|
+
|
|
1355
|
+
| Tool | Description |
|
|
1356
|
+
| ------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
1357
|
+
| `get_stats` | Get overview stats for `7d`, `30d`, or `90d`; filter by structural email type. |
|
|
1358
|
+
| `get_transactional_stats` | Get all-time or time-scoped metrics for one saved transactional email by ID or slug. |
|
|
1359
|
+
| `get_campaign_stats` | Get campaign performance, reply metrics, attached conversion goals, and Poll/NPS summaries. |
|
|
1360
|
+
| `list_poll_responses` | List each respondent's latest Poll/NPS answer per block, with identity and response time. |
|
|
1361
|
+
| `get_sequence_stats` | Get aggregate and per-step sequence performance plus live active/waiting enrollment counts by current node. |
|
|
1362
|
+
| `list_email_metrics` | Compare campaign and sequence-step funnels, replies, conversions, and revenue, including cross-sequence steps. |
|
|
1363
|
+
| `list_campaign_events` | List paginated raw email events for a campaign. |
|
|
1364
|
+
| `list_sequence_events` | List paginated raw events for a sequence, optionally scoped to one email step. |
|
|
1365
|
+
| `get_subscriber_activity` | Get subscriber email stats, activity, and enrollments. |
|
|
1366
|
+
|
|
1367
|
+
Campaign and sequence event filters accept `transport_failure` alongside
|
|
1368
|
+
delivery, bounce, complaint, engagement, unsubscribe, and delay events.
|
|
1369
|
+
Transport failures describe MTA infrastructure or egress-path exhaustion; they
|
|
1370
|
+
do not classify a valid recipient address as bounced.
|
|
1371
|
+
|
|
1372
|
+
Analytics tools exclude detected bot, scanner, link-preview, and tracked asset opens/clicks by default. Pass `includeMachineEngagement: true` to `get_stats`, `get_campaign_stats`, `get_sequence_stats`, `get_ab_test_stats`, `get_subscriber`, or `get_subscriber_activity` when you need raw engagement diagnostics; included open/click activity rows expose `machine`, `engagementQuality`, and `classificationReasons` fields where the API returns event-level activity.
|
|
1373
|
+
|
|
1374
|
+
`get_sequence_stats.enrollmentCounts` is a live point-in-time snapshot of
|
|
1375
|
+
active and waiting enrollment runs grouped by current node. It counts
|
|
1376
|
+
enrollment tokens rather than necessarily distinct subscribers, and it is not
|
|
1377
|
+
limited by historical `period`, `start`, or `end` filters.
|
|
1378
|
+
|
|
1379
|
+
Use `list_email_metrics` for comparisons across campaigns or sequence steps.
|
|
1380
|
+
Pass `step` with optional `sequenceId` values to total the same step across
|
|
1381
|
+
sequences; use the returned `automationNodeId` with `list_sequence_events` or
|
|
1382
|
+
`list_email_sends` to inspect recipients. `campaignId` cannot be combined with
|
|
1383
|
+
`sequenceId` or `step`. Explicit campaign and sequence scopes retain configured
|
|
1384
|
+
emails with zero activity so weak performers are not silently omitted.
|
|
1385
|
+
|
|
1386
|
+
Pass `emailType: "transactional"` to `get_stats` for Send API and
|
|
1387
|
+
transactional SMTP delivery, open, click, and reply rates. This includes direct
|
|
1388
|
+
and saved-template sends. Use the `emailSendId` returned by `send_email` with
|
|
1389
|
+
`get_email_send` when you need one delivery's status and event timeline.
|
|
1390
|
+
Use `get_transactional_stats` when you need aggregate rates for one saved
|
|
1391
|
+
transactional email. Its response includes top clicked links, complaints,
|
|
1392
|
+
replies, latest permanent/transient bounce classifications, and separate human
|
|
1393
|
+
and machine open/click counts. Direct-content sends do not have a stable
|
|
1394
|
+
template ID and remain available through account transactional stats plus
|
|
1395
|
+
delivery search.
|
|
1396
|
+
|
|
1397
|
+
When a campaign collects Poll or NPS answers, `get_campaign_stats` includes a
|
|
1398
|
+
top-level `polls` array. Each subscriber counts once per poll block using their
|
|
1399
|
+
latest answer. NPS summaries include the score, average, and
|
|
1400
|
+
promoter/passive/detractor counts. These are lifetime response summaries even
|
|
1401
|
+
when engagement metrics use a time filter.
|
|
1402
|
+
|
|
1403
|
+
Use `list_poll_responses` to read who answered what and when. It returns each
|
|
1404
|
+
subscriber's latest answer per poll block, newest first, including the email,
|
|
1405
|
+
stored value, attribute key, and response time. Pass `blockId` to scope one
|
|
1406
|
+
poll; for a sequence email step, pass its automation node ID as `campaignId`.
|
|
1407
|
+
Do not reconstruct this history by scanning subscriber attributes: an
|
|
1408
|
+
attribute has no response timestamp and may have been overwritten by a later
|
|
1409
|
+
email that reused the same key.
|
|
1410
|
+
|
|
1411
|
+
To list the exact historical respondents behind a count, call `create_segment`
|
|
1412
|
+
with field `pollResponse`, operator `is`, and a JSON value scoped to the
|
|
1413
|
+
campaign and the summary's `blockId`:
|
|
1414
|
+
|
|
1415
|
+
```json
|
|
1416
|
+
{
|
|
1417
|
+
"v": 1,
|
|
1418
|
+
"campaignId": "camp_123",
|
|
1419
|
+
"blockId": "poll_1",
|
|
1420
|
+
"match": { "kind": "answer", "value": "loved" }
|
|
1421
|
+
}
|
|
1422
|
+
```
|
|
1423
|
+
|
|
1424
|
+
For NPS, use a match such as
|
|
1425
|
+
`{"kind":"npsBucket","bucket":"detractors"}`; valid buckets are
|
|
1426
|
+
`promoters`, `passives`, and `detractors`. The summary's `attributeKey` stores
|
|
1427
|
+
the subscriber's current/latest response and may be overwritten by a later poll
|
|
1428
|
+
that reuses the key, so it is not an exact historical drill-down.
|
|
1429
|
+
|
|
1430
|
+
### Team, Inbox, Webhooks
|
|
1431
|
+
|
|
1432
|
+
| Tool | Description |
|
|
1433
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
1434
|
+
| `list_team_members` | List team members and pending invitations. |
|
|
1435
|
+
| `invite_team_member` | Invite a teammate as admin or viewer, with optional billing access. |
|
|
1436
|
+
| `cancel_team_invitation` | Cancel a pending team invitation. |
|
|
1437
|
+
| `list_conversations` | List subscriber reply conversations with status and unread filters. |
|
|
1438
|
+
| `get_conversation` | Read a conversation and its message history. |
|
|
1439
|
+
| `reply_to_conversation` | Queue an outbound reply or add an internal note. |
|
|
1440
|
+
| `update_conversation_status` | Open or close a conversation. |
|
|
1441
|
+
| `mark_conversation_read` | Mark all messages in a conversation as read. |
|
|
1442
|
+
| `list_webhooks` | List outbound webhook endpoints. |
|
|
1443
|
+
| `create_webhook` | Create an endpoint and return its one-time signing secret on standard MCP; omitted from the OpenAI-reviewed route. |
|
|
1444
|
+
| `update_webhook` | Update webhook name, URL, events, or status. |
|
|
1445
|
+
| `delete_webhook` | Permanently delete a webhook endpoint and delivery history. |
|
|
1446
|
+
| `test_webhook` | Send a test event to a webhook endpoint. |
|
|
1447
|
+
| `list_webhook_deliveries` | List recent delivery attempts for a webhook. |
|
|
1448
|
+
| `replay_webhook_delivery` | Replay a webhook delivery. |
|
|
1449
|
+
|
|
1450
|
+
Per-list consent changes are available as opt-in outbound events:
|
|
1451
|
+
`subscriber.list_subscribed` and `subscriber.list_unsubscribed`. Their payloads
|
|
1452
|
+
identify the subscriber and list, report `action` as `added` or `removed`, and
|
|
1453
|
+
include the change `source` (for example `preferences_page`, `dashboard`,
|
|
1454
|
+
`api`, or `automation`).
|
|
1455
|
+
|
|
1456
|
+
Use the `email.failed` event for terminal delivery failures such as exhausted
|
|
1457
|
+
MTA transport paths. Recipient bounces continue to use `email.bounced`.
|
|
1458
|
+
|
|
1459
|
+
Use the explicit-only `campaign.sent` event when a workflow needs one terminal
|
|
1460
|
+
notification after an email or SMS campaign settles, including a valid
|
|
1461
|
+
zero-recipient send. It is not added when `create_webhook` omits `events` on
|
|
1462
|
+
standard MCP; on the OpenAI-reviewed route, add it in the dashboard when
|
|
1463
|
+
creating or editing the webhook.
|
|
1464
|
+
|
|
1465
|
+
### AI Generation
|
|
1466
|
+
|
|
1467
|
+
| Tool | Description |
|
|
1468
|
+
| ------------------------ | ----------------------------------------------------------- |
|
|
1469
|
+
| `generate_email` | Generate branded email blocks from a prompt. |
|
|
1470
|
+
| `generate_sequence` | Deprecated alias that persists a goal-based sequence draft. |
|
|
1471
|
+
| `generate_subject_lines` | Generate A/B subject line variants. |
|
|
1472
|
+
|
|
1473
|
+
Generated email content includes the company's logo and footer by default.
|
|
1474
|
+
`generate_email` accepts `applyBranding: false` for raw content blocks and
|
|
1475
|
+
`emailType: "transactional"` for a footer without an unsubscribe link.
|
|
1476
|
+
Prompt-based campaigns inherit the company's configured email font. Generated
|
|
1477
|
+
content is returned as draft content for review. Use `create_sequence` to
|
|
1478
|
+
generate and persist a disabled sequence draft that appears in
|
|
1479
|
+
`list_sequences`; the deprecated `generate_sequence` alias does the same.
|
|
1480
|
+
|
|
1481
|
+
### SMS
|
|
1482
|
+
|
|
1483
|
+
| Tool | Description |
|
|
1484
|
+
| ------------------------- | ------------------------------------------------------------------------------------------- |
|
|
1485
|
+
| `generate_sms` | Generate SMS copy from a prompt. |
|
|
1486
|
+
| `get_sms_settings` | Read SMS add-on readiness, credits, defaults, and provisioned numbers. |
|
|
1487
|
+
| `get_sms_usage` | Compare sends, delivery outcomes, charged credits, last activity, and test sends by number. |
|
|
1488
|
+
| `update_sms_number_label` | Update a number's label or per-number brand-prefix override. |
|
|
1489
|
+
| `release_sms_number` | Permanently return a number to the carrier and free its workspace slot. |
|
|
1490
|
+
| `send_test_sms` | Send a test message, optionally choosing a provisioned sender with `fromNumberId`. |
|
|
1491
|
+
|
|
1492
|
+
`release_sms_number` is irreversible. Campaign or sequence steps pinned to a
|
|
1493
|
+
released number will skip their SMS sends until they are repointed to an active
|
|
1494
|
+
number. `get_sms_usage` reports production totals separately from `testSends`.
|
|
1495
|
+
When `send_test_sms` omits `fromNumberId`, it uses the same oldest-active-number
|
|
1496
|
+
default as production sends. Test sends are real, credit-charged messages that
|
|
1497
|
+
bypass quiet hours and are limited to 100 per company in a rolling 24-hour
|
|
1498
|
+
window.
|
|
1499
|
+
|
|
1500
|
+
### Product Feedback
|
|
1501
|
+
|
|
1502
|
+
Use `submit_feedback` only when the user explicitly asks the assistant to send
|
|
1503
|
+
feedback to the Sequenzy team. Standard MCP can include the structured
|
|
1504
|
+
reproduction fields `userIntent`, `toolCalls`, `expected`, `actual`, and
|
|
1505
|
+
`resourceIds` when needed for that report. The OpenAI-reviewed route accepts
|
|
1506
|
+
only the message, category, and optional generalized workflow context. Do not
|
|
1507
|
+
include unrelated subscriber data, email content, raw API payloads, debug data,
|
|
1508
|
+
or secrets.
|
|
1509
|
+
|
|
1510
|
+
## Resources
|
|
1511
|
+
|
|
1512
|
+
The server also exposes read-only MCP resources.
|
|
1513
|
+
|
|
1514
|
+
| Resource | Description |
|
|
1515
|
+
| -------------------------------- | ---------------------------------------------- |
|
|
1516
|
+
| `sequenzy://dashboard` | Live overview stats for the last 7 days. |
|
|
1517
|
+
| `sequenzy://company` | Current company and localization settings. |
|
|
1518
|
+
| `sequenzy://campaigns/recent` | Last 10 campaigns with status and basic stats. |
|
|
1519
|
+
| `sequenzy://subscribers/recent` | Most recently added subscribers. |
|
|
1520
|
+
| `sequenzy://subscribers/engaged` | Most active or engaged subscribers. |
|
|
1521
|
+
| `sequenzy://sequences` | All sequences with status. |
|
|
1522
|
+
| `sequenzy://templates` | Templates with localization status. |
|
|
1523
|
+
| `sequenzy://segments` | Saved segments with subscriber counts. |
|
|
1524
|
+
| `sequenzy://tags` | Tags with usage counts. |
|
|
1525
|
+
| `sequenzy://health` | Deliverability metrics and health status. |
|
|
1526
|
+
| `sequenzy://email-blocks` | Field reference for every email block type. |
|
|
1527
|
+
| `sequenzy://app-routes` | Dashboard route templates and settings tabs. |
|
|
1528
|
+
|
|
1529
|
+
## Example Prompts
|
|
1530
|
+
|
|
1531
|
+
```text
|
|
1532
|
+
Add john@example.com with tags "vip" and "developer", then put them on the beta list.
|
|
1533
|
+
```
|
|
1534
|
+
|
|
1535
|
+
```text
|
|
1536
|
+
Create a 4-email churn prevention sequence for users whose subscription expires soon. Leave it in draft mode.
|
|
1537
|
+
```
|
|
1538
|
+
|
|
1539
|
+
```text
|
|
1540
|
+
Create a segment for subscribers who bought Stripe product prod_pro at least 3 times.
|
|
1541
|
+
```
|
|
1542
|
+
|
|
1543
|
+
```text
|
|
1544
|
+
Draft a campaign about our new analytics dashboard, target the Pro users segment, and send a test to me.
|
|
1545
|
+
```
|
|
1546
|
+
|
|
1547
|
+
```text
|
|
1548
|
+
How did the last campaign perform compared with the one before it?
|
|
1549
|
+
```
|
|
1550
|
+
|
|
1551
|
+
## Security
|
|
1552
|
+
|
|
1553
|
+
- Use personal API keys, not shared team secrets.
|
|
1554
|
+
- Keys only access companies your Sequenzy user can access.
|
|
1555
|
+
- Revoke keys from Settings -> API Keys when access is no longer needed.
|
|
1556
|
+
- Keep client approval prompts enabled for sends, scheduling, deletes, and bulk changes.
|
|
1557
|
+
- Prefer draft workflows for campaigns and sequences, then review in Sequenzy before launch.
|
|
1558
|
+
|
|
1559
|
+
## Troubleshooting
|
|
1560
|
+
|
|
1561
|
+
### `SEQUENZY_API_KEY environment variable is required`
|
|
1562
|
+
|
|
1563
|
+
Set `SEQUENZY_API_KEY` in the MCP client config, or run:
|
|
1564
|
+
|
|
1565
|
+
```bash
|
|
1566
|
+
npx @sequenzy/setup
|
|
1567
|
+
```
|
|
1568
|
+
|
|
1569
|
+
### Invalid API Key
|
|
1570
|
+
|
|
1571
|
+
Create a new personal key in Settings -> API Keys, update your MCP config, and restart the client.
|
|
1572
|
+
|
|
1573
|
+
### Missing API Key Scope
|
|
1574
|
+
|
|
1575
|
+
Call `get_account` and inspect `apiKeyPermissions`. Local connections should
|
|
1576
|
+
open `apiKeyPermissions.manageUrl`, add the missing scope to the loaded key, and
|
|
1577
|
+
retry without restarting. `update_api_key` can perform this only for company
|
|
1578
|
+
keys that already hold `api_keys:manage`; edit personal keys on the account-level
|
|
1579
|
+
API Keys page. Hosted OAuth connections can alternatively disconnect and
|
|
1580
|
+
reauthorize with broader permissions. The tool error includes the exact scope or
|
|
1581
|
+
scopes required.
|
|
1582
|
+
|
|
1583
|
+
### Duplicate Resources
|
|
1584
|
+
|
|
1585
|
+
If a tool call would create a duplicate segment name or sending domain, the server returns a stable `code`, an agent-friendly `description`, a concrete `resolution`, and a `docsUrl`. For segments, call `list_segments` and reuse the existing segment ID or choose a different name. For websites, call `list_websites`; if the domain is not listed for the selected company, it belongs to another company or account and must be removed, reassigned, or replaced with a different sending domain.
|
|
1586
|
+
|
|
1587
|
+
### Tools Do Not Appear
|
|
1588
|
+
|
|
1589
|
+
- Confirm `npx` is available in the environment the client uses.
|
|
1590
|
+
- Restart the MCP client after editing config.
|
|
1591
|
+
- Check that the config is in the correct client-specific location.
|
|
1592
|
+
|
|
1593
|
+
### Network or API URL Issues
|
|
1594
|
+
|
|
1595
|
+
The server uses `https://api.sequenzy.com` by default. If you override it, verify `SEQUENZY_API_URL` points at a reachable Sequenzy API base URL.
|
|
1596
|
+
|
|
1597
|
+
## Development
|
|
1598
|
+
|
|
1599
|
+
```bash
|
|
1600
|
+
bun install
|
|
1601
|
+
bun test
|
|
1602
|
+
bun run type-check
|
|
1603
|
+
bun run build
|
|
1604
|
+
```
|
|
1605
|
+
|
|
1606
|
+
MCP tool schemas must remain compatible with strict clients:
|
|
1607
|
+
|
|
1608
|
+
- Tool `inputSchema` roots must be plain `type: "object"` schemas.
|
|
1609
|
+
- Do not publish `anyOf` anywhere in tool schemas.
|
|
1610
|
+
- Do not put `oneOf`, `allOf`, `enum`, or `not` at the root of a tool schema.
|
|
1611
|
+
- Enforce conditional requirements in handlers and cover them with tests.
|
|
1612
|
+
|
|
1613
|
+
This standalone repository mirrors the MCP package maintained in the Sequenzy monorepo. Release automation updates it after successful API deployment and package publication. Maintain source, tests and this README in the monorepo `packages/mcp/` directory.
|
|
1614
|
+
|
|
1615
|
+
## License
|
|
1616
|
+
|
|
1617
|
+
MIT
|
|
1618
|
+
|
|
1619
|
+
## Agent-native discovery
|
|
1620
|
+
|
|
1621
|
+
Sequenzy publishes machine-readable manifests for agent networks and A2A-style discovery:
|
|
1622
|
+
|
|
1623
|
+
- Remote MCP endpoint: `https://api.sequenzy.com/v1/mcp`
|
|
1624
|
+
- Agent capability manifest: [`agent-capability.json`](https://github.com/Sequenzy/mcp/blob/main/agent-capability.json)
|
|
1625
|
+
- A2A-style agent card: [`.well-known/agent-card.json`](https://github.com/Sequenzy/mcp/blob/main/.well-known/agent-card.json)
|
|
1626
|
+
- OpenClaw/Moltbot skill metadata: [`openclaw/skill.json`](https://github.com/Sequenzy/mcp/blob/main/openclaw/skill.json)
|
|
1627
|
+
- OpenClaw/Moltbot operating guide: [`openclaw/SKILL.md`](https://github.com/Sequenzy/mcp/blob/main/openclaw/SKILL.md)
|
|
1628
|
+
|
|
1629
|
+
These files describe Sequenzy as an authorized email automation capability for agents. They explicitly exclude scraping, spam, and unsolicited cold outreach use cases.
|
|
1630
|
+
|
|
1631
|
+
## Workspace roles
|
|
1632
|
+
|
|
1633
|
+
Account-key access combines key scopes with your current workspace role. `get_account` reports blocked scopes in `apiKeyPermissions.roleRestrictedScopes`; `canSendLive` means at least one permitted delivery workflow is available, not that every send tool is allowed.
|
|
1634
|
+
|
|
1635
|
+
You can invite a `marketer` to manage subscribers, marketing campaigns and sequences without granting access to transactional mail, workspace settings, team or billing. Marketers choose existing sender/reply profiles. Transactional-backed campaign, A/B and sequence sources remain protected through previews, sharing, analytics and send history. Marketers and restricted members cannot receive billing access.
|
|
1636
|
+
|
|
1637
|
+
### Saved AI email styles
|
|
1638
|
+
|
|
1639
|
+
Use `get_email_ai_style` to inspect the company's saved appearance and `revisionId`. `save_email_ai_style` captures an existing email by its underlying `emailId`; pass `expectedStyleId: null` only for an initial save, or the reviewed revision when replacing. Optional `canvas` captures an unsaved editor snapshot containing `blocks`, `theme`, `fontFamily`, and `emailPreset`. Saving also detects layout habits (for example dotted dividers around every button) and keeps all of them unless `layoutRuleIds` lists the rule IDs to keep (`[]` keeps none); optional `notes` (500 characters max) adds design guidance. Review `style.layout.rules` in the response. `clear_email_ai_style` requires the current nonempty revision.
|
|
1640
|
+
|
|
1641
|
+
Reads require `emails:read`; saves/clears require `emails:write` and the current workspace role. Marketers cannot capture transactional source emails. A 409 conflict requires reading and reviewing the new state before retrying. These tools never edit or send the source email. Generation across all surfaces uses the saved default unless explicit styling or a plain-text choice takes precedence.
|