@myapihq/cli 2.7.0 → 2.7.2

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.
Files changed (33) hide show
  1. package/dist/commands/account.js +15 -0
  2. package/dist/commands/audience.js +7 -5
  3. package/dist/commands/container.js +50 -26
  4. package/dist/commands/crm/companies.js +4 -4
  5. package/dist/commands/crm/contacts.js +4 -4
  6. package/dist/commands/crm/index.js +3 -0
  7. package/dist/commands/crm/origin-flag.test.d.ts +1 -0
  8. package/dist/commands/crm/origin-flag.test.js +38 -0
  9. package/dist/commands/crm/pagination.d.ts +2 -0
  10. package/dist/commands/crm/pagination.js +9 -0
  11. package/dist/commands/database.js +21 -14
  12. package/dist/commands/domain.js +11 -0
  13. package/dist/commands/fn.js +10 -5
  14. package/dist/commands/task.js +12 -4
  15. package/dist/skills/my-api-hq/SKILL.md +25 -1
  16. package/dist/skills/my-audience-api/SKILL.md +5 -5
  17. package/dist/skills/my-auth-api/SKILL.md +8 -1
  18. package/dist/skills/my-company-api/SKILL.md +3 -3
  19. package/dist/skills/my-container-api/SKILL.md +47 -30
  20. package/dist/skills/my-crm-api/SKILL.md +6 -6
  21. package/dist/skills/my-database-api/README.md +1 -1
  22. package/dist/skills/my-database-api/SKILL.md +25 -4
  23. package/dist/skills/my-domain-api/SKILL.md +18 -1
  24. package/dist/skills/my-email-api/SKILL.md +36 -1
  25. package/dist/skills/my-function-api/SKILL.md +38 -10
  26. package/dist/skills/my-funnel-api/SKILL.md +6 -3
  27. package/dist/skills/my-git-api/SKILL.md +10 -4
  28. package/dist/skills/my-people-api/SKILL.md +3 -3
  29. package/dist/skills/my-pixel-api/SKILL.md +12 -1
  30. package/dist/skills/my-storage-api/SKILL.md +31 -2
  31. package/dist/skills/my-task-api/SKILL.md +9 -1
  32. package/dist/skills/my-webhook-api/SKILL.md +12 -1
  33. package/package.json +3 -2
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
5
  Add authentication to apps you build on MyAPI — a managed OIDC identity provider for your app's END USERS (à la Kinde/Auth0). One auth tenant per org; register OIDC clients; sign users in with managed Google or the hosted login page; verify RS256 tokens against the tenant JWKS.
6
6
  triggers: [auth, authentication, login, sign-in, oidc, oauth, jwt, jwks, sso, google sign-in, user accounts, identity provider, kinde, auth0, clerk]
7
- checksum: sha256-b5eca82bb59647677fdb5796778329160572598ac6914887768fd33529cdfe84
7
+ checksum: sha256-5eeacc463d7323f85a330639b7073f735ccc80bddfb8217c9c15c56989b8a99a
8
8
  ---
9
9
 
10
10
  # MyAuthAPI
@@ -114,4 +114,11 @@ myapi auth client list
114
114
  `http://localhost…` for local dev).
115
115
  - `402 INSUFFICIENT_FUNDS` = empty wallet → `myapi billing topup <amount>` (or keep it funded automatically: `myapi billing auto-recharge set`). `402 SPEND_CAP_EXCEEDED` = you hit your account spend ceiling → raise it with `myapi billing spend-cap`.
116
116
 
117
+ ## Anonymous accounts
118
+
119
+ `myapi account setup --anonymous` skips registration and creates an account
120
+ with no email — for throwaway or machine-owned orgs. It cannot receive
121
+ password resets or magic links, so attach a real identity before anything
122
+ depends on it. `myapi status` shows `Type: anonymous`.
123
+
117
124
  **End-to-end example:** `examples/authenticated-app/` walks the full seam — hosted login → token verification → per-user KV record → deployed container — including the parts that cost real users hours (verify the id_token for identity; the access token is a bearer credential for `<issuer>/userinfo`).
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
5
  Company database backed by the Goldfox crawl. Filter companies by Goldfox confidence tier, country/TLD consistency, behavioral page signals (has_careers_page, has_investors_page, has_shop_page, has_c_level, has_decision_maker), legal-entity status, headcount, and source-URL count. Account-based targeting and B2B firmographics.
6
6
  triggers: [companies, accounts, firmographics, abm, search, filter, goldfox, careers signal, investors, c-level, shop, b2b targeting]
7
- checksum: sha256-67dd4b65a9b0cc7acf7c1e4262bc66d2b58ff11ed227a24299924e0b620712f0
7
+ checksum: sha256-4754de8a66bf13e7e2f2a23acc407ccec147e142abf8adc670ae7962ca860a74
8
8
  ---
9
9
 
10
10
  # MyCompanyAPI
@@ -90,7 +90,7 @@ myapi company get auroracloud.com --include-people 5
90
90
  ```bash
91
91
  # Save filter as audience (companies)
92
92
  AID=$(myapi audience create "EU growth-stage SaaS" \
93
- --source company \
93
+ --from company \
94
94
  --filter '{"country":["DE","FR","GB","NL"],"has_careers_page":true,"has_decision_maker":true,"min_source_count":3}' \
95
95
  --json | jq -r .id)
96
96
 
@@ -105,6 +105,6 @@ myapi audience members $AID --limit 50 --json > accounts.json
105
105
  - `seniority`, `email_type`, and `min_link_confidence` are people-only — passing them on company search is silently ignored.
106
106
  - `include_people` only works on company search/get; people-source already embeds company by default.
107
107
  - `keyword` is a substring match on the company's **domain** — use `--keyword stripe` to find domains containing "stripe".
108
- - For a persistent account list, use `my-audience-api` with `--source company`.
108
+ - For a persistent account list, use `my-audience-api` with `--from company`.
109
109
 
110
110
  Run `myapi company --help` for full flag reference.
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
5
  Run containers on demand — long-running services, background workers, and scheduled jobs. The heavier-duty sibling of edge functions, for native deps and long execution.
6
6
  triggers: [container, cloud run, dynamic app, custom domain app, service, worker, scheduled job, deploy container, docker image]
7
- checksum: sha256-4847ab675fa971bbd0fdd83f0039d9110ba4c38e406860fe9265dd540b7f299e
7
+ checksum: sha256-47eda6baa9055dadbd3e9d04df9fc425f1a7e96a9cd80c971c4951b97f1e94ff
8
8
  ---
9
9
 
10
10
  # MyContainerAPI
@@ -16,25 +16,33 @@ A container runs a pre-built image on managed cloud infrastructure. Three types:
16
16
  The lifecycle is **create → deploy → (optionally) bind a custom domain**.
17
17
 
18
18
  - `create` registers the container and issues a **scoped API key**, returned once. The running container receives it as the `MYAPI_KEY` env var, so your code calls other MyAPI slots with no token handling. Deploy rotates this key.
19
- - `deploy` ships a pre-built image reference to the runtime and makes the container live at a generated URL.
19
+ - `deploy` takes **either** a pre-built image reference **or** a source
20
+ directory. `--source ./dir` tars the directory, builds it server-side
21
+ (typically ~4 minutes) and deploys the result — **no Docker on your machine,
22
+ no registry account, no image to push**. If you can write a Dockerfile you
23
+ can deploy; you do not need to be able to run one.
20
24
  - `domain` puts the container on a **custom domain** — how you serve a dynamic app at `app.yourbrand.com`.
21
25
 
22
- ### Deploying safely
26
+ ### Deploying safely — NOT YET POSSIBLE ON THIS PLATFORM
23
27
 
24
- A deploy takes 100% of traffic the moment it lands, so a broken build is live
25
- before you can look at it. Two ways to avoid that:
28
+ A deploy takes 100% of traffic the moment it lands. There is no dry run, no
29
+ definition of correct beyond "something is listening on the port", and no way
30
+ back. Plan for that.
26
31
 
27
- - `--smoke 'GET / contains assets/'` the platform deploys the revision with
28
- NO traffic, runs the assertion, and promotes only if it holds. A failure
29
- leaves the previous revision serving. **Assert on content, not status**:
30
- "returns 200" is true of a placeholder page too.
31
- - `--no-promote` — build the revision and hold it back. You get a URL to
32
- exercise it, then `myapi container promote <id> <revision>`.
32
+ `--no-promote` and `--smoke` exist as flags and **the CLI refuses them**: they
33
+ shipped before the platform could honour them, and a guard that silently
34
+ passes is worse than no guard. `--health-check` is accepted at create but does
35
+ not appear on the container afterwards, so do not rely on it either.
33
36
 
34
- `--health-check /livez` at create time makes the startup probe an HTTP request
35
- instead of a bare TCP connect. `/healthz` is refused: the runtime intercepts
36
- it, so the probe would never reach your container and would report success
37
- regardless.
37
+ Until they work, the only safe sequence is:
38
+
39
+ 1. deploy to a **non-production** container
40
+ 2. verify it yourself — `curl` for a string only a real build emits, not just
41
+ a 200, because a broken build returns 200 too
42
+ 3. deploy the same image to production
43
+
44
+ `myapi container promote <id> <revision>` currently fails, so a bad deploy
45
+ must be fixed by deploying forward. Keep a known-good image reference to hand.
38
46
 
39
47
  ### Custom domains (dynamic apps)
40
48
 
@@ -53,7 +61,7 @@ Get it right:
53
61
  | Command | What it does |
54
62
  |---|---|
55
63
  | `myapi container create --name <name> [--type service\|worker\|job] [--cron <expr>] [--cpu <n>] [--memory <size>] [--port <n>] [--env K=V,...]` | Register a container, get its scoped API key (once) |
56
- | `myapi container deploy <id> <image-ref> [--no-promote] [--smoke '<assertion>']` | Ship a pre-built image (rotates the scoped key) |
64
+ | `myapi container deploy <id> <image-ref> [--no-promote] [--smoke '<assertion>']` | Ship a pre-built image (rotates the scoped API key) |
57
65
  | `myapi container revisions <id>` | List revisions and the traffic each takes |
58
66
  | `myapi container promote <id> <revision>` | Move all traffic to a revision (seconds, no rebuild) |
59
67
  | `myapi container list` | List containers in your org |
@@ -66,25 +74,23 @@ Get it right:
66
74
  ## Examples
67
75
  <!-- llm:start -->
68
76
  ```bash
69
- # 1. Register a service container. --health-check makes the startup probe an
70
- # HTTP request instead of a bare TCP connect.
71
- myapi container create --name api --type service --port 8080 --health-check /livez
77
+ # 1. Register a service container
78
+ myapi container create --name api --type service --port 8080
72
79
  # → prints a scoped API key ONCE — save it if your code needs it
73
80
 
74
- # 2a. Deploy. Plain form takes 100% of traffic immediately.
81
+ # 2a. Deploy from source MyAPI builds it. No local Docker required.
82
+ # Takes ~4 minutes; the CLI polls until it is live.
83
+ myapi container deploy <id> --source ./my-app
84
+
85
+ # 2b. Or ship an image you already built and pushed.
75
86
  myapi container deploy <id> registry.example.com/my-app:v1
76
87
 
77
- # 2b. SAFER: assert before any traffic moves. The revision is deployed with no
78
- # traffic, checked, and promoted only if the check holds. Assert on
79
- # CONTENT — a broken build still returns 200.
80
- myapi container deploy <id> registry.example.com/my-app:v1 \
81
- --smoke 'GET / contains assets/'
88
+ # Either way this takes 100% of traffic immediately there is no staging
89
+ # step, so verify on a non-production container FIRST.
82
90
 
83
- # 2c. Or hold it back and look yourself.
84
- myapi container deploy <id> registry.example.com/my-app:v1 --no-promote
85
- # prints a revision URL serving 0% of traffic
86
- myapi container revisions <id>
87
- myapi container promote <id> <revision>
91
+ # 3. Check what you actually shipped. Assert on content: a build whose
92
+ # frontend never bundled still binds its port and returns 200.
93
+ curl -s https://<your-domain>/ | grep -q 'assets/' || echo "BROKEN BUILD"
88
94
 
89
95
  # 3. Serve it on a custom domain. The parent domain must already be
90
96
  # registered: myapi domain register synthesisdaily.com
@@ -118,6 +124,13 @@ way that looks like an application bug.
118
124
  `create` and cannot be changed by `deploy`.** Passing them to `deploy` does
119
125
  nothing. Recreate the container to change them.
120
126
 
127
+ ### Keeping a service warm
128
+
129
+ `--min-instances 1` at create stops a `service` scaling to zero, which removes
130
+ cold starts at the cost of running continuously. Leave it at the default `0`
131
+ unless latency on the first request actually matters — a scaled-to-zero
132
+ service costs nothing while idle.
133
+
121
134
  ## Notes
122
135
 
123
136
  - The scoped API key is shown **once** at create, and again (rotated) on every deploy. Save it if your code needs it.
@@ -126,6 +139,10 @@ way that looks like an application bug.
126
139
  the same stream and share the `--tail` budget, so raise `--tail` with it.
127
140
  - Custom domains need a deployed container **and** a MyAPI-registered parent domain — see `my-domain-api`.
128
141
  - Containers are for dynamic apps and native deps. For static sites use `my-funnel-api`; for edge functions use `my-function-api`.
142
+ - **`--source` does not honour `.dockerignore`.** It tars the directory as-is,
143
+ so a `node_modules` can push the context past the limit and fail as
144
+ `invalid_json_response`. Build the tarball yourself and pass
145
+ `--source ctx.tar.gz`, or keep the directory clean.
129
146
 
130
147
  Run `myapi container --help` for the full flag reference.
131
148
 
@@ -4,7 +4,7 @@ version: 1.0.0
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-50cbdd28ed2a901b7a75f1a6c1df1c225d256a8d281ad86cf1e3b42511edc2fe
7
+ checksum: sha256-dfadb20670d9d978503549d330c2c9717fbe6d13ac35b53d9e1a8874d2136fde
8
8
  ---
9
9
 
10
10
  # MyCRMAPI
@@ -38,7 +38,7 @@ Move stage with `myapi crm contacts update <id> --stage qualified`. Every stage
38
38
  goldfox | email | pixel | webhook | manual
39
39
  ```
40
40
 
41
- Set automatically from how the contact entered. Filter with `--source manual` (added by hand) vs `--source goldfox` (from outreach).
41
+ Set automatically from how the contact entered. Filter with `--origin manual` (added by hand) vs `--origin goldfox` (from outreach).
42
42
 
43
43
  ### Event timeline — reserved kinds
44
44
 
@@ -75,7 +75,7 @@ A contact promoted from Goldfox carries a `goldfox_person_id`. In v2 the GET res
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 `--source goldfox` or post-filter the JSON.
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` or post-filter the JSON.
79
79
 
80
80
  ### Failure modes
81
81
 
@@ -92,7 +92,7 @@ A contact promoted from Goldfox carries a `goldfox_person_id`. In v2 the GET res
92
92
  | Command | What it does |
93
93
  |---|---|
94
94
  | `myapi crm contacts list [--limit N] [--offset N]` | List all contacts (newest engagement first) |
95
- | `myapi crm contacts search [--stage ...] [--source ...] [--email ...] [--min/max-last-engagement-days N]` | Filter contacts |
95
+ | `myapi crm contacts search [--stage ...] [--origin ...] [--email ...] [--min/max-last-engagement-days N]` | Filter contacts |
96
96
  | `myapi crm contacts create <email> [--first-name ...] [--last-name ...] [--stage ...] [--custom-json ...]` | Manually create (source='manual') |
97
97
  | `myapi crm contacts get <id>` | Fetch one contact (with embedded Goldfox enrichment when available) |
98
98
  | `myapi crm contacts update <id> [--stage ...] [...]` | Patch fields. Stage change emits `stage_changed` event |
@@ -138,7 +138,7 @@ myapi crm contacts update <id> --stage customer
138
138
  myapi crm contacts events <id>
139
139
 
140
140
  # What landed in CRM from this Stripe webhook?
141
- myapi crm contacts search --source webhook --json \
141
+ myapi crm contacts search --origin webhook --json \
142
142
  | jq '.contacts[] | {email, last_engagement_at}'
143
143
  ```
144
144
 
@@ -151,7 +151,7 @@ URL=$(echo "$WH" | jq -r .url)
151
151
  echo "Point Stripe at: $URL"
152
152
 
153
153
  # Later, after Stripe fires...
154
- myapi crm contacts search --source webhook --email "$STRIPE_CUSTOMER_EMAIL"
154
+ myapi crm contacts search --origin webhook --email "$STRIPE_CUSTOMER_EMAIL"
155
155
  myapi crm contacts events <id> --kind webhook_received
156
156
  ```
157
157
  <!-- llm:end -->
@@ -15,7 +15,7 @@ Per-org KV store with namespaces. JSON values up to 256 KB per key. Compare-and-
15
15
  myapi database create my-app
16
16
  myapi database set users '{"alice":{"plan":"pro"}}' --ns my-app
17
17
  myapi database get users --ns my-app
18
- myapi database keys --ns my-app --values
18
+ myapi database entries --ns my-app --values
19
19
  ```
20
20
 
21
21
  ## Authentication
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
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
6
  triggers: [database, kv, key value, namespace, store, state, etag, cas, session, idempotency]
7
- checksum: sha256-b66f7ebdff5bce05eaab90c6812ffc0f9ec729f6df1dc4a8bca90368406b4c21
7
+ checksum: sha256-924071245c33bf3e43f085fbd756af003e19c990f4522f658de33f42504452d7
8
8
  ---
9
9
 
10
10
  # MyDatabaseAPI
@@ -51,7 +51,7 @@ Pass `--if-match <etag>` from a previous `get` to make `set` or `del` conditiona
51
51
  | `myapi database namespaces [--json]` | List namespaces in the org |
52
52
  | `myapi database create <name>` | Create a namespace |
53
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 |
54
+ | `myapi database entries --ns <ns> [--prefix <p>] [--limit N] [--values] [--cursor <c>]` | List keys, optionally with inline values |
55
55
  | `myapi database get <key> --ns <ns>` | Get value + etag (etag printed to stderr) |
56
56
  | `myapi database set <key> <value-json> --ns <ns> [--if-match <etag>] [--file <path>]` | Set key. CAS via --if-match |
57
57
  | `myapi database del <key> --ns <ns> [--if-match <etag>]` | Delete key. CAS via --if-match |
@@ -62,7 +62,7 @@ Pass `-` as `<value-json>` to read the value from stdin, or `--file <path>` to r
62
62
  ## Examples
63
63
  <!-- llm:start -->
64
64
  ```bash
65
- # Create a namespace, set a key, read it back
65
+ # Create a namespace, set an entry, read it back
66
66
  myapi database create my-app
67
67
  myapi database set user:alice '{"plan":"pro","trial_ends":"2026-06-01"}' --ns my-app
68
68
  myapi database get user:alice --ns my-app
@@ -70,7 +70,7 @@ myapi database get user:alice --ns my-app
70
70
  # stderr: — etag=A1B2C3 · updated=2026-05-12T17:00:00Z
71
71
 
72
72
  # List keys with a prefix
73
- myapi database keys --ns my-app --prefix user: --values
73
+ myapi database entries --ns my-app --prefix user: --values
74
74
 
75
75
  # Compare-and-swap update
76
76
  ETAG=$(myapi database get user:alice --ns my-app --json | jq -r .etag)
@@ -104,6 +104,27 @@ myapi database get "by-email:$EMAIL" --ns users --json | jq -r .value
104
104
  - **Eventual `key_count`.** The `keys` field on a namespace is approximate; don't use it for strict pagination math.
105
105
  - **Free in v1.** Metered later if usage shows a need. Cost discipline still applies — store data, not blobs.
106
106
 
107
+
108
+ ## Calling this from deployed code (HTTP)
109
+
110
+ The CLI is not what runs in production — a deployed function or container calls
111
+ the HTTP API directly. That surface was previously only discoverable by
112
+ grepping the CLI bundle, which cost one team an hour per slot.
113
+
114
+ ```
115
+ base https://api.myapihq.com
116
+ path /database/orgs/{org_id}/namespaces/{ns}/keys/{key}
117
+ auth Authorization: Bearer <api key>
118
+ (inside a function: env.__MYAPI_KEY · inside a container: env.MYAPI_KEY)
119
+ body writes take {"value": <json>} — the value is WRAPPED
120
+ reply { "success": true, "data": …, "error": null, "meta": {…} }
121
+ Unwrap `data`. On failure `success` is false and `error` is
122
+ { code, message }.
123
+ ```
124
+
125
+ **The org id goes in the PATH, not a header.** There is no `X-Org-Id`.
126
+ **Base URLs differ per slot** — do not assume one host for everything.
127
+
107
128
  Run `myapi database --help` for inline reference.
108
129
 
109
130
  **End-to-end example:** `examples/authenticated-app/` walks the full seam — hosted login → token verification → per-user KV record → deployed container — including the parts that cost real users hours (KV writes must be wrapped as `{"value": …}`).
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
5
  Register new domains and manage edge settings. Required before a funnel can go live on a custom URL.
6
6
  triggers: [domain, register domain, dns, custom domain, edge, cdn, security level, browser check, renew, namecheap]
7
- checksum: sha256-8f96d19c11c3591af71e9d73b2cea6d83f40abbfa1c58c5674dbe15db02efa3c
7
+ checksum: sha256-6a686b453528c69dcc791db409c04a514422951abf333c8feed7c614311815cb
8
8
  ---
9
9
 
10
10
  # MyDomainAPI
@@ -116,4 +116,21 @@ Set `essentially_off` + `browser-check=off` to allow AI crawlers and training bo
116
116
  - All commands default to `--org` from your saved config (set with `myapi config set-org <id>`).
117
117
  - `402 INSUFFICIENT_FUNDS` = empty wallet → `myapi billing topup <amount>` (or keep it funded automatically: `myapi billing auto-recharge set`). `402 SPEND_CAP_EXCEEDED` = you hit your account spend ceiling → raise it with `myapi billing spend-cap`.
118
118
 
119
+ ## DNS record flags
120
+
121
+ ```bash
122
+ myapi domain records create <domain> --type A --name @ --content 1.2.3.4 --ttl 300
123
+ myapi domain records create <domain> --type MX --name @ --content mx.x.com --priority 10
124
+ myapi domain records create <domain> --type CNAME --name app --content x.com --proxied
125
+ ```
126
+
127
+ - `--ttl <n>` — seconds; default `1` meaning "automatic". Explicit range 60–86400.
128
+ - `--priority <n>` — MX only, and required for it (typical `10`).
129
+ - `--proxied` — route through the edge proxy (A/AAAA/CNAME only). Off means
130
+ the record resolves straight to your origin, exposing its address.
131
+ - `myapi domain assign <domain> --no-www` skips the `www` → apex redirect.
132
+ - `--force` on assign re-points a domain already bound elsewhere. It is the
133
+ reassign path, so pass `--org` explicitly and check `domain list --filter all`
134
+ first.
135
+
119
136
  Run `myapi domain --help` or `myapi domain <subcommand> --help` for full flag reference.
@@ -4,7 +4,7 @@ version: 1.0.0
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-fa1eb6ee9e24935266643ceeecf7a748747b23377a0bfe256f76b71b62bd6349
7
+ checksum: sha256-aa22381613affcff041a8d51d2acb2ba657fecefc97f4feba45958bcc11b2e06
8
8
  ---
9
9
 
10
10
  # MyEmailAPI
@@ -66,4 +66,39 @@ myapi email warmup stats --address hello@yourdomain.com
66
66
  - Sending is opt-in per mailbox. Newly-created mailboxes can receive but not send until `activate-sending` runs.
67
67
  - Templates are org-scoped. Set a default org once: `myapi config set-org <id>`.
68
68
 
69
+
70
+ ## Which name mail actually lives on
71
+
72
+ Two things that read as contradictory and are not:
73
+
74
+ - **Mailbox addresses are on the APEX** — `contact@yourdomain.com`, never
75
+ `contact@mail.yourdomain.com`. `mail.<domain>` is the *sending identity* that
76
+ `myapi domain email-setup` provisions, not a mailbox namespace. Creating a
77
+ mailbox on the subdomain fails with `DOMAIN_NOT_OWNED`.
78
+ - **Registration and assign put `MX`, `SPF` and `DMARC` on the apex** whether or
79
+ not you run `email-setup`. So "apex is never touched" — which describes
80
+ `email-setup` specifically — is not true of the domain as a whole. If you plan
81
+ to run Google Workspace or another provider on the apex, check the existing
82
+ records first with `myapi domain records <domain>`.
83
+
84
+ ## Calling this from deployed code (HTTP)
85
+
86
+ The CLI is not what runs in production — a deployed function or container calls
87
+ the HTTP API directly. That surface was previously only discoverable by
88
+ grepping the CLI bundle, which cost one team an hour per slot.
89
+
90
+ ```
91
+ base https://api.myemailapi.com ← not the gateway
92
+ path /email/mailboxes · /email/orgs/{org_id}/messages/send
93
+ auth Authorization: Bearer <api key>
94
+ (inside a function: env.__MYAPI_KEY · inside a container: env.MYAPI_KEY)
95
+ body application/json
96
+ reply { "success": true, "data": …, "error": null, "meta": {…} }
97
+ Unwrap `data`. On failure `success` is false and `error` is
98
+ { code, message }.
99
+ ```
100
+
101
+ **The org id goes in the PATH, not a header.** There is no `X-Org-Id`.
102
+ **Base URLs differ per slot** — do not assume one host for everything.
103
+
69
104
  Run `myapi email --help` or `myapi email <namespace> --help` for full flag reference.
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
5
  Deploy JavaScript functions to the MyAPI edge runtime. Register a function, upload a single-file JS bundle, get a live HTTP invocation URL or run it on a cron schedule. Each function gets a scoped capability key for cross-slot calls.
6
6
  triggers: [function, deploy function, edge function, serverless, cloudflare worker, cron, scoped api key, capability key, invocation url, bundle]
7
- checksum: sha256-610e16c931e44d43ee6ac94a32e6d852bb900cdf6f5eea61aaeae7bb95a0814e
7
+ checksum: sha256-1ef76e07c9fb4f295b491224261b5719314f15d3645c32e6e7b443a7fdaf95c6
8
8
  ---
9
9
 
10
10
  # MyFunctionAPI
@@ -35,12 +35,12 @@ Name rules (validated client- and server-side, kept identical):
35
35
  | Command | What it does |
36
36
  |---|---|
37
37
  | `myapi fn create --name <name> [--cron <expr>] [--scope <slot>[,<slot>...]]` | Register a function record + receive scoped API key (returned once). `--scope` narrows the key's slot grants |
38
- | `myapi fn deploy <id> <bundle.js>` | Upload a single-file JS bundle (≤4MB) and go live; rotates the scoped key |
38
+ | `myapi fn deploy <id> <bundle.js>` | Upload a single-file JS bundle (≤4MB) and go live; rotates the scoped API key |
39
39
  | `myapi fn env <id> <name> <value>` | Set an encrypted secret on a deployed function |
40
40
  | `myapi fn runs <id>` | List recent invocation records (status, duration, errors) |
41
41
  | `myapi fn list` | List functions in your org |
42
42
  | `myapi fn get <id>` | Inspect a function (name, trigger, invocation URL) |
43
- | `myapi fn delete <id>` | Soft-delete the record + revoke the scoped key |
43
+ | `myapi fn delete <id>` | Soft-delete the record + revoke the scoped API key |
44
44
  <!-- generated:end -->
45
45
 
46
46
  ## Examples
@@ -50,9 +50,9 @@ Name rules (validated client- and server-side, kept identical):
50
50
  myapi fn create --name my-app-api
51
51
  # → Function created: fn_abc123
52
52
  # Scoped API key (returned once — save it if you need it):
53
- # hq_live_... (scoped keys are not visually distinct from account keys)
53
+ # hq_live_... (scoped API keys are not visually distinct from account keys)
54
54
 
55
- # Deploy a single-file JS bundle → goes live, scoped key is rotated
55
+ # Deploy a single-file JS bundle → goes live, scoped API key is rotated
56
56
  myapi fn deploy fn_abc123 ./dist/bundle.js
57
57
  # → Deployed function fn_abc123
58
58
  # Invocation URL: https://fn-abc123.<...>.workers.dev
@@ -74,17 +74,44 @@ myapi fn create --name mailer --scope email,storage
74
74
  myapi fn list
75
75
  myapi fn get fn_abc123
76
76
 
77
- # Delete (revokes the scoped key — future calls with it return 401)
77
+ # Delete (revokes the scoped API key — future calls with it return 401)
78
78
  myapi fn delete fn_abc123
79
79
  ```
80
80
 
81
- ### Using the scoped key
81
+ ### The scoped API key is already in your function — as `__MYAPI_KEY`
82
+
83
+ **Two leading underscores, and it is injected for you.** Verified by probing a
84
+ deployed function: `Object.keys(env)` returns exactly `["__MYAPI_KEY"]`, and
85
+ `MYAPI_KEY` (no underscores) is NOT present.
86
+
87
+ ```js
88
+ export default {
89
+ async fetch(request, env) {
90
+ const r = await fetch('https://api.myapihq.com/database/orgs/<org>/namespaces/app/keys/x', {
91
+ headers: { Authorization: `Bearer ${env.__MYAPI_KEY}` },
92
+ });
93
+ return new Response(await r.text());
94
+ },
95
+ };
96
+ ```
97
+
98
+ **Do not capture the key printed at `fn create` and set it yourself.** Every
99
+ `fn deploy` rotates it, so a manually-set copy goes stale on the next deploy
100
+ and the function starts returning 502 with nothing in the deploy output to
101
+ explain it. The injected `__MYAPI_KEY` is always current.
102
+
103
+ Note the name differs from containers, which receive `MYAPI_KEY` without the
104
+ underscores. Both verified 2026-07-28.
105
+
106
+ ### Using the scoped API key
82
107
 
83
108
  ```bash
84
- # Save the key returned at create/deploy time
109
+ # You do NOT need this env.__MYAPI_KEY is injected and always current.
110
+ # Shown only for calling the function's slots from OUTSIDE the function.
111
+ # Save the API key returned at create/deploy time
85
112
  SCOPED_KEY="hq_live_..."
86
113
 
87
- # Call slots the key was granted — works (within its org + grants)
114
+ # Call slots the API key was granted — works (within its org + grants)
88
115
  curl -H "Authorization: Bearer $SCOPED_KEY" \
89
116
  https://api.myapihq.com/database/orgs/$ORG_ID/namespaces
90
117
 
@@ -99,6 +126,7 @@ curl -H "Authorization: Bearer $SCOPED_KEY" \
99
126
 
100
127
  - The bundle is a **single JavaScript file** (≤4MB). Bundle your dependencies before deploy (esbuild/rollup/etc.).
101
128
  - `--cron` is set at create time; the trigger type is fixed for the function's lifetime.
102
- - Deploy rotates the scoped key on every call — re-capture the printed value if other systems use it.
129
+ - Deploy rotates the scoped API key on every call — re-capture the printed value if other systems use it.
130
+ - `myapi fn env <id> --set KEY=VALUE,OTHER=VALUE` sets several secrets in one call instead of one command each.
103
131
 
104
132
  Run `myapi fn --help` or `myapi fn <subcommand> --help` for full flag reference.
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
5
  Create and publish websites (funnels) to the edge. Push raw HTML to any slug and it goes live instantly on your org's domain or preview subdomain.
6
6
  triggers: [funnel, landing page, website, page, publish, push, slug, html, edge, preview subdomain, makeautonomous]
7
- checksum: sha256-3b463d6ac52fba7d44f89195b5704b02903ffdd9a677655f9c1bff0f13b25ab4
7
+ checksum: sha256-849afbb7c2c60ea88c3476d50bf51289b77cedc819a0c2b69787075ff9c23b4b
8
8
  ---
9
9
 
10
10
  # MyFunnelAPI
@@ -33,7 +33,7 @@ Every funnel auto-provisions a **webhook** at creation (`org_webhook_id`), and e
33
33
  | `myapi funnel push [slug]` | Push HTML from stdin to a slug (default: `/`). **Overwrites** an existing page — refused without `--force`. `--json` prints `{slug, subdomain_url, overwritten, org_id, funnel_id}` |
34
34
  | `myapi funnel publish <dir>` | Upload a whole directory as the funnel's site (`--env dev\|prod`, default prod; `--api-fn <id>`; `--json`). Prod refuses to replace a live site without `--force` |
35
35
  | `myapi funnel pages [funnel_id]` | List the pages currently published to a funnel |
36
- | `myapi funnel form [funnel_id]` | Emit canonical form HTML (and register a binding with `--capture-to`) |
36
+ | `myapi funnel form [funnel_id]` | Emit canonical form HTML (`--capture-to`, `--cta`, `--success`, `--honeypot`) |
37
37
  | `myapi funnel verify [slug]` | Verify a published page is reachable + check links/webhooks |
38
38
  <!-- generated:end -->
39
39
 
@@ -83,7 +83,10 @@ Zero-config form (the happy path most agents want) — still pin the org + funne
83
83
 
84
84
  ```bash
85
85
  myapi funnel create --name acme-demo --org <org_id>
86
- myapi funnel form --slug join --fields email:required,name --funnel <funnel_id> > snippet.html
86
+ myapi funnel form --slug join --fields email:required,name --funnel <funnel_id> \
87
+ --cta "Join" --success "Thanks — check your inbox." --honeypot company_url > snippet.html
88
+ # --honeypot names a hidden field: bots fill it, humans never do, so a
89
+ # submission carrying it is dropped.
87
90
  # paste snippet.html into your page (or pipe through funnel push):
88
91
  cat page-with-snippet.html | myapi funnel push / --funnel <funnel_id>
89
92
  # Submissions land in the funnel's auto-provisioned webhook → CRM upsert on `email` → any bound workflow fires.
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
5
  Hosted git repositories over HTTP. Create repos, read history (log/show/tree/blob/diff), and write atomically (commit/branch/tag/merge) — no clone needed. Real `git clone`/`push` also work over HTTPS with your API key as the password.
6
6
  triggers: [git, repo, repository, clone, push, commit, branch, tag, merge, diff, version control, source control, vcs]
7
- checksum: sha256-a059c8f2b59205a1d66ecf70556b60fa3a3606044aaa54e242344ea652efb5e9
7
+ checksum: sha256-417bafc3e56707f637937f98341d6200c8a9bb6ad5d0b13f84f7b6810e0340f5
8
8
  ---
9
9
 
10
10
  # MyGitAPI
@@ -90,7 +90,7 @@ myapi git delete-branch my-app feature
90
90
  ### Clone & push with real git
91
91
  Hosted repos speak the real git smart-HTTP protocol. Clone, fetch, and push
92
92
  over HTTPS with **HTTP Basic auth — your MyAPI API key is the password**, any
93
- username works (git accepts the key in either field).
93
+ username works (git accepts the API key in either field).
94
94
 
95
95
  ```bash
96
96
  # URL: https://git.mygitapi.com/<org-slug>/<repo>.git
@@ -100,7 +100,7 @@ username works (git accepts the key in either field).
100
100
  # Clone (key as password; "x" is a throwaway username)
101
101
  git clone https://x:$MYAPI_KEY@git.mygitapi.com/my-org-slug/my-app.git
102
102
 
103
- # Or set the remote and let git prompt for the password (paste the key)
103
+ # Or set the remote and let git prompt for the password (paste the API key)
104
104
  git remote add origin https://git.mygitapi.com/my-org-slug/my-app.git
105
105
  git push origin main
106
106
  ```
@@ -117,6 +117,12 @@ surface never leaks which repos exist).
117
117
  - **`commit --base`** is the concurrency guard: pass the expected tip SHA to reject a stale write, or `--base ""` to require the branch be newly created. Omit it to create-or-update.
118
118
  - **Metering.** A `git push` (and `myapi git commit`) is metered like a commit. Clone/fetch (`upload-pack`) is free.
119
119
  - **Limits.** A push body is capped at 100 MiB; per-repo size limits apply (a push past the cap is reported as a receive-pack failure).
120
- - **Auth field.** git may put the key in the username or password slot — both work. Embedding it in the URL (`https://x:$KEY@…`) avoids the interactive prompt but writes the key into `.git/config`; use a credential helper for anything persistent.
120
+ - **Auth field.** git may put the API key in the username or password slot — both work. Embedding it in the URL (`https://x:$KEY@…`) avoids the interactive prompt but writes the API key into `.git/config`; use a credential helper for anything persistent.
121
+
122
+ ## Commit authorship
123
+
124
+ `myapi git commit … --author-name "<n>" --author-email "<e>"` sets the commit
125
+ author. Without them the commit is attributed to the API key's account, which
126
+ makes every agent-written commit look like the same person.
121
127
 
122
128
  Run `myapi git --help` for the full flag reference.
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
5
  Contact database backed by the Goldfox crawl. Filter people by Goldfox confidence tier, seniority, email type, country, link confidence, plus rich behavioral company signals (has_c_level, has_careers_page, has_decision_maker, etc.). The targeting layer for outbound campaigns.
6
6
  triggers: [people, contacts, leads, prospects, search, filter, goldfox, decision-makers, c-level, b2b targeting, corporate email]
7
- checksum: sha256-a4b594a30cc06d2f40fe26c594c1cb6962d91c4dbcc0625210d45a3faa27336e
7
+ checksum: sha256-1eb93087638966eee65fb7a88fe37baaa27a01dd5d97c1ef17387b1a36300c0e
8
8
  ---
9
9
 
10
10
  # MyPeopleAPI
@@ -88,7 +88,7 @@ myapi people get p_MTdlc2llY2xlLmZy.0
88
88
  ```bash
89
89
  # Build the target audience (saved filter)
90
90
  AID=$(myapi audience create "EU decision makers w/ careers signal" \
91
- --source people \
91
+ --from people \
92
92
  --filter '{"seniority":["c_level","vp_director"],"country":["DE","FR","GB"],"email_type":["corporate"],"has_careers_page":true}' \
93
93
  --json | jq -r .id)
94
94
 
@@ -100,7 +100,7 @@ myapi audience members $AID --limit 100 --json > targets.json
100
100
  ## Notes
101
101
 
102
102
  - The dataset is the Goldfox crawl — multi-million-row corporate contact data with provenance signals. Filter quality matters: defaults to `confidence=high` gives 96.4% of rows by count, but it's the curated tier; widening with `confidence=low` brings UGC rows that need spot-checking.
103
- - `seniority`, `email_type`, and `min_link_confidence` are people-only — silently ignored on `my-company-api` and on audiences with `--source company`.
103
+ - `seniority`, `email_type`, and `min_link_confidence` are people-only — silently ignored on `my-company-api` and on audiences with `--from company`.
104
104
  - `keyword` matches the row's **domain**, not name/title. Use `--keyword acme` to find people whose domain contains "acme".
105
105
  - For a persistent target list, use `my-audience-api` (snapshot the filter; re-evaluate on `audience refresh`).
106
106
 
@@ -4,7 +4,7 @@ version: 1.0.0
4
4
  description: >
5
5
  Tracking pixel + identity resolution for MyAPI funnels and email. Capture visits and events, resolve known users to anonymous sessions, stream interaction events for analytics. Pairs with mycrmapi for auto-ingest of pixel_visit events on known contacts.
6
6
  triggers: [pixel, analytics, tracking, visit, event, identity, session, attribution, geo, open pixel]
7
- checksum: sha256-1e8284fbf546ad1bdff32790f56f8c524a19e0b80b92cc6d612ce15295632c9f
7
+ checksum: sha256-562f081ef28c0dae01045a4135f9d073d69c50899145e75c6c97fe75b974cb15
8
8
  ---
9
9
 
10
10
  # MyPixelAPI
@@ -83,6 +83,17 @@ myapi pixel audience
83
83
  - **No write API for synthetic events** — the pixel records what the embedded JS/email-pixel observes. To inject custom timeline entries, use `myapi crm contacts/{id}/events` instead (when reserved-kind allows; today event writes are platform-only).
84
84
  - **`my-crm-api` is the durable record.** Pixel data ages out at ~90 days; CRM events are permanent. If a behavioral signal matters for long-term targeting, promote it into the CRM.
85
85
 
86
+ ## Linking a known identity
87
+
88
+ `myapi pixel identify <pixel_id>` attaches a known identity to an anonymous
89
+ visitor:
90
+
91
+ - `--email <addr>` — the address to link.
92
+ - `--external-id <id>` — your own user id, for joining back to your database.
93
+
94
+ Pass either or both. After this, `pixel identity <pixel_id>` resolves the
95
+ graph across the visitor's sessions.
96
+
86
97
  Run `myapi pixel --help` for inline reference.
87
98
 
88
99
  ## Status