@myapihq/cli 2.16.2 → 2.16.4
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/dist/commands/domain.d.ts +1 -0
- package/dist/commands/domain.js +13 -0
- package/dist/commands/email/mailbox.d.ts +1 -0
- package/dist/commands/email/mailbox.js +2 -2
- package/dist/commands/email/message.d.ts +1 -0
- package/dist/commands/email/message.js +2 -2
- package/dist/commands/email/template.d.ts +1 -0
- package/dist/commands/email/template.js +2 -2
- package/dist/commands/email/verify.d.ts +1 -0
- package/dist/commands/email/verify.js +7 -0
- package/dist/commands/email/warmup.d.ts +1 -0
- package/dist/commands/email/warmup.js +10 -2
- package/dist/commands/manifest.js +18 -6
- package/dist/skills/my-api-hq/SKILL.md +13 -11
- package/dist/skills/my-crm-api/SKILL.md +10 -10
- package/dist/skills/my-email-api/SKILL.md +19 -3
- package/package.json +2 -2
|
@@ -30,5 +30,6 @@ export declare function retryProvisioning(domainArg: string, flags: Flags): Prom
|
|
|
30
30
|
export declare function mailServerResync(domainArg: string, flags: Flags): Promise<void>;
|
|
31
31
|
export declare function settings(domainArg: string, flags: Flags): Promise<void>;
|
|
32
32
|
export declare function updateSettings(domainArg: string, flags: Flags): Promise<void>;
|
|
33
|
+
export declare const NESTED_SUBCOMMAND_USAGE: Record<string, Record<string, string>>;
|
|
33
34
|
export declare const SUBCOMMAND_USAGE: Record<string, string>;
|
|
34
35
|
export declare function run(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;
|
package/dist/commands/domain.js
CHANGED
|
@@ -549,6 +549,19 @@ Examples:
|
|
|
549
549
|
--content 'v=spf1 include:_spf.mailersend.net include:_spf.google.com ~all'
|
|
550
550
|
myapi domain records create x80security.com --type TXT --name @ \\
|
|
551
551
|
--content 'google-site-verification=...'`;
|
|
552
|
+
// `domain records` is a second level inside a flat command module, so its
|
|
553
|
+
// verbs are invisible to anything reading SUBCOMMAND_USAGE alone — the command
|
|
554
|
+
// manifest could confirm `domain records` and nothing under it. Declared here
|
|
555
|
+
// so `domain records list` can be told apart from `domain records lst`.
|
|
556
|
+
export const NESTED_SUBCOMMAND_USAGE = {
|
|
557
|
+
records: {
|
|
558
|
+
'create': 'myapi domain records create <domain> --type <T> --name <n> --content <c> [--ttl <n>] [--priority <n>] [--proxied]',
|
|
559
|
+
'delete': 'myapi domain records delete <domain> <record-id> [--yes]',
|
|
560
|
+
'get': 'myapi domain records get <domain> <record-id>',
|
|
561
|
+
'list': 'myapi domain records list <domain> [--type A|AAAA|CNAME|MX|TXT]',
|
|
562
|
+
'update': 'myapi domain records update <domain> <record-id> [--content ...] [--ttl ...] [--priority ...] [--proxied]',
|
|
563
|
+
},
|
|
564
|
+
};
|
|
552
565
|
async function recordsRun(sub, args, flags) {
|
|
553
566
|
if (!sub || (flags.help && !sub)) {
|
|
554
567
|
info(RECORDS_HELP);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Flags } from '../../helpers.js';
|
|
2
2
|
import type { Exposes } from '../../exposes.js';
|
|
3
3
|
export declare const EXPOSES: Exposes;
|
|
4
|
+
export declare const SUBCOMMAND_USAGE: Record<string, string>;
|
|
4
5
|
export declare function run(sub: string | undefined, args: string[], flags: Flags): Promise<void>;
|
|
@@ -93,7 +93,7 @@ async function del(address, _flags) {
|
|
|
93
93
|
await sdkEmail.deleteMailbox(config.api_key, address);
|
|
94
94
|
success(`Mailbox deleted: ${address}`);
|
|
95
95
|
}
|
|
96
|
-
const
|
|
96
|
+
export const SUBCOMMAND_USAGE = {
|
|
97
97
|
'create': `myapi email mailbox create <user@domain> [--display-name <name>]
|
|
98
98
|
myapi email mailbox create --username <u> --domain <d> [--display-name <name>]
|
|
99
99
|
|
|
@@ -131,7 +131,7 @@ Subcommands:
|
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
133
|
if (flags.help) {
|
|
134
|
-
const usage =
|
|
134
|
+
const usage = SUBCOMMAND_USAGE[sub];
|
|
135
135
|
if (usage)
|
|
136
136
|
info(`Usage: ${usage}`);
|
|
137
137
|
else
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Flags } from '../../helpers.js';
|
|
2
2
|
import type { Exposes } from '../../exposes.js';
|
|
3
3
|
export declare const EXPOSES: Exposes;
|
|
4
|
+
export declare const SUBCOMMAND_USAGE: Record<string, string>;
|
|
4
5
|
export declare function run(sub: string | undefined, args: string[], flags: Flags): Promise<void>;
|
|
@@ -108,7 +108,7 @@ async function get(messageId, flags) {
|
|
|
108
108
|
const res = await sdkEmail.getMessage(config.api_key, messageId, flags.address);
|
|
109
109
|
printJson(res);
|
|
110
110
|
}
|
|
111
|
-
const
|
|
111
|
+
export const SUBCOMMAND_USAGE = {
|
|
112
112
|
'send': 'myapi email message send --from <email> --to <email> --subject <str> [--body <str> | --html <str> | --template-id <id> [--template-vars <json>]]',
|
|
113
113
|
'status': 'myapi email message status <message_id>',
|
|
114
114
|
'sent': 'myapi email message sent [--limit <n>] [--offset <n>]',
|
|
@@ -130,7 +130,7 @@ Subcommands:
|
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
132
|
if (flags.help) {
|
|
133
|
-
const usage =
|
|
133
|
+
const usage = SUBCOMMAND_USAGE[sub];
|
|
134
134
|
if (usage)
|
|
135
135
|
info(`Usage: ${usage}`);
|
|
136
136
|
else
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Flags } from '../../helpers.js';
|
|
2
2
|
import type { Exposes } from '../../exposes.js';
|
|
3
3
|
export declare const EXPOSES: Exposes;
|
|
4
|
+
export declare const SUBCOMMAND_USAGE: Record<string, string>;
|
|
4
5
|
export declare function run(sub: string | undefined, args: string[], flags: Flags): Promise<void>;
|
|
@@ -118,7 +118,7 @@ async function del(id, flags) {
|
|
|
118
118
|
await sdkEmail.deleteTemplate(config.api_key, orgId, id);
|
|
119
119
|
success(`Deleted template ${id}`);
|
|
120
120
|
}
|
|
121
|
-
const
|
|
121
|
+
export const SUBCOMMAND_USAGE = {
|
|
122
122
|
'generate': `myapi email template generate <name> --prompt <str> [--org <id>]
|
|
123
123
|
myapi email template generate --name <name> --prompt <str> [--org <id>]
|
|
124
124
|
|
|
@@ -147,7 +147,7 @@ All commands accept --org <id> (or set default: myapi config set-org <id>).`);
|
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
149
|
if (flags.help) {
|
|
150
|
-
const usage =
|
|
150
|
+
const usage = SUBCOMMAND_USAGE[sub];
|
|
151
151
|
if (usage)
|
|
152
152
|
info(`Usage: ${usage}`);
|
|
153
153
|
else
|
|
@@ -4,4 +4,5 @@ import type { Exposes } from '../../exposes.js';
|
|
|
4
4
|
export declare const EXPOSES: Exposes;
|
|
5
5
|
export declare const SCHEMA: FlagSchema;
|
|
6
6
|
export declare const VERIFY_HELP = "Usage: myapi email verify <email> [--org <id>] [--json]\n myapi email verify bulk [--quick] [--org <id>] < emails.txt\n myapi email verify job <job_id> [--org <id>] [--json]\n\nSingle-address verification (sync): syntax + DNS + Microsoft probe.\nReturns a verdict in <1s for ~50% of inputs; the rest get\nverdict='unknown' with smtp_recommended=true.\n\nBulk verification (async): reads up to 500 addresses from stdin (one per\nline), starts a job, and prints a job_id. It runs the cheap verdict on\nevery address then SMTP-probes the uncertain ones. --quick skips the\ncatch-all check (faster, but catch-all domains aren't flagged). Poll with\n\"myapi email verify job <job_id>\".\n";
|
|
7
|
+
export declare const SUBCOMMAND_USAGE: Record<string, string>;
|
|
7
8
|
export declare function run(arg: string | undefined, rest: string[], flags?: Flags): Promise<void>;
|
|
@@ -22,6 +22,13 @@ every address then SMTP-probes the uncertain ones. --quick skips the
|
|
|
22
22
|
catch-all check (faster, but catch-all domains aren't flagged). Poll with
|
|
23
23
|
"myapi email verify job <job_id>".
|
|
24
24
|
`;
|
|
25
|
+
// `email verify` takes an address directly, so these are its only two real
|
|
26
|
+
// subcommands. Listed so the command manifest — and the site-copy checker
|
|
27
|
+
// that reads it — can tell `verify bulk` from a typo.
|
|
28
|
+
export const SUBCOMMAND_USAGE = {
|
|
29
|
+
'bulk': 'myapi email verify bulk [--quick] [--org <id>] < emails.txt',
|
|
30
|
+
'job': 'myapi email verify job <job_id> [--org <id>] [--json]',
|
|
31
|
+
};
|
|
25
32
|
async function readStdinLines() {
|
|
26
33
|
if (process.stdin.isTTY) {
|
|
27
34
|
error('No input on stdin. Pipe a newline-separated list of addresses:\n myapi email verify bulk < emails.txt');
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Flags } from '../../helpers.js';
|
|
2
2
|
import type { Exposes } from '../../exposes.js';
|
|
3
3
|
export declare const EXPOSES: Exposes;
|
|
4
|
+
export declare const SUBCOMMAND_USAGE: Record<string, string>;
|
|
4
5
|
export declare function run(sub: string | undefined, args: string[], flags: Flags): Promise<void>;
|
|
@@ -8,13 +8,21 @@ export const EXPOSES = [
|
|
|
8
8
|
'POST /email/warmup/stop',
|
|
9
9
|
'GET /email/warmup/stats/{address}',
|
|
10
10
|
];
|
|
11
|
+
export const SUBCOMMAND_USAGE = {
|
|
12
|
+
'start': 'myapi email warmup start --address <email>',
|
|
13
|
+
'pause': 'myapi email warmup pause --address <email>',
|
|
14
|
+
'resume': 'myapi email warmup resume --address <email>',
|
|
15
|
+
'stop': 'myapi email warmup stop --address <email>',
|
|
16
|
+
'stats': 'myapi email warmup stats --address <email>',
|
|
17
|
+
};
|
|
11
18
|
export async function run(sub, args, flags) {
|
|
12
19
|
if (!sub || (flags.help && !sub)) {
|
|
13
|
-
info(
|
|
20
|
+
info(`Usage: myapi email warmup <${Object.keys(SUBCOMMAND_USAGE).join('|')}> --address <email>`);
|
|
14
21
|
return;
|
|
15
22
|
}
|
|
16
23
|
if (flags.help) {
|
|
17
|
-
|
|
24
|
+
const usage = SUBCOMMAND_USAGE[sub];
|
|
25
|
+
info(usage ? `Usage: ${usage}` : `Unknown warmup subcommand: ${sub}. Run "myapi email warmup --help".`);
|
|
18
26
|
return;
|
|
19
27
|
}
|
|
20
28
|
const config = requireConfig();
|
|
@@ -41,10 +41,17 @@ const MODULE_ALIAS = {
|
|
|
41
41
|
};
|
|
42
42
|
// Commands implemented inline in index.ts, with no module of their own.
|
|
43
43
|
const INLINE = new Set(['completion', 'help', 'install-skills', 'whoami', 'login', 'setup', 'status', 'update', 'doctor']);
|
|
44
|
-
async function
|
|
44
|
+
async function registriesFor(file) {
|
|
45
45
|
const mod = await import(pathToFileURL(file).href).catch(() => null);
|
|
46
46
|
const usage = mod?.SUBCOMMAND_USAGE;
|
|
47
|
-
|
|
47
|
+
const nested = mod?.NESTED_SUBCOMMAND_USAGE;
|
|
48
|
+
return {
|
|
49
|
+
usage: usage && typeof usage === 'object' ? usage : null,
|
|
50
|
+
// A third level inside a flat module — `domain records list`. Namespaces
|
|
51
|
+
// that get a directory of their own (email/, crm/) express this by file
|
|
52
|
+
// layout instead and need no such export.
|
|
53
|
+
nested: nested && typeof nested === 'object' ? nested : null,
|
|
54
|
+
};
|
|
48
55
|
}
|
|
49
56
|
// Shipped code runs from dist/ (.js); the test suite runs the sources (.ts).
|
|
50
57
|
// Matching only .js made the enrichment pass find nothing under vitest and
|
|
@@ -97,7 +104,7 @@ export async function buildManifest(version) {
|
|
|
97
104
|
if (!isModule(f))
|
|
98
105
|
continue;
|
|
99
106
|
const group = f.replace(MODULE_RE, '');
|
|
100
|
-
const usage = await
|
|
107
|
+
const { usage } = await registriesFor(path.join(HERE, ns, f));
|
|
101
108
|
if (!usage)
|
|
102
109
|
continue;
|
|
103
110
|
if (group === 'index') {
|
|
@@ -116,8 +123,8 @@ export async function buildManifest(version) {
|
|
|
116
123
|
continue;
|
|
117
124
|
const base = entry.name.replace(MODULE_RE, '');
|
|
118
125
|
const cmd = MODULE_ALIAS[base] ?? base;
|
|
119
|
-
const usage = await
|
|
120
|
-
if (!usage)
|
|
126
|
+
const { usage, nested } = await registriesFor(path.join(HERE, entry.name));
|
|
127
|
+
if (!usage && !nested)
|
|
121
128
|
continue;
|
|
122
129
|
if (!COMMANDS.includes(cmd)) {
|
|
123
130
|
// Not fatal: `verify.js` backs `email verify`, not a top-level command.
|
|
@@ -125,8 +132,13 @@ export async function buildManifest(version) {
|
|
|
125
132
|
warnings.push(`module "${base}.js" publishes subcommands but "${cmd}" is not a top-level command`);
|
|
126
133
|
continue;
|
|
127
134
|
}
|
|
128
|
-
for (const [sub, u] of Object.entries(usage))
|
|
135
|
+
for (const [sub, u] of Object.entries(usage ?? {}))
|
|
129
136
|
add(`${cmd} ${sub}`, u);
|
|
137
|
+
for (const [sub, subs] of Object.entries(nested ?? {})) {
|
|
138
|
+
add(`${cmd} ${sub}`);
|
|
139
|
+
for (const [leaf, u] of Object.entries(subs))
|
|
140
|
+
add(`${cmd} ${sub} ${leaf}`, u);
|
|
141
|
+
}
|
|
130
142
|
}
|
|
131
143
|
// The spine alone always yields a plausible-looking manifest, so "the
|
|
132
144
|
// enrichment pass found nothing" is invisible unless it is stated. It means
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: my-api-hq
|
|
3
|
-
version: 1.2.
|
|
3
|
+
version: 1.2.1
|
|
4
4
|
description: >
|
|
5
5
|
Auth, organizations, and billing hub. Start here to get an api_key and org_id — every other service depends on both.
|
|
6
6
|
triggers: [api key, account, organization, org, billing, balance, topup, credits, setup, defaults, brand, sync brand, doctor, health check, is my org healthy]
|
|
7
|
-
checksum: sha256-
|
|
7
|
+
checksum: sha256-b4eef3d505e92f2b9fe8dfa45b74d4221e3c646947ebfe8961aa5a2445bfa139
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# MyApiHQ
|
|
@@ -34,27 +34,29 @@ An anonymous account can upgrade at any time via `myapi account link <email>`
|
|
|
34
34
|
| Command | What it does |
|
|
35
35
|
|---|---|
|
|
36
36
|
| `myapi account setup` | Interactive setup: creates account, generates api_key, sets defaults |
|
|
37
|
-
| `myapi status` | Single-screen orientation: account + every resource in the default org. Start here when you don't know what
|
|
37
|
+
| `myapi status` | Single-screen orientation: account + every resource in the default org. Start here when you don't know what exists |
|
|
38
38
|
| `myapi account whoami` | Show current account, default org/funnel, balance, free-tier usage |
|
|
39
|
-
| `myapi account link [email]` | Upgrade anonymous account to registered (or add a
|
|
39
|
+
| `myapi account link [email]` | Upgrade anonymous account to registered (or add a session) |
|
|
40
40
|
| `myapi account switch [index]` | Switch active account |
|
|
41
|
+
| `myapi account import-key` | Import an API key non-interactively (CI, Docker) |
|
|
42
|
+
| `myapi account registrant <set\|get\|clear>` | WHOIS contact info `domain register` requires (ICANN) |
|
|
41
43
|
| `myapi org list` | List all orgs (`*` marks the default) |
|
|
42
44
|
| `myapi org create --name "..."` | Create a new org (`--yes` auto-sets as default) |
|
|
43
45
|
| `myapi org get [id]` | Inspect one org (defaults to current default) |
|
|
44
46
|
| `myapi org update [id]` | Update fields (name, tagline, description, business-sector, logo-url) |
|
|
45
|
-
| `myapi org delete <id>` | Delete an org and cascade (funnels included). Verify
|
|
46
|
-
| `myapi org sync-brand <domain>` | Scrape a live site
|
|
47
|
+
| `myapi org delete <id>` | Delete an org and cascade (funnels included). Verify with `myapi org get <id>` first; `--yes` required non-interactively |
|
|
48
|
+
| `myapi org sync-brand <domain>` | Scrape a live site to auto-fill brand info |
|
|
47
49
|
| `myapi keys list / create / revoke <id>` | Manage API keys (alias `myapi account api-keys`) |
|
|
48
50
|
| `myapi billing balance` | Check balance |
|
|
49
51
|
| `myapi billing topup <amount>` | Top up by dollar amount |
|
|
50
52
|
| `myapi billing history` | Recent transactions |
|
|
51
|
-
| `myapi billing usage [--period month|30d]` | Spend rolled up by service (
|
|
52
|
-
| `myapi billing spend-cap [<amount> | clear] [--period month|day]` | Set/show/clear the account-level spend ceiling
|
|
53
|
-
| `myapi billing auto-recharge [show \| set \| disable]` | Keep the wallet funded
|
|
53
|
+
| `myapi billing usage [--period month|30d]` | Spend rolled up by service (month or trailing 30d) |
|
|
54
|
+
| `myapi billing spend-cap [<amount> | clear] [--period month|day]` | Set/show/clear the account-level spend ceiling |
|
|
55
|
+
| `myapi billing auto-recharge [show \| set \| disable]` | Keep the wallet funded — off-session refill when balance drops below a threshold, capped monthly |
|
|
54
56
|
| `myapi account mailing-address ["<address>"]` | Get or set the account's CAN-SPAM mailing address (required for email send) |
|
|
55
57
|
| `myapi config set-org <id>` / `set-funnel <id>` / `set-domain <name>` | Set CLI defaults |
|
|
56
|
-
| `myapi install-skills` | Install agent
|
|
57
|
-
| `myapi doctor [--verbose] [--json]` | Org-wide health check:
|
|
58
|
+
| `myapi install-skills` | Install agent skills into ~/.claude/, ~/.gemini/, ~/.cursor/ |
|
|
59
|
+
| `myapi doctor [--verbose] [--json]` | Org-wide health check: config/integrity findings + DNS/HTTP probes |
|
|
58
60
|
<!-- generated:end -->
|
|
59
61
|
|
|
60
62
|
## Examples
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: my-crm-api
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.1
|
|
4
4
|
description: >
|
|
5
5
|
The canonical store of engaged contacts + companies for an org. Auto-ingests from inbound webhooks via a configurable dot-path. Fixed lifecycle_stage enum (cold | warm | qualified | customer | churned). Append-only event timeline with reserved kinds. Soft delete + restore. Promote-from-Goldfox closes the discovery → engagement loop.
|
|
6
6
|
triggers: [crm, contact, company, lead, engagement, pipeline, lifecycle, qualified, customer, webhook ingest, promote]
|
|
7
|
-
checksum: sha256-
|
|
7
|
+
checksum: sha256-285ad94b1266588d103119ec139f11f0d19831bcbfd12779130f9fbeaf7f33f5
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# MyCRMAPI
|
|
11
11
|
|
|
12
|
-
The store that closes the funnel.
|
|
12
|
+
The store that closes the funnel. Without CRM the loop ends nowhere: discover people (Goldfox) → audience → email → pixel → form-fill via webhook → … nothing. People who *engage* live nowhere. CRM is where they land.
|
|
13
13
|
|
|
14
14
|
## Capabilities
|
|
15
15
|
<!-- llm:start -->
|
|
@@ -55,7 +55,7 @@ Agents cannot write events directly — the closed enum is intentional. For cust
|
|
|
55
55
|
### Auto-ingest
|
|
56
56
|
|
|
57
57
|
Today (v1):
|
|
58
|
-
- **Webhook**:
|
|
58
|
+
- **Webhook**: set per endpoint via `crm_email_path`, a JSON dot-path. Default `"email"` ingests `{"email":"x@y.com"}`. For Stripe, set `data.object.customer_email`; for GitHub, `sender.email`. Empty string disables ingest.
|
|
59
59
|
|
|
60
60
|
Coming next (backend wiring in progress):
|
|
61
61
|
- **Email**: every `myapi email message send` writes `email_sent`; opens/clicks fire `email_opened`/`email_clicked`
|
|
@@ -63,19 +63,19 @@ Coming next (backend wiring in progress):
|
|
|
63
63
|
|
|
64
64
|
If a contact doesn't exist for the matched email, it's auto-created with `source=` matching the originating service. The contact's company is auto-linked by email domain (creates the company on first sight).
|
|
65
65
|
|
|
66
|
-
**Missing lead? Check `myapi webhook deliveries` before concluding it never arrived.** A deadlock under concurrent ingest could drop the contact *after* the form returned success
|
|
66
|
+
**Missing lead? Check `myapi webhook deliveries` before concluding it never arrived.** A deadlock under concurrent ingest could drop the contact *after* the form returned success (fixed 2026-07-27). Raw payloads are always stored, so the delivery is there even when the contact isn't.
|
|
67
67
|
|
|
68
68
|
### Soft delete + restore
|
|
69
69
|
|
|
70
|
-
`myapi crm contacts delete <id>` sets `deleted_at` but **
|
|
70
|
+
`myapi crm contacts delete <id>` sets `deleted_at` but **keeps the event timeline**. By default soft-deleted contacts are excluded from search — pass `--include-deleted` to see them. Restore with `myapi crm contacts restore <id>`.
|
|
71
71
|
|
|
72
72
|
### Goldfox enrichment (deferred)
|
|
73
73
|
|
|
74
|
-
A contact promoted from Goldfox carries a `goldfox_person_id`. In v2 the GET response will
|
|
74
|
+
A contact promoted from Goldfox carries a `goldfox_person_id`. In v2 the GET response will embed the row as `goldfox_person`; today it is null. Goldfox-only fields are not yet searchable.
|
|
75
75
|
|
|
76
76
|
### Search filter — re-engagement semantics
|
|
77
77
|
|
|
78
|
-
`--max-last-engagement-days N` returns contacts last engaged *more than* N days ago, and intentionally **includes contacts with no engagement at all** (promoted-but-never-emailed Goldfox leads) — the natural targets of a re-engagement campaign. To separate "never tried" from "tried and went cold," layer `--origin goldfox
|
|
78
|
+
`--max-last-engagement-days N` returns contacts last engaged *more than* N days ago, and intentionally **includes contacts with no engagement at all** (promoted-but-never-emailed Goldfox leads) — the natural targets of a re-engagement campaign. `--min-last-engagement-days N` is its complement: engaged *within* N days. `--company-id <id>` narrows to one company. To separate "never tried" from "tried and went cold," layer `--origin goldfox`.
|
|
79
79
|
|
|
80
80
|
### Failure modes
|
|
81
81
|
|
|
@@ -98,13 +98,13 @@ A contact promoted from Goldfox carries a `goldfox_person_id`. In v2 the GET res
|
|
|
98
98
|
| `myapi crm contacts update <id> [--stage ...] [...]` | Patch fields. Stage change emits `stage_changed` event |
|
|
99
99
|
| `myapi crm contacts delete <id>` | Soft delete (events retained) |
|
|
100
100
|
| `myapi crm contacts restore <id>` | Restore a soft-deleted contact |
|
|
101
|
-
| `myapi crm contacts promote <goldfox_person_id>` | Idempotent Goldfox → CRM
|
|
101
|
+
| `myapi crm contacts promote <goldfox_person_id>` | Idempotent Goldfox → CRM promote |
|
|
102
102
|
| `myapi crm contacts events <id> [--kind ...]` | Timeline (newest first), filter by kind |
|
|
103
103
|
|
|
104
104
|
### Companies
|
|
105
105
|
| Command | What it does |
|
|
106
106
|
|---|---|
|
|
107
|
-
| `myapi crm companies list / search / create / get / update / delete / restore` | Same shape as contacts |
|
|
107
|
+
| `myapi crm companies list / search / create / get / update / delete / restore` | Same shape as contacts. `--domain` filters search, `--name` sets display name |
|
|
108
108
|
| `myapi crm companies promote <domain>` | Goldfox company id IS its domain — pass the domain |
|
|
109
109
|
|
|
110
110
|
<!-- generated:end -->
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: my-email-api
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.1
|
|
4
4
|
description: >
|
|
5
5
|
Send transactional and bulk email from your own domain. Create mailboxes, send/receive messages, generate AI templates, and manage warmup.
|
|
6
6
|
triggers: [email, mailbox, send email, transactional email, template, warmup, inbox, outbox, ses, sender reputation]
|
|
7
|
-
checksum: sha256-
|
|
7
|
+
checksum: sha256-18f539fc12dd9e9e8f2abecf518aa1ee70741f85cc26ba0a6a941b9c29d537d8
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# MyEmailAPI
|
|
@@ -24,7 +24,7 @@ A registered domain via **mydomainapi** is the prerequisite — mailboxes need a
|
|
|
24
24
|
<!-- generated:start -->
|
|
25
25
|
| Namespace | Subcommands | Purpose |
|
|
26
26
|
|---|---|---|
|
|
27
|
-
| `email mailbox` | `create`, `list`, `activate-sending` | Create and manage mailboxes |
|
|
27
|
+
| `email mailbox` | `create`, `list`, `delete`, `activate-sending`, `set-forwarding`, `clear-forwarding` | Create and manage mailboxes |
|
|
28
28
|
| `email message` | `send`, `status`, `sent`, `inbox`, `outbox`, `get` | Transactional send + read |
|
|
29
29
|
| `email warmup` | `start`, `stats`, `pause`, `resume`, `stop` | IP/domain warmup for sending reputation |
|
|
30
30
|
| `email template` | `generate`, `list`, `get`, `preview`, `edit`, `send-test`, `delete` | AI-generated HTML templates |
|
|
@@ -60,6 +60,22 @@ myapi email warmup stats --address hello@yourdomain.com
|
|
|
60
60
|
```
|
|
61
61
|
<!-- llm:end -->
|
|
62
62
|
|
|
63
|
+
## Flags worth knowing
|
|
64
|
+
|
|
65
|
+
| Flag | Where | What it does |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `--username` + `--domain` | `mailbox create` | Alternative to the positional `<user@domain>` |
|
|
68
|
+
| `--filter unassigned` | `mailbox list` | Orphaned mailboxes — those whose domain is gone |
|
|
69
|
+
| `--html` | `message send` | Send an HTML body instead of `--body` plain text |
|
|
70
|
+
| `--template-id` + `--template-vars` | `message send` | Send a stored template with a JSON var map, instead of a body |
|
|
71
|
+
| `--name` | `template generate` | Alternative to the positional `<name>` |
|
|
72
|
+
| `--per-day` | `warmup start` | Cap the daily volume the ramp climbs to |
|
|
73
|
+
| `--emails`, `--quick` | `verify bulk` | Addresses inline rather than on stdin; skip the catch-all probe |
|
|
74
|
+
|
|
75
|
+
Forwarding keeps the original: `set-forwarding <user@domain> <forward-to@domain>`
|
|
76
|
+
copies every inbound message to an external address and leaves it in the mailbox.
|
|
77
|
+
`clear-forwarding <user@domain>` stops it.
|
|
78
|
+
|
|
63
79
|
## Notes
|
|
64
80
|
|
|
65
81
|
- A mailbox is uniquely identified by its address (`username@domain`).
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myapihq/cli",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "2.16.
|
|
4
|
+
"version": "2.16.4",
|
|
5
5
|
"description": "MyAPI command-line interface",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"lint:skills:strict": "node scripts/copy-skills.js && node scripts/lint-skills.js --strict"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@myapihq/sdk": "^2.16.
|
|
49
|
+
"@myapihq/sdk": "^2.16.4"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/node": "^25.6.0",
|