@myapihq/cli 1.1.0-wip.4 → 1.2.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/dist/commands/{email.d.ts → audience.d.ts} +2 -0
- package/dist/commands/audience.js +245 -0
- package/dist/commands/auth.d.ts +5 -2
- package/dist/commands/auth.js +133 -5
- package/dist/commands/billing.d.ts +2 -0
- package/dist/commands/billing.js +18 -1
- package/dist/commands/company.d.ts +6 -0
- package/dist/commands/company.js +149 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +20 -0
- package/dist/commands/crm/companies.d.ts +6 -0
- package/dist/commands/crm/companies.js +193 -0
- package/dist/commands/crm/contacts.d.ts +6 -0
- package/dist/commands/crm/contacts.js +241 -0
- package/dist/commands/crm/index.d.ts +6 -0
- package/dist/commands/crm/index.js +74 -0
- package/dist/commands/database.d.ts +6 -0
- package/dist/commands/database.js +259 -0
- package/dist/commands/domain.d.ts +3 -0
- package/dist/commands/domain.js +67 -1
- package/dist/commands/email/campaign.d.ts +2 -0
- package/dist/commands/email/campaign.js +34 -1
- package/dist/commands/email/index.d.ts +2 -0
- package/dist/commands/email/index.js +9 -0
- package/dist/commands/email/mailbox.d.ts +2 -0
- package/dist/commands/email/mailbox.js +5 -0
- package/dist/commands/email/message.d.ts +2 -0
- package/dist/commands/email/message.js +8 -0
- package/dist/commands/email/template.d.ts +2 -0
- package/dist/commands/email/template.js +54 -0
- package/dist/commands/email/verify.d.ts +7 -0
- package/dist/commands/email/verify.js +52 -0
- package/dist/commands/email/warmup.d.ts +2 -0
- package/dist/commands/email/warmup.js +7 -0
- package/dist/commands/funnel.d.ts +3 -0
- package/dist/commands/funnel.js +31 -0
- package/dist/commands/image.d.ts +2 -0
- package/dist/commands/image.js +43 -9
- package/dist/commands/keys.d.ts +2 -0
- package/dist/commands/keys.js +5 -0
- package/dist/commands/llm.d.ts +6 -0
- package/dist/commands/llm.js +156 -0
- package/dist/commands/org.d.ts +3 -0
- package/dist/commands/org.js +55 -0
- package/dist/commands/people.d.ts +6 -0
- package/dist/commands/people.js +136 -0
- package/dist/commands/pixel.d.ts +11 -3
- package/dist/commands/pixel.js +93 -0
- package/dist/commands/setup.d.ts +2 -0
- package/dist/commands/setup.js +57 -5
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.js +154 -0
- package/dist/commands/storage.d.ts +2 -0
- package/dist/commands/storage.js +14 -2
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.js +3 -0
- package/dist/commands/url.d.ts +7 -2
- package/dist/commands/url.js +6 -0
- package/dist/commands/verify.d.ts +7 -0
- package/dist/commands/verify.js +56 -0
- package/dist/commands/webhook.d.ts +2 -0
- package/dist/commands/webhook.js +31 -6
- package/dist/commands/workflow.d.ts +2 -0
- package/dist/commands/workflow.js +19 -1
- package/dist/completion.d.ts +3 -0
- package/dist/completion.js +78 -0
- package/dist/config.d.ts +2 -0
- package/dist/exposes.d.ts +2 -0
- package/dist/exposes.js +13 -0
- package/dist/exposes.test.js +99 -0
- package/dist/flags.test.js +84 -0
- package/dist/index.js +106 -14
- package/dist/prompt.d.ts +15 -0
- package/dist/prompt.js +27 -0
- package/dist/registrant.d.ts +6 -0
- package/dist/registrant.js +155 -0
- package/dist/services-sync.test.d.ts +1 -0
- package/dist/services-sync.test.js +32 -0
- package/dist/skills/my-api-hq/SKILL.md +51 -45
- package/dist/skills/my-crm-api/README.md +42 -0
- package/dist/skills/my-crm-api/SKILL.md +165 -0
- package/dist/skills/my-crm-api/claude/.claude-plugin/plugin.json +6 -0
- package/dist/skills/my-database-api/README.md +41 -0
- package/dist/skills/my-database-api/SKILL.md +107 -0
- package/dist/skills/my-database-api/claude/.claude-plugin/plugin.json +6 -0
- package/dist/skills/my-domain-api/SKILL.md +53 -26
- package/dist/skills/my-email-verify-api/README.md +33 -0
- package/dist/skills/my-email-verify-api/SKILL.md +91 -0
- package/dist/skills/my-email-verify-api/claude/.claude-plugin/plugin.json +6 -0
- package/dist/skills/my-funnel-api/SKILL.md +41 -37
- package/dist/skills/my-image-api/SKILL.md +48 -44
- package/dist/skills/my-llm-api/README.md +35 -0
- package/dist/skills/my-llm-api/SKILL.md +125 -0
- package/dist/skills/my-llm-api/claude/.claude-plugin/plugin.json +6 -0
- package/dist/skills/my-storage-api/README.md +1 -1
- package/dist/skills/my-storage-api/SKILL.md +44 -54
- package/dist/skills/my-webhook-api/README.md +1 -1
- package/dist/skills/my-webhook-api/SKILL.md +48 -92
- package/dist/skills/my-workflow-api/SKILL.md +46 -115
- package/dist/telemetry.d.ts +12 -0
- package/dist/telemetry.js +80 -0
- package/dist/telemetry.test.d.ts +1 -0
- package/dist/telemetry.test.js +101 -0
- package/package.json +13 -8
- package/dist/commands/email.js +0 -586
- package/dist/skills/my-email-api/README.md +0 -45
- package/dist/skills/my-email-api/SKILL.md +0 -104
- package/dist/skills/my-email-api/claude/.claude-plugin/plugin.json +0 -6
- package/dist/skills/my-email-api/make/.gitkeep +0 -0
- package/dist/skills/my-email-api/n8n/.gitkeep +0 -0
- package/dist/skills/my-email-api/openapi/.gitkeep +0 -0
- package/dist/skills/my-funnel-api/make/.gitkeep +0 -0
- package/dist/skills/my-funnel-api/n8n/.gitkeep +0 -0
- package/dist/skills/my-image-api/make/.gitkeep +0 -0
- package/dist/skills/my-image-api/n8n/.gitkeep +0 -0
- package/dist/skills/my-storage-api/make/.gitkeep +0 -0
- package/dist/skills/my-storage-api/n8n/.gitkeep +0 -0
- package/dist/skills/my-webhook-api/make/.gitkeep +0 -0
- package/dist/skills/my-webhook-api/n8n/.gitkeep +0 -0
- package/dist/skills/my-workflow-api/make/.gitkeep +0 -0
- package/dist/skills/my-workflow-api/n8n/.gitkeep +0 -0
- package/dist/utils.test.js +0 -48
- /package/dist/{utils.test.d.ts → exposes.test.d.ts} +0 -0
- /package/dist/skills/{my-api-hq/make → my-crm-api/openapi}/.gitkeep +0 -0
- /package/dist/skills/{my-api-hq/n8n → my-database-api/openapi}/.gitkeep +0 -0
- /package/dist/skills/{my-domain-api/make → my-email-verify-api/openapi}/.gitkeep +0 -0
- /package/dist/skills/{my-domain-api/n8n → my-llm-api/openapi}/.gitkeep +0 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: my-crm-api
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: >
|
|
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
|
+
triggers: [crm, contact, company, lead, engagement, pipeline, lifecycle, qualified, customer, webhook ingest, promote]
|
|
7
|
+
checksum: sha256-pending
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# MyCRMAPI
|
|
11
|
+
|
|
12
|
+
The store that closes the funnel. Today's loop without CRM: discover people (Goldfox) → save audience → send email → track pixel → form-fill via webhook → … nothing. People who *engage* live nowhere. CRM is where they land — automatically.
|
|
13
|
+
|
|
14
|
+
## Capabilities
|
|
15
|
+
<!-- llm:start -->
|
|
16
|
+
|
|
17
|
+
### Where CRM sits in the stack
|
|
18
|
+
|
|
19
|
+
- **mypeopleapi / mycompanyapi** — read-only Goldfox global lead universe (the crawl)
|
|
20
|
+
- **myaudienceapi** — saved filter snapshots over Goldfox
|
|
21
|
+
- **mycrmapi** — engaged contacts + companies, *private to your org*, with engagement history
|
|
22
|
+
|
|
23
|
+
A Goldfox row becomes a CRM contact when:
|
|
24
|
+
1. You explicitly **promote** it (`myapi crm contacts promote <goldfox_person_id>`)
|
|
25
|
+
2. *Or* a downstream service receives engagement for that email and auto-upserts the contact
|
|
26
|
+
|
|
27
|
+
### Lifecycle stages (fixed enum — same for contacts and companies)
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
cold | warm | qualified | customer | churned
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Move stage with `myapi crm contacts update <id> --stage qualified`. Every stage change emits a `stage_changed` event with `{from, to}` so the timeline shows the journey.
|
|
34
|
+
|
|
35
|
+
### Contact sources (fixed enum)
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
goldfox | email | pixel | webhook | manual
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Set automatically based on how the contact entered the CRM. Useful filter when you want "only contacts I've personally added" (`--source manual`) vs "warmed via Goldfox outreach" (`--source goldfox`).
|
|
42
|
+
|
|
43
|
+
### Event timeline — reserved kinds
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
created | promoted | stage_changed
|
|
47
|
+
email_sent | email_opened | email_clicked | email_replied
|
|
48
|
+
pixel_visit | webhook_received
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Agents cannot write events directly — the closed enum is intentional. If you need custom state, use **mydatabaseapi** (KV) keyed on the contact id; the curated timeline stays authoritative for engagement.
|
|
52
|
+
|
|
53
|
+
**Engagement-event kinds bump `last_engagement_at`**: email_sent/opened/clicked/replied, pixel_visit, webhook_received. Admin kinds (created, promoted, stage_changed) don't. That's the right semantics — promoting a Goldfox lead into the CRM is not engagement.
|
|
54
|
+
|
|
55
|
+
### Auto-ingest
|
|
56
|
+
|
|
57
|
+
Today (v1):
|
|
58
|
+
- **Webhook**: configurable 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 for that endpoint.
|
|
59
|
+
|
|
60
|
+
Coming next (backend wiring in progress):
|
|
61
|
+
- **Email**: every `myapi email message send` writes `email_sent`; opens/clicks fire `email_opened`/`email_clicked`
|
|
62
|
+
- **Pixel**: `identify` calls with an email write `pixel_visit`
|
|
63
|
+
|
|
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
|
+
|
|
66
|
+
### Soft delete + restore
|
|
67
|
+
|
|
68
|
+
`myapi crm contacts delete <id>` sets `deleted_at` but **retains 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>`.
|
|
69
|
+
|
|
70
|
+
### Goldfox enrichment (deferred)
|
|
71
|
+
|
|
72
|
+
A CRM contact promoted from Goldfox carries a `goldfox_person_id` reference. In v2 the GET response will join to Goldfox live, embedding the latest row inline as `goldfox_person`. Today that field is null until the BQ get-by-id helper lands. Search filters that hit Goldfox-only fields are not yet wired into CRM search.
|
|
73
|
+
|
|
74
|
+
### Search filter — re-engagement semantics
|
|
75
|
+
|
|
76
|
+
`--max-last-engagement-days N` returns contacts last engaged *more than* N days ago. This intentionally **includes contacts with no engagement at all** (promoted-but-never-emailed Goldfox leads), because those are exactly the natural targets of a re-engagement campaign. If you want to distinguish "never tried" from "tried and went cold," layer `--source goldfox` (never engaged after promotion) or post-filter the JSON.
|
|
77
|
+
|
|
78
|
+
### Failure modes
|
|
79
|
+
|
|
80
|
+
- `404 CONTACT_NOT_FOUND` / `COMPANY_NOT_FOUND`
|
|
81
|
+
- `409` on duplicate email/domain in the same org
|
|
82
|
+
- `400 INVALID_STAGE` if you pass a value outside the enum
|
|
83
|
+
- `400 GOLDFOX_PERSON_NOT_FOUND` on promote with an unknown id
|
|
84
|
+
<!-- llm:end -->
|
|
85
|
+
|
|
86
|
+
## Commands
|
|
87
|
+
<!-- generated:start -->
|
|
88
|
+
|
|
89
|
+
### Contacts
|
|
90
|
+
| Command | What it does |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `myapi crm contacts list [--limit N]` | List all contacts (newest engagement first) |
|
|
93
|
+
| `myapi crm contacts search [--stage ...] [--source ...] [--email ...] [--min/max-last-engagement-days N]` | Filter contacts |
|
|
94
|
+
| `myapi crm contacts create <email> [--first-name ...] [--last-name ...] [--stage ...] [--custom-json ...]` | Manually create (source='manual') |
|
|
95
|
+
| `myapi crm contacts get <id>` | Fetch one contact (with embedded Goldfox enrichment when available) |
|
|
96
|
+
| `myapi crm contacts update <id> [--stage ...] [...]` | Patch fields. Stage change emits `stage_changed` event |
|
|
97
|
+
| `myapi crm contacts delete <id>` | Soft delete (events retained) |
|
|
98
|
+
| `myapi crm contacts restore <id>` | Restore a soft-deleted contact |
|
|
99
|
+
| `myapi crm contacts promote <goldfox_person_id>` | Idempotent Goldfox → CRM promotion |
|
|
100
|
+
| `myapi crm contacts events <id> [--kind ...]` | Timeline (newest first), filter by kind |
|
|
101
|
+
|
|
102
|
+
### Companies
|
|
103
|
+
| Command | What it does |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `myapi crm companies list / search / create / get / update / delete / restore` | Same shape as contacts |
|
|
106
|
+
| `myapi crm companies promote <domain>` | Goldfox company id IS its domain — pass the domain |
|
|
107
|
+
|
|
108
|
+
<!-- generated:end -->
|
|
109
|
+
|
|
110
|
+
All commands accept `--org <id>` (or set default: `myapi config set-org <id>`) and `--json` for machine-readable output.
|
|
111
|
+
|
|
112
|
+
## Examples
|
|
113
|
+
<!-- llm:start -->
|
|
114
|
+
```bash
|
|
115
|
+
# Discover → promote → engage workflow
|
|
116
|
+
myapi people search --keyword saas --has-c-level --country US --limit 5 --json \
|
|
117
|
+
| jq -r '.people[].id' \
|
|
118
|
+
| while read pid; do myapi crm contacts promote "$pid"; done
|
|
119
|
+
|
|
120
|
+
# Find everyone in 'qualified' for a follow-up email
|
|
121
|
+
myapi crm contacts search --stage qualified --json | jq -r '.contacts[].email'
|
|
122
|
+
|
|
123
|
+
# Re-engagement: contacts last engaged > 30 days ago (or never engaged at all)
|
|
124
|
+
myapi crm contacts search --max-last-engagement-days 30
|
|
125
|
+
|
|
126
|
+
# Manual add + tag with custom fields
|
|
127
|
+
myapi crm contacts create alice@acme.com \
|
|
128
|
+
--first-name Alice --stage warm \
|
|
129
|
+
--custom-json '{"intro_via":"riccardo","topic":"video editing"}'
|
|
130
|
+
|
|
131
|
+
# Update stage as the deal progresses — emits a stage_changed event
|
|
132
|
+
myapi crm contacts update <id> --stage qualified
|
|
133
|
+
myapi crm contacts update <id> --stage customer
|
|
134
|
+
|
|
135
|
+
# See the full engagement timeline
|
|
136
|
+
myapi crm contacts events <id>
|
|
137
|
+
|
|
138
|
+
# What landed in CRM from this Stripe webhook?
|
|
139
|
+
myapi crm contacts search --source webhook --json \
|
|
140
|
+
| jq '.contacts[] | {email, last_engagement_at}'
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### End-to-end recipe — configure a webhook that auto-creates CRM contacts
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Endpoint that ingests Stripe customer.created events
|
|
147
|
+
WH=$(myapi webhook create stripe --crm-email-path 'data.object.customer_email' --json)
|
|
148
|
+
URL=$(echo "$WH" | jq -r .url)
|
|
149
|
+
echo "Point Stripe at: $URL"
|
|
150
|
+
|
|
151
|
+
# Later, after Stripe fires...
|
|
152
|
+
myapi crm contacts search --source webhook --email "$STRIPE_CUSTOMER_EMAIL"
|
|
153
|
+
myapi crm contacts events <id> --kind webhook_received
|
|
154
|
+
```
|
|
155
|
+
<!-- llm:end -->
|
|
156
|
+
|
|
157
|
+
## Notes
|
|
158
|
+
|
|
159
|
+
- **Reserved event kinds — no custom events in v1.** If an agent needs custom state per contact, use `myapi database` keyed by contact id. The curated timeline stays the authoritative engagement record.
|
|
160
|
+
- **Event payloads carry an `external_id`** field used by the backend's idempotency index — same value as the natural id of the underlying action (`goldfox_person_id` for `promoted`, `delivery_id` for `webhook_received`, future `message_id` for `email_sent`). Read the semantic field (e.g. `goldfox_person_id`); `external_id` is a backend-internal duplicate. Old rows may still carry a legacy `message_id` field — same value as `external_id`; safe to ignore.
|
|
161
|
+
- **Goldfox enrichment field deferred** — the live join lands once the BQ get-by-id helper is wired backend-side. CLI treats it as optional today.
|
|
162
|
+
- **Email + Pixel auto-ingest not yet wired**. Only `webhook_received` events fire today. Email and pixel ingest are coming — the CLI surface stays unchanged when they land.
|
|
163
|
+
- **Free in v1.** Metered later if usage shows a need.
|
|
164
|
+
|
|
165
|
+
Run `myapi crm --help` or `myapi crm <namespace> --help` for inline reference.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# my-database-api
|
|
2
|
+
|
|
3
|
+
Per-org KV store with namespaces. JSON values up to 256 KB per key. Compare-and-swap via `If-Match` etags. The substrate for stateful agent-built apps on MyAPI.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- Explicit, named namespaces (containers for keys)
|
|
8
|
+
- `get` / `set` / `del` / list keys (with prefix + cursor pagination)
|
|
9
|
+
- Inline values on list via `--values`
|
|
10
|
+
- Optimistic concurrency: `--if-match <etag>` returns an error if another writer raced
|
|
11
|
+
|
|
12
|
+
## Quickstart
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
myapi database create my-app
|
|
16
|
+
myapi database set users '{"alice":{"plan":"pro"}}' --ns my-app
|
|
17
|
+
myapi database get users --ns my-app
|
|
18
|
+
myapi database keys --ns my-app --values
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Authentication
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
export MYAPI_KEY=mak_...
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Requires `api_key` and `org_id` from **myapihq**.
|
|
28
|
+
|
|
29
|
+
## When to use
|
|
30
|
+
|
|
31
|
+
- Application state for a function or workflow: sessions, lookup tables, idempotency keys, lightweight counters
|
|
32
|
+
- Storing the state behind a CRM-like product an agent builds (the user table, the per-user URL ownership map)
|
|
33
|
+
- Anything where you'd reach for Redis but don't need its perf envelope
|
|
34
|
+
|
|
35
|
+
When **not** to use: blobs/binary (use `myapi storage`), large rows (>256 KB), complex queries (no secondary indexes today — prefix scans only).
|
|
36
|
+
|
|
37
|
+
## Documentation
|
|
38
|
+
|
|
39
|
+
Per-key size limit, CAS semantics, pagination model: see `SKILL.md`.
|
|
40
|
+
|
|
41
|
+
Run `myapi database --help` for inline reference.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: my-database-api
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: >
|
|
5
|
+
Per-org KV store with named namespaces, JSON values up to 256 KB, prefix-scan listing, and compare-and-swap via etag. The substrate for any stateful agent-built app on MyAPI — user tables, session stores, idempotency keys, per-user lookup maps.
|
|
6
|
+
triggers: [database, kv, key value, namespace, store, state, etag, cas, session, idempotency]
|
|
7
|
+
checksum: sha256-pending
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# MyDatabaseAPI
|
|
11
|
+
|
|
12
|
+
A small KV primitive scoped to your MyAPI org. Two resources: namespaces (containers) and keys (the actual values). Values are JSON; binary belongs in `myapi storage`. Compare-and-swap via etags is supported on day one.
|
|
13
|
+
|
|
14
|
+
## Capabilities
|
|
15
|
+
<!-- llm:start -->
|
|
16
|
+
Use this when you need **state behind a workflow or a function** — the user table for a SaaS the agent is building on MyAPI primitives, a per-customer settings store, idempotency keys for webhook handlers, a session cache. Anything where Redis is overkill but raw env-var configuration isn't enough.
|
|
17
|
+
|
|
18
|
+
### Model
|
|
19
|
+
- An **organization** owns many **namespaces**
|
|
20
|
+
- A **namespace** owns many **keys**
|
|
21
|
+
- A **key** points to one JSON **value** (≤ 256 KB serialized)
|
|
22
|
+
- Every value has an opaque **etag** that changes on every successful write
|
|
23
|
+
|
|
24
|
+
### Limits
|
|
25
|
+
- **Key** ≤ 512 bytes (UTF-8)
|
|
26
|
+
- **Value** ≤ 256 KB serialized JSON. For blobs/binary, use `myapi storage`.
|
|
27
|
+
- **Namespace name** matches `^[a-z0-9][a-z0-9_-]{0,62}$`; the `__myapi_` prefix is reserved.
|
|
28
|
+
|
|
29
|
+
### Compare-and-swap
|
|
30
|
+
Pass `--if-match <etag>` from a previous `get` to make `set` or `del` conditional. Returns an error if another writer changed the value between your read and write. Without `--if-match`, last-write-wins.
|
|
31
|
+
|
|
32
|
+
### Listing
|
|
33
|
+
- Default: keys only, one per line
|
|
34
|
+
- `--values` adds inline values + etags (cost: a bigger response payload)
|
|
35
|
+
- `--prefix foo` for prefix-scoped listing
|
|
36
|
+
- `--limit N` (1–1000, default 50)
|
|
37
|
+
- Paginates via `--cursor` — the previous response's `next_cursor`
|
|
38
|
+
|
|
39
|
+
### Failure modes
|
|
40
|
+
- `412 ETAG_MISMATCH` on CAS conflict (CLI surfaces it as a friendly error)
|
|
41
|
+
- `404 NAMESPACE_NOT_FOUND` / `KEY_NOT_FOUND`
|
|
42
|
+
- `409 NAMESPACE_EXISTS` on re-create
|
|
43
|
+
- `400 VALUE_NOT_JSON` if the body's `value` isn't valid JSON
|
|
44
|
+
- `413 VALUE_TOO_LARGE` if you exceed 256 KB (CLI also pre-flight checks)
|
|
45
|
+
<!-- llm:end -->
|
|
46
|
+
|
|
47
|
+
## Commands
|
|
48
|
+
<!-- generated:start -->
|
|
49
|
+
| Command | What it does |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `myapi database namespaces [--json]` | List namespaces in the org |
|
|
52
|
+
| `myapi database create <name>` | Create a namespace |
|
|
53
|
+
| `myapi database delete-namespace <name>` | Delete namespace AND all its keys (irreversible) |
|
|
54
|
+
| `myapi database keys --ns <ns> [--prefix <p>] [--limit N] [--values] [--cursor <c>]` | List keys, optionally with inline values |
|
|
55
|
+
| `myapi database get <key> --ns <ns>` | Get value + etag (etag printed to stderr) |
|
|
56
|
+
| `myapi database set <key> <value-json> --ns <ns> [--if-match <etag>] [--file <path>]` | Set key. CAS via --if-match |
|
|
57
|
+
| `myapi database del <key> --ns <ns> [--if-match <etag>]` | Delete key. CAS via --if-match |
|
|
58
|
+
<!-- generated:end -->
|
|
59
|
+
|
|
60
|
+
Pass `-` as `<value-json>` to read the value from stdin, or `--file <path>` to read from a file.
|
|
61
|
+
|
|
62
|
+
## Examples
|
|
63
|
+
<!-- llm:start -->
|
|
64
|
+
```bash
|
|
65
|
+
# Create a namespace, set a key, read it back
|
|
66
|
+
myapi database create my-app
|
|
67
|
+
myapi database set user:alice '{"plan":"pro","trial_ends":"2026-06-01"}' --ns my-app
|
|
68
|
+
myapi database get user:alice --ns my-app
|
|
69
|
+
# stdout: {"plan":"pro","trial_ends":"2026-06-01"}
|
|
70
|
+
# stderr: — etag=A1B2C3 · updated=2026-05-12T17:00:00Z
|
|
71
|
+
|
|
72
|
+
# List keys with a prefix
|
|
73
|
+
myapi database keys --ns my-app --prefix user: --values
|
|
74
|
+
|
|
75
|
+
# Compare-and-swap update
|
|
76
|
+
ETAG=$(myapi database get user:alice --ns my-app --json | jq -r .etag)
|
|
77
|
+
myapi database set user:alice '{"plan":"enterprise"}' --ns my-app --if-match "$ETAG"
|
|
78
|
+
|
|
79
|
+
# Idempotency keys for a webhook handler
|
|
80
|
+
myapi database set "delivery:$DELIVERY_ID" 'true' --ns idempotency --if-match '"00000000"' \
|
|
81
|
+
|| { echo "already processed"; exit 0; }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### End-to-end recipe — user table for an agent-built SaaS
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Bootstrap a "users" namespace
|
|
88
|
+
myapi database create users
|
|
89
|
+
|
|
90
|
+
# Sign-up handler: webhook receives { email, name } → store the user
|
|
91
|
+
myapi database set "by-email:$EMAIL" "$(jq -nc --arg n "$NAME" '{name:$n, plan:"trial"}')" \
|
|
92
|
+
--ns users
|
|
93
|
+
|
|
94
|
+
# Login handler: look up by email
|
|
95
|
+
myapi database get "by-email:$EMAIL" --ns users --json | jq -r .value
|
|
96
|
+
```
|
|
97
|
+
<!-- llm:end -->
|
|
98
|
+
|
|
99
|
+
## Notes
|
|
100
|
+
|
|
101
|
+
- **No transactions across keys.** Each key is independently atomic; multi-key updates aren't atomic. Use a single composite-JSON value if you need joint atomicity.
|
|
102
|
+
- **No secondary indexes today.** Prefix scans are the only query primitive. Design your keys for the access pattern (`user:by-email:alice@x.com`, `user:by-plan:pro:alice@x.com`, etc.).
|
|
103
|
+
- **No TTL today.** Keys live until deleted. If you need expiry, store `expires_at` in the value and let your reader drop stale rows.
|
|
104
|
+
- **Eventual `key_count`.** The `keys` field on a namespace is approximate; don't use it for strict pagination math.
|
|
105
|
+
- **Free in v1.** Metered later if usage shows a need. Cost discipline still applies — store data, not blobs.
|
|
106
|
+
|
|
107
|
+
Run `myapi database --help` for inline reference.
|
|
@@ -1,62 +1,89 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: my-domain-api
|
|
3
|
+
version: 1.0.0
|
|
3
4
|
description: >
|
|
4
5
|
Register new domains and manage edge settings. Required before a funnel can go live on a custom URL.
|
|
6
|
+
triggers: [domain, register domain, dns, custom domain, edge, cdn, security level, browser check, renew, namecheap]
|
|
7
|
+
checksum: sha256-pending
|
|
5
8
|
---
|
|
6
9
|
|
|
7
10
|
# MyDomainAPI
|
|
8
11
|
|
|
9
12
|
Handles domain registration, assignment to orgs, and edge (CDN/security) settings. DNS is fully managed — you never touch nameservers manually.
|
|
10
13
|
|
|
11
|
-
##
|
|
14
|
+
## Capabilities
|
|
15
|
+
<!-- llm:start -->
|
|
16
|
+
Domains are how you take a funnel from `your-org.makeautonomous.com` to `your-real-brand.com`. The flow is: check availability, register (deducts credits), assign to an org, watch status until DNS propagates. From that point, your org's funnel serves at `https://yourdomain.com`. SSL provisions automatically a few minutes after status flips to `active`.
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
- A domain assigned to an org is the prerequisite for a **myfunnelapi** funnel to be reachable at a custom URL.
|
|
15
|
-
- Without a domain, funnels still work on the free `*.makeautonomous.com` preview subdomain.
|
|
18
|
+
You can also import existing domains (without re-registering) and tune CDN/security settings per-domain.
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
Without a domain, funnels still work on the free `*.makeautonomous.com` preview subdomain.
|
|
21
|
+
|
|
22
|
+
### Registrant (ICANN requirement)
|
|
23
|
+
|
|
24
|
+
Every `myapi domain register` call needs WHOIS contact info — name, email, phone, address, country code (ISO alpha-2). State is required for US/CA registrants.
|
|
25
|
+
|
|
26
|
+
The CLI stores this locally so you only enter it once:
|
|
18
27
|
|
|
19
28
|
```bash
|
|
20
|
-
|
|
21
|
-
myapi
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
# One-time interactive setup (human)
|
|
30
|
+
myapi auth registrant set
|
|
31
|
+
|
|
32
|
+
# Or non-interactive (agent)
|
|
33
|
+
myapi auth registrant set --registrant-json '{
|
|
34
|
+
"name":"Simon Janin", "email":"simon@example.com", "phone":"+33612345678",
|
|
35
|
+
"street":"1 rue de la Paix", "city":"Paris",
|
|
36
|
+
"postal_code":"75001", "country_code":"FR"
|
|
37
|
+
}'
|
|
24
38
|
```
|
|
25
39
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## All Commands
|
|
40
|
+
Resolution at register time (highest wins): `--registrant-json` → per-field flags (`--registrant-name`, …) → stored config → interactive TTY prompt → error. Stored contact info is never sent to the backend except as a per-request field on register.
|
|
41
|
+
<!-- llm:end -->
|
|
29
42
|
|
|
43
|
+
## Commands
|
|
44
|
+
<!-- generated:start -->
|
|
30
45
|
| Command | What it does |
|
|
31
46
|
|---|---|
|
|
32
47
|
| `myapi domain check <domain>` | Check availability and yearly price |
|
|
33
|
-
| `myapi domain register <domain> [--years N]
|
|
48
|
+
| `myapi domain register <domain> [--years N] <registrant flags>` | Register a new domain (deducts credits). Requires ICANN WHOIS contact info — store once with `myapi auth registrant set`, or pass per-call via `--registrant-json` / `--registrant-*` flags |
|
|
49
|
+
| `myapi domain renew <domain>` | Renew a registered domain for another period |
|
|
34
50
|
| `myapi domain list [--filter all\|unassigned\|org]` | List domains in your account |
|
|
35
|
-
| `myapi domain assign <domain>` | Assign domain to
|
|
36
|
-
| `myapi domain unassign <domain>` | Remove domain from its org
|
|
37
|
-
| `myapi domain status <domain>` |
|
|
51
|
+
| `myapi domain assign <domain>` | Assign domain to your default (or `--org`) org |
|
|
52
|
+
| `myapi domain unassign <domain>` | Remove domain from its org |
|
|
53
|
+
| `myapi domain status <domain>` | Registration + DNS propagation status |
|
|
38
54
|
| `myapi domain settings <domain>` | View edge/CDN settings |
|
|
39
|
-
| `myapi domain update-settings <domain>` |
|
|
55
|
+
| `myapi domain update-settings <domain>` | Change security level, browser check, purge cache |
|
|
56
|
+
<!-- generated:end -->
|
|
40
57
|
|
|
41
|
-
|
|
58
|
+
## Examples
|
|
59
|
+
<!-- llm:start -->
|
|
60
|
+
```bash
|
|
61
|
+
# One-time: store your WHOIS contact info (used by every register call)
|
|
62
|
+
myapi auth registrant set
|
|
42
63
|
|
|
43
|
-
|
|
64
|
+
# Register and bring online
|
|
65
|
+
myapi domain check example.com
|
|
66
|
+
myapi domain register example.com
|
|
67
|
+
myapi domain assign example.com
|
|
68
|
+
myapi domain status example.com # poll until status = active
|
|
44
69
|
|
|
45
|
-
|
|
70
|
+
# Renew before expiry
|
|
71
|
+
myapi domain renew example.com
|
|
46
72
|
|
|
47
|
-
|
|
73
|
+
# Tune the edge for AI bot traffic
|
|
48
74
|
myapi domain update-settings example.com \
|
|
49
|
-
--security=essentially_off
|
|
50
|
-
--browser-check=off \
|
|
51
|
-
--purge-cache
|
|
75
|
+
--security=essentially_off --browser-check=off --purge-cache
|
|
52
76
|
```
|
|
53
77
|
|
|
54
|
-
Security levels: `essentially_off` · `low` · `medium` · `high` · `under_attack`.
|
|
78
|
+
Security levels: `essentially_off` · `low` · `medium` · `high` · `under_attack`.
|
|
79
|
+
|
|
55
80
|
Set `essentially_off` + `browser-check=off` to allow AI crawlers and training bots through without challenge pages.
|
|
81
|
+
<!-- llm:end -->
|
|
56
82
|
|
|
57
83
|
## Notes
|
|
58
84
|
|
|
59
|
-
-
|
|
85
|
+
- `register`, `renew`, `assign`, and `unassign` always require an explicit domain argument — they don't fall back to a stored default, to prevent accidental destructive actions.
|
|
86
|
+
- All commands default to `--org` from your saved config (set with `myapi config set-org <id>`).
|
|
60
87
|
- `402` errors mean insufficient credits — run `myapi billing topup <amount>`.
|
|
61
88
|
|
|
62
89
|
Run `myapi domain --help` or `myapi domain <subcommand> --help` for full flag reference.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
# my-email-verify-api
|
|
3
|
+
|
|
4
|
+
Synchronous single-address email verification — syntax + DNS + Microsoft probe. Pre-send quality gate for outbound campaigns.
|
|
5
|
+
|
|
6
|
+
## What it does
|
|
7
|
+
|
|
8
|
+
- Validates email syntax (instant)
|
|
9
|
+
- Looks up DNS / MX records (sub-second)
|
|
10
|
+
- Probes Microsoft GetCredentialType for Microsoft-hosted domains
|
|
11
|
+
- Returns `deliverable` / `undeliverable` / `unknown` with confidence score
|
|
12
|
+
- Sets `smtp_recommended: true` when the cheap layer was inconclusive
|
|
13
|
+
|
|
14
|
+
## Quickstart
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
myapi email verify alice@example.com
|
|
18
|
+
myapi email verify alice@example.com --json # full check breakdown
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Authentication
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
export MYAPI_KEY=mak_...
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Requires `api_key` and `org_id` from **myapihq**.
|
|
28
|
+
|
|
29
|
+
## Documentation
|
|
30
|
+
|
|
31
|
+
Verdicts, confidence semantics, and pre-send filter recipe: see `SKILL.md`.
|
|
32
|
+
|
|
33
|
+
Run `myapi email verify --help` for inline reference.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: my-email-verify-api
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: >
|
|
5
|
+
Synchronous single-address email verification — syntax + DNS + Microsoft GetCredentialType probe. Returns a verdict in <1s for ~50% of inputs; the rest get verdict='unknown' with smtp_recommended=true. The pre-send quality gate for any outbound campaign.
|
|
6
|
+
triggers: [email verify, email validation, deliverability, smtp, syntax check, dns mx, microsoft, mx lookup, bounce prevention]
|
|
7
|
+
checksum: sha256-pending
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# MyEmailVerifyAPI
|
|
11
|
+
|
|
12
|
+
A cheap, fast quality gate for a single email address. Runs three layers in sequence: syntax check (instant) → DNS / MX lookup (sub-second) → Microsoft GetCredentialType probe (sub-second for non-Microsoft, slower for federated domains). Returns a definitive `deliverable` / `undeliverable` verdict for about half of inputs; the rest get `verdict: 'unknown'` with `smtp_recommended: true`, suggesting a downstream SMTP probe that isn't part of this API today.
|
|
13
|
+
|
|
14
|
+
## Capabilities
|
|
15
|
+
<!-- llm:start -->
|
|
16
|
+
Use this before any campaign send — pipe the audience members through `verify` and drop the undeliverable ones to protect your sender reputation.
|
|
17
|
+
|
|
18
|
+
Verdicts:
|
|
19
|
+
- **`deliverable`** — high-confidence acceptance. Safe to send.
|
|
20
|
+
- **`undeliverable`** — high-confidence reject. Skip. Most common causes: malformed syntax (`missing '@'`), no MX records, Microsoft positively returns "no such mailbox".
|
|
21
|
+
- **`unknown`** — couldn't determine cheaply. The `smtp_recommended` flag will be `true`; in practice, treat as "send but watch the bounce signal" or run a more expensive SMTP probe externally.
|
|
22
|
+
|
|
23
|
+
Response shape (full check breakdown available via `--json`):
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"email": "alice@example.com",
|
|
27
|
+
"verdict": "deliverable" | "undeliverable" | "unknown",
|
|
28
|
+
"confidence": 0.0..1.0,
|
|
29
|
+
"smtp_recommended": true,
|
|
30
|
+
"checks": {
|
|
31
|
+
"syntax": { "valid": true, "detail": "missing '@'" },
|
|
32
|
+
"dns": { "valid": true, "mx_records": ["mx1.example.com", ...] },
|
|
33
|
+
"microsoft": { "verdict": "...", "if_exists_result": 0, "domain_type": 4, "federated": false }
|
|
34
|
+
},
|
|
35
|
+
"elapsed_ms": 124
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Latency notes: syntax + DNS are <100ms. Microsoft GetCredentialType is fast for non-Microsoft domains, can take 5–8s on federated (custom) Microsoft tenants while it walks redirects. Set call timeouts ≥10s for safety.
|
|
40
|
+
<!-- llm:end -->
|
|
41
|
+
|
|
42
|
+
## Commands
|
|
43
|
+
<!-- generated:start -->
|
|
44
|
+
| Command | What it does |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `myapi email verify <email> [--json]` | Run all three verification layers on one address; print verdict + confidence + key checks |
|
|
47
|
+
<!-- generated:end -->
|
|
48
|
+
|
|
49
|
+
Pass `--json` for the full check breakdown (syntax detail, MX records, Microsoft probe result). The default human render shows the verdict + a one-line summary per check that fired.
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
<!-- llm:start -->
|
|
53
|
+
```bash
|
|
54
|
+
# Clear undeliverable — syntax fails instantly
|
|
55
|
+
myapi email verify not-an-email
|
|
56
|
+
# → Verdict: ✗ undeliverable (confidence 1.00)
|
|
57
|
+
# → Syntax: missing '@'
|
|
58
|
+
# → Took: 0ms
|
|
59
|
+
|
|
60
|
+
# Generic domain — unknown verdict, MX visible, confidence 0.5
|
|
61
|
+
myapi email verify hello@gmail.com
|
|
62
|
+
# → Verdict: ? unknown (confidence 0.50)
|
|
63
|
+
# → SMTP next: yes — consider an SMTP probe
|
|
64
|
+
# → MX: gmail-smtp-in.l.google.com, alt1...
|
|
65
|
+
|
|
66
|
+
# Full breakdown
|
|
67
|
+
myapi email verify alice@corp.com --json | jq '.checks'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### End-to-end recipe — filter an audience before send
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Pull all members from a saved audience
|
|
74
|
+
AID=$(myapi audience list --json | jq -r '.[0].id')
|
|
75
|
+
myapi audience members $AID --limit 100 --json | jq -r '.people[].email' > emails.txt
|
|
76
|
+
|
|
77
|
+
# Verify each in parallel (modest concurrency to be polite)
|
|
78
|
+
while read email; do
|
|
79
|
+
myapi email verify "$email" --json | jq -r '"\(.email) \(.verdict)"'
|
|
80
|
+
done < emails.txt | grep -v ' undeliverable$' > verified.txt
|
|
81
|
+
```
|
|
82
|
+
<!-- llm:end -->
|
|
83
|
+
|
|
84
|
+
## Notes
|
|
85
|
+
|
|
86
|
+
- This is the **cheap layer only**. The full pipeline at outreach scale typically chains: this verify (free signal) → SMTP probe (medium cost) → catch-all detector (slow). Only the first is exposed today.
|
|
87
|
+
- The `confidence` field is a hint, not a guarantee. A `deliverable` verdict at 0.95 confidence is still ≈5% bounce risk in practice.
|
|
88
|
+
- For bulk verification, call this in parallel from your code with throttling — there is no batch endpoint today. A batch + async-job endpoint is on the backend roadmap.
|
|
89
|
+
- Verification is per-org; you'll get rate-limited if you blast more than ~1 req/sec per key.
|
|
90
|
+
|
|
91
|
+
Run `myapi email verify --help` for inline reference.
|