conduyt-mcp 4.15.0 → 4.18.0
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
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
MCP server for [Conduyt CRM](https://conduyt.app) — expose your CRM as AI-accessible tools. Covers the core CRM surface (contacts, deals, pipelines, custom fields, automations, messaging, and more); use `conduyt_api_catalog` to discover the full set of 500+ REST endpoints.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 173 Tools
|
|
6
6
|
|
|
7
7
|
### Discovery
|
|
8
8
|
| Tool | Description |
|
|
@@ -270,6 +270,14 @@ MCP server for [Conduyt CRM](https://conduyt.app) — expose your CRM as AI-acce
|
|
|
270
270
|
| `conduyt_update_intake_deals` | Configure automatic deal creation on live intake (webhooks, forms, bookings) |
|
|
271
271
|
| `conduyt_update_master_statuses` | Set the account's custom lead lifecycle statuses |
|
|
272
272
|
|
|
273
|
+
### Reply Capture (inbound email)
|
|
274
|
+
| Tool | Description |
|
|
275
|
+
|------|-------------|
|
|
276
|
+
| `conduyt_reply_capture_get` | Current state: configured/live, capture domain + reply address, pending DNS records, provider health |
|
|
277
|
+
| `conduyt_reply_capture_setup` | Create the receiving subdomain (must be a subdomain of the verified sending domain) and return its DNS records |
|
|
278
|
+
| `conduyt_reply_capture_verify` | Check DNS and promote to live once the provider confirms inbound receiving |
|
|
279
|
+
| `conduyt_reply_capture_remove` | Remove capture (and finish an interrupted removal) — requires `confirm='REMOVE'`; replies to already-sent email are lost |
|
|
280
|
+
|
|
273
281
|
## Setup
|
|
274
282
|
|
|
275
283
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,7 @@ import { registerWorkflowSandboxTools } from "./tools/workflow-sandbox.js";
|
|
|
37
37
|
import { registerPrivacyTools } from "./tools/privacy.js";
|
|
38
38
|
import { registerAccountExportTools } from "./tools/account-exports.js";
|
|
39
39
|
import { registerLifecycleTools } from "./tools/lifecycle.js";
|
|
40
|
+
import { registerReplyCaptureTools } from "./tools/reply-capture.js";
|
|
40
41
|
const apiUrl = process.env.CONDUYT_API_URL;
|
|
41
42
|
const apiKey = process.env.CONDUYT_API_KEY;
|
|
42
43
|
if (!apiUrl || !apiKey) {
|
|
@@ -96,5 +97,6 @@ registerWorkflowSandboxTools(server, client);
|
|
|
96
97
|
registerPrivacyTools(server, client);
|
|
97
98
|
registerAccountExportTools(server, client);
|
|
98
99
|
registerLifecycleTools(server, client);
|
|
100
|
+
registerReplyCaptureTools(server, client);
|
|
99
101
|
const transport = new StdioServerTransport();
|
|
100
102
|
await server.connect(transport);
|
|
@@ -45,6 +45,10 @@ export function registerAutomationTools(server, client) {
|
|
|
45
45
|
schedule: z.string().optional().describe("Updated cron schedule"),
|
|
46
46
|
scheduleTimezone: z.string().optional().describe("Updated timezone"),
|
|
47
47
|
stopOnResponse: z.boolean().optional().describe("Stop drip if contact responds"),
|
|
48
|
+
activeRunPolicy: z
|
|
49
|
+
.enum(["keep", "restart"])
|
|
50
|
+
.optional()
|
|
51
|
+
.describe("What a NEW trigger does when the contact is already mid-sequence: 'keep' (default — skip, existing run keeps its schedule) or 'restart' (cancel the parked run and re-enroll from step 1)"),
|
|
48
52
|
}, async ({ id, ...updates }) => {
|
|
49
53
|
const result = await client.patch(`/api/v1/automations/${id}`, updates);
|
|
50
54
|
return formatResult(result);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { ConduytClient } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Reply capture: the dedicated receiving subdomain that lets replies to CRM
|
|
5
|
+
* emails record and thread against the contact.
|
|
6
|
+
*
|
|
7
|
+
* Lifecycle mirrors the sending domain: create -> DNS records -> verify ->
|
|
8
|
+
* live. It is a strict subdomain of the account's own VERIFIED sending
|
|
9
|
+
* domain (the API refuses anything else — that rule is the cross-tenant
|
|
10
|
+
* fence, not a formatting preference), and only ONE capture domain can be
|
|
11
|
+
* set up at a time.
|
|
12
|
+
*
|
|
13
|
+
* Outcomes that are NORMAL here, not failures to retry blindly:
|
|
14
|
+
* - 409 "already configured" — remove the current one first.
|
|
15
|
+
* - 409 "contact support to reconcile" — the row is in an operator-repair
|
|
16
|
+
* state (a provider create whose response was lost, or a stored provider
|
|
17
|
+
* id that does not resolve to this domain). Support repairs it through a
|
|
18
|
+
* super-admin, session-only endpoint that API keys deliberately cannot
|
|
19
|
+
* reach; do not loop on it.
|
|
20
|
+
* - 429 — the per-account budget (setup/teardown are limited per hour,
|
|
21
|
+
* verification per minute). DNS takes minutes to propagate; wait.
|
|
22
|
+
* - 503 — the shared email-provider allowance is busy with customer sends.
|
|
23
|
+
* Retry in a moment; it says nothing about the domain's health.
|
|
24
|
+
*
|
|
25
|
+
* Removal semantics (#39 drain, shipped 2026-08-07) — branch by state:
|
|
26
|
+
* - LIVE (provider-backed): DRAIN. Sending stops immediately, the
|
|
27
|
+
* address keeps receiving for a 30-day window (late replies still
|
|
28
|
+
* land on the timeline), then it parks. The name is permanently
|
|
29
|
+
* retired — no account can ever set it up again.
|
|
30
|
+
* - LIVE legacy row with no stored provider id: immediate removal, NO
|
|
31
|
+
* drain (threading stops at once); providerCleanup='manual' and the
|
|
32
|
+
* name stays reusable.
|
|
33
|
+
* - DEGRADED (provider reports it can no longer receive): same drain
|
|
34
|
+
* lifecycle and same permanent retirement, but NO delivery guarantee
|
|
35
|
+
* during the window — receiving was already broken.
|
|
36
|
+
* - PENDING setup, a domain the provider has already lost, or a cleanup
|
|
37
|
+
* retry: immediate teardown. The registry row is deleted and the name
|
|
38
|
+
* is NOT retired — it can be reused.
|
|
39
|
+
* Sending-domain removal: every capture row EXCEPT a released tombstone
|
|
40
|
+
* blocks it. Pending/cleanup rows clear through this same remove tool
|
|
41
|
+
* (self-service); draining/parked rows keep blocking until an operator
|
|
42
|
+
* releases them after the drain.
|
|
43
|
+
*/
|
|
44
|
+
export declare function registerReplyCaptureTools(server: McpServer, client: ConduytClient): void;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Reply capture: the dedicated receiving subdomain that lets replies to CRM
|
|
5
|
+
* emails record and thread against the contact.
|
|
6
|
+
*
|
|
7
|
+
* Lifecycle mirrors the sending domain: create -> DNS records -> verify ->
|
|
8
|
+
* live. It is a strict subdomain of the account's own VERIFIED sending
|
|
9
|
+
* domain (the API refuses anything else — that rule is the cross-tenant
|
|
10
|
+
* fence, not a formatting preference), and only ONE capture domain can be
|
|
11
|
+
* set up at a time.
|
|
12
|
+
*
|
|
13
|
+
* Outcomes that are NORMAL here, not failures to retry blindly:
|
|
14
|
+
* - 409 "already configured" — remove the current one first.
|
|
15
|
+
* - 409 "contact support to reconcile" — the row is in an operator-repair
|
|
16
|
+
* state (a provider create whose response was lost, or a stored provider
|
|
17
|
+
* id that does not resolve to this domain). Support repairs it through a
|
|
18
|
+
* super-admin, session-only endpoint that API keys deliberately cannot
|
|
19
|
+
* reach; do not loop on it.
|
|
20
|
+
* - 429 — the per-account budget (setup/teardown are limited per hour,
|
|
21
|
+
* verification per minute). DNS takes minutes to propagate; wait.
|
|
22
|
+
* - 503 — the shared email-provider allowance is busy with customer sends.
|
|
23
|
+
* Retry in a moment; it says nothing about the domain's health.
|
|
24
|
+
*
|
|
25
|
+
* Removal semantics (#39 drain, shipped 2026-08-07) — branch by state:
|
|
26
|
+
* - LIVE (provider-backed): DRAIN. Sending stops immediately, the
|
|
27
|
+
* address keeps receiving for a 30-day window (late replies still
|
|
28
|
+
* land on the timeline), then it parks. The name is permanently
|
|
29
|
+
* retired — no account can ever set it up again.
|
|
30
|
+
* - LIVE legacy row with no stored provider id: immediate removal, NO
|
|
31
|
+
* drain (threading stops at once); providerCleanup='manual' and the
|
|
32
|
+
* name stays reusable.
|
|
33
|
+
* - DEGRADED (provider reports it can no longer receive): same drain
|
|
34
|
+
* lifecycle and same permanent retirement, but NO delivery guarantee
|
|
35
|
+
* during the window — receiving was already broken.
|
|
36
|
+
* - PENDING setup, a domain the provider has already lost, or a cleanup
|
|
37
|
+
* retry: immediate teardown. The registry row is deleted and the name
|
|
38
|
+
* is NOT retired — it can be reused.
|
|
39
|
+
* Sending-domain removal: every capture row EXCEPT a released tombstone
|
|
40
|
+
* blocks it. Pending/cleanup rows clear through this same remove tool
|
|
41
|
+
* (self-service); draining/parked rows keep blocking until an operator
|
|
42
|
+
* releases them after the drain.
|
|
43
|
+
*/
|
|
44
|
+
export function registerReplyCaptureTools(server, client) {
|
|
45
|
+
server.tool("conduyt_reply_capture_get", "Get the account's reply-capture state: whether it is configured and live, the capture domain and reply address, DNS records for a pending setup, and provider health. health='checking' with a healthWarning means the provider is re-checking DNS — capture stays active. degraded=true means the provider can no longer receive on that domain and it must be removed and set up again. needsSupport=true means an operator must reconcile it first. cleanupPending=true means a previous removal did not finish at the provider — call conduyt_reply_capture_remove again to complete it. After a removal: draining=true (with drainEndsAt) means the drain window is open — a domain that was live at removal keeps receiving replies until it closes (one that was degraded has no such guarantee); parked=true means it is retired and inbound-inert. Either way that name is permanently unavailable — use suggestedDomain when setting up again.", {}, async () => {
|
|
46
|
+
const result = await client.get("/api/v1/email-domains/reply-capture");
|
|
47
|
+
return formatResult(result);
|
|
48
|
+
});
|
|
49
|
+
server.tool("conduyt_reply_capture_setup", "Start reply-capture setup: creates the receiving domain at the email provider and returns the DNS records to add. The domain MUST be a strict subdomain of the account's own verified sending domain (omit it to use the suggested 'reply.<sending-domain>'); anything else is refused. Requires a verified sending domain first. After adding the DNS records, call conduyt_reply_capture_verify. A 409 means capture is already configured, a setup is already in progress, the previous one still needs operator reconciliation, or the requested name belongs to a retired (drained/parked) domain — retired names are permanently unavailable, so read suggestedDomain from conduyt_reply_capture_get (e.g. 'reply2.<domain>') instead of retrying the old name.", {
|
|
50
|
+
domain: z
|
|
51
|
+
.string()
|
|
52
|
+
// TRIM BEFORE the emptiness check: the API trims and treats a blank
|
|
53
|
+
// as "omitted", silently creating reply.<sending-domain>. An empty
|
|
54
|
+
// agent variable would then burn mutation quota, take the account's
|
|
55
|
+
// ONE capture slot, and block sending-domain removal. Fail here.
|
|
56
|
+
.trim()
|
|
57
|
+
.min(1, "domain must not be blank — omit it entirely to use the suggested default")
|
|
58
|
+
.optional()
|
|
59
|
+
.describe("Capture subdomain, e.g. 'reply.acme.com'. Must be a subdomain of the account's verified sending domain. Omit to use the suggested default."),
|
|
60
|
+
}, async ({ domain }) => {
|
|
61
|
+
// An absent domain is serialized away, which is exactly how the API
|
|
62
|
+
// reads "use the suggested reply.<sending-domain>".
|
|
63
|
+
const result = await client.post("/api/v1/email-domains/reply-capture", { domain });
|
|
64
|
+
return formatResult(result);
|
|
65
|
+
});
|
|
66
|
+
server.tool("conduyt_reply_capture_verify", "Check the pending reply-capture domain's DNS and promote it to live once the provider reports it verified with inbound receiving in place. Returns verified=false plus the current DNS record states while records are still propagating — that is expected, not an error; poll sparingly (DNS takes minutes, and this endpoint is budgeted per account). Promotion is what turns on inbound matching and the Reply-To on outgoing email.", {}, async () => {
|
|
67
|
+
const result = await client.post("/api/v1/email-domains/reply-capture/verify", {});
|
|
68
|
+
return formatResult(result);
|
|
69
|
+
});
|
|
70
|
+
server.tool("conduyt_reply_capture_remove", "Remove reply capture. Outcome depends on the domain's state. LIVE with a provider-backed setup: it DRAINS — the capture Reply-To stops on new email immediately, but the address keeps receiving for 30 days (drainEndsAt in the response) so late replies to already-sent emails still reach the contact's timeline; after that it parks, and the name is permanently retired (no account can ever set it up again — resuming capture means a NEW subdomain, see suggestedDomain on conduyt_reply_capture_get). LIVE legacy row with no stored provider id: removed immediately with NO drain — reply threading stops at once and the response says providerCleanup='manual' (an operator finishes the provider side); the name stays reusable. DEGRADED: drain lifecycle and permanent retirement, but receiving was already broken, so do NOT promise the 30-day delivery window. PENDING setup, a domain the provider has already lost, or an interrupted-removal retry (cleanupPending): torn down immediately, the row is deleted, and the name stays reusable. Requires an explicit confirm='REMOVE'. Sending-domain removal stays blocked by every capture row except a released tombstone — pending/cleanup rows clear right here, but a draining/parked row keeps blocking until support releases it after the drain.", {
|
|
71
|
+
confirm: z
|
|
72
|
+
.literal("REMOVE")
|
|
73
|
+
.describe("Must be exactly 'REMOVE'. Hard safety gate: sending stops immediately, and a provider-backed live or degraded domain's name is permanently retired — there is no undo on the retirement (a legacy id-less live row instead stops threading at once)."),
|
|
74
|
+
}, async () => {
|
|
75
|
+
const result = await client.del("/api/v1/email-domains/reply-capture");
|
|
76
|
+
return formatResult(result);
|
|
77
|
+
});
|
|
78
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conduyt-mcp",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "MCP server for Conduyt CRM
|
|
3
|
+
"version": "4.18.0",
|
|
4
|
+
"description": "MCP server for Conduyt CRM — expose CRM operations as AI-accessible tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -57,4 +57,4 @@
|
|
|
57
57
|
"tsx": "^4.19.0",
|
|
58
58
|
"@types/node": "^22.0.0"
|
|
59
59
|
}
|
|
60
|
-
}
|
|
60
|
+
}
|
|
@@ -203,7 +203,7 @@
|
|
|
203
203
|
{
|
|
204
204
|
"match": "/api/v1/email-domains",
|
|
205
205
|
"status": "planned",
|
|
206
|
-
"reason": "sending-domain management"
|
|
206
|
+
"reason": "sending-domain management (reply-capture subpaths ARE covered \u2014 see the reply_capture_* tools)"
|
|
207
207
|
},
|
|
208
208
|
{
|
|
209
209
|
"match": "/api/v1/mailbox",
|
|
@@ -501,4 +501,4 @@
|
|
|
501
501
|
"reason": "outbound webhook subscription management (distinct from the inbound /webhooks/ receivers)"
|
|
502
502
|
}
|
|
503
503
|
]
|
|
504
|
-
}
|
|
504
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-
|
|
3
|
-
"toolCount":
|
|
4
|
-
"totalEndpoints":
|
|
2
|
+
"generatedAt": "2026-08-06T22:46:04.536Z",
|
|
3
|
+
"toolCount": 173,
|
|
4
|
+
"totalEndpoints": 842,
|
|
5
5
|
"counts": {
|
|
6
|
-
"covered":
|
|
7
|
-
"excluded":
|
|
8
|
-
"planned":
|
|
6
|
+
"covered": 161,
|
|
7
|
+
"excluded": 248,
|
|
8
|
+
"planned": 433,
|
|
9
9
|
"uncategorized": 0
|
|
10
10
|
},
|
|
11
11
|
"matrix": {
|
|
@@ -297,6 +297,14 @@
|
|
|
297
297
|
"status": "excluded",
|
|
298
298
|
"reason": "super-admin platform operations (Conduyt staff only)"
|
|
299
299
|
},
|
|
300
|
+
"GET /api/v1/admin/reply-capture/reconcile": {
|
|
301
|
+
"status": "excluded",
|
|
302
|
+
"reason": "super-admin platform operations (Conduyt staff only)"
|
|
303
|
+
},
|
|
304
|
+
"POST /api/v1/admin/reply-capture/reconcile": {
|
|
305
|
+
"status": "excluded",
|
|
306
|
+
"reason": "super-admin platform operations (Conduyt staff only)"
|
|
307
|
+
},
|
|
300
308
|
"GET /api/v1/admin/scale-readiness": {
|
|
301
309
|
"status": "excluded",
|
|
302
310
|
"reason": "super-admin platform operations (Conduyt staff only)"
|
|
@@ -1289,6 +1297,10 @@
|
|
|
1289
1297
|
"status": "planned",
|
|
1290
1298
|
"reason": "conversation thread surfaces"
|
|
1291
1299
|
},
|
|
1300
|
+
"POST /api/v1/conversations/:contactId/compliance": {
|
|
1301
|
+
"status": "planned",
|
|
1302
|
+
"reason": "conversation thread surfaces"
|
|
1303
|
+
},
|
|
1292
1304
|
"GET /api/v1/conversations/:contactId/state": {
|
|
1293
1305
|
"status": "planned",
|
|
1294
1306
|
"reason": "conversation thread surfaces"
|
|
@@ -1321,6 +1333,10 @@
|
|
|
1321
1333
|
"status": "excluded",
|
|
1322
1334
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1323
1335
|
},
|
|
1336
|
+
"GET /api/v1/cron/capture-rfc-ids": {
|
|
1337
|
+
"status": "excluded",
|
|
1338
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1339
|
+
},
|
|
1324
1340
|
"GET /api/v1/cron/cleanup-audit-logs": {
|
|
1325
1341
|
"status": "excluded",
|
|
1326
1342
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1373,6 +1389,10 @@
|
|
|
1373
1389
|
"status": "excluded",
|
|
1374
1390
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1375
1391
|
},
|
|
1392
|
+
"GET /api/v1/cron/process-consent-outbox": {
|
|
1393
|
+
"status": "excluded",
|
|
1394
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1395
|
+
},
|
|
1376
1396
|
"GET /api/v1/cron/process-data-model-jobs": {
|
|
1377
1397
|
"status": "excluded",
|
|
1378
1398
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1477,6 +1497,10 @@
|
|
|
1477
1497
|
"status": "excluded",
|
|
1478
1498
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1479
1499
|
},
|
|
1500
|
+
"GET /api/v1/cron/reconcile-reply-capture": {
|
|
1501
|
+
"status": "excluded",
|
|
1502
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1503
|
+
},
|
|
1480
1504
|
"GET /api/v1/cron/recurring-tasks": {
|
|
1481
1505
|
"status": "excluded",
|
|
1482
1506
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -2033,27 +2057,51 @@
|
|
|
2033
2057
|
},
|
|
2034
2058
|
"GET /api/v1/email-domains": {
|
|
2035
2059
|
"status": "planned",
|
|
2036
|
-
"reason": "sending-domain management"
|
|
2060
|
+
"reason": "sending-domain management (reply-capture subpaths ARE covered — see the reply_capture_* tools)"
|
|
2037
2061
|
},
|
|
2038
2062
|
"POST /api/v1/email-domains": {
|
|
2039
2063
|
"status": "planned",
|
|
2040
|
-
"reason": "sending-domain management"
|
|
2064
|
+
"reason": "sending-domain management (reply-capture subpaths ARE covered — see the reply_capture_* tools)"
|
|
2041
2065
|
},
|
|
2042
2066
|
"PATCH /api/v1/email-domains": {
|
|
2043
2067
|
"status": "planned",
|
|
2044
|
-
"reason": "sending-domain management"
|
|
2068
|
+
"reason": "sending-domain management (reply-capture subpaths ARE covered — see the reply_capture_* tools)"
|
|
2045
2069
|
},
|
|
2046
2070
|
"DELETE /api/v1/email-domains": {
|
|
2047
2071
|
"status": "planned",
|
|
2048
|
-
"reason": "sending-domain management"
|
|
2072
|
+
"reason": "sending-domain management (reply-capture subpaths ARE covered — see the reply_capture_* tools)"
|
|
2073
|
+
},
|
|
2074
|
+
"GET /api/v1/email-domains/reply-capture": {
|
|
2075
|
+
"status": "covered",
|
|
2076
|
+
"tools": [
|
|
2077
|
+
"conduyt_reply_capture_get"
|
|
2078
|
+
]
|
|
2079
|
+
},
|
|
2080
|
+
"POST /api/v1/email-domains/reply-capture": {
|
|
2081
|
+
"status": "covered",
|
|
2082
|
+
"tools": [
|
|
2083
|
+
"conduyt_reply_capture_setup"
|
|
2084
|
+
]
|
|
2085
|
+
},
|
|
2086
|
+
"DELETE /api/v1/email-domains/reply-capture": {
|
|
2087
|
+
"status": "covered",
|
|
2088
|
+
"tools": [
|
|
2089
|
+
"conduyt_reply_capture_remove"
|
|
2090
|
+
]
|
|
2091
|
+
},
|
|
2092
|
+
"POST /api/v1/email-domains/reply-capture/verify": {
|
|
2093
|
+
"status": "covered",
|
|
2094
|
+
"tools": [
|
|
2095
|
+
"conduyt_reply_capture_verify"
|
|
2096
|
+
]
|
|
2049
2097
|
},
|
|
2050
2098
|
"GET /api/v1/email-domains/status": {
|
|
2051
2099
|
"status": "planned",
|
|
2052
|
-
"reason": "sending-domain management"
|
|
2100
|
+
"reason": "sending-domain management (reply-capture subpaths ARE covered — see the reply_capture_* tools)"
|
|
2053
2101
|
},
|
|
2054
2102
|
"POST /api/v1/email-domains/verify": {
|
|
2055
2103
|
"status": "planned",
|
|
2056
|
-
"reason": "sending-domain management"
|
|
2104
|
+
"reason": "sending-domain management (reply-capture subpaths ARE covered — see the reply_capture_* tools)"
|
|
2057
2105
|
},
|
|
2058
2106
|
"POST /api/v1/email/send": {
|
|
2059
2107
|
"status": "covered",
|
|
@@ -2455,6 +2503,10 @@
|
|
|
2455
2503
|
"status": "planned",
|
|
2456
2504
|
"reason": "message surfaces beyond send tools"
|
|
2457
2505
|
},
|
|
2506
|
+
"GET /api/v1/messages/:id/media/:mediaIndex": {
|
|
2507
|
+
"status": "planned",
|
|
2508
|
+
"reason": "message surfaces beyond send tools"
|
|
2509
|
+
},
|
|
2458
2510
|
"GET /api/v1/messages/sms/:id": {
|
|
2459
2511
|
"status": "planned",
|
|
2460
2512
|
"reason": "message surfaces beyond send tools"
|