@myapihq/sdk 1.2.5 → 1.2.7

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/config.d.ts CHANGED
@@ -2,6 +2,8 @@ export declare const HQ_BASE: string;
2
2
  export declare const DOMAIN_BASE: string;
3
3
  export declare const FUNNEL_BASE: string;
4
4
  export declare const FUNCTION_BASE: string;
5
+ export declare const PAYMENTS_BASE: string;
6
+ export declare const CONTAINER_BASE: string;
5
7
  export declare const IMAGE_BASE: string;
6
8
  export declare const WEBHOOK_BASE: string;
7
9
  export declare const WORKFLOW_BASE: string;
package/dist/config.js CHANGED
@@ -8,7 +8,7 @@
8
8
  // local dev — `source scripts/local-env.sh` still points everything at
9
9
  // localhost:8080 regardless of the prod default.
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.CRM_BASE = exports.DATABASE_BASE = exports.LLM_BASE = exports.AUDIENCE_BASE = exports.COMPANY_BASE = exports.PEOPLE_BASE = exports.PIXEL_BASE = exports.URL_BASE = exports.STORAGE_BASE = exports.EMAIL_BASE = exports.WORKFLOW_BASE = exports.WEBHOOK_BASE = exports.IMAGE_BASE = exports.FUNCTION_BASE = exports.FUNNEL_BASE = exports.DOMAIN_BASE = exports.HQ_BASE = void 0;
11
+ exports.CRM_BASE = exports.DATABASE_BASE = exports.LLM_BASE = exports.AUDIENCE_BASE = exports.COMPANY_BASE = exports.PEOPLE_BASE = exports.PIXEL_BASE = exports.URL_BASE = exports.STORAGE_BASE = exports.EMAIL_BASE = exports.WORKFLOW_BASE = exports.WEBHOOK_BASE = exports.IMAGE_BASE = exports.CONTAINER_BASE = exports.PAYMENTS_BASE = exports.FUNCTION_BASE = exports.FUNNEL_BASE = exports.DOMAIN_BASE = exports.HQ_BASE = void 0;
12
12
  const GATEWAY = 'https://api.myapihq.com';
13
13
  exports.HQ_BASE = process.env.MYAPI_HQ_URL ?? process.env.MYAPI_API_BASE ?? GATEWAY;
14
14
  exports.DOMAIN_BASE = process.env.MYAPI_DOMAIN_URL ?? 'https://api.mydomainapi.com';
@@ -16,6 +16,8 @@ exports.FUNNEL_BASE = process.env.MYAPI_FUNNEL_URL ?? 'https://api.myfunnelapi.c
16
16
  // New slots — routed via the gateway until brand hosts are DNS-wired
17
17
  // (mirrors the LLM/DATABASE/CRM pattern below).
18
18
  exports.FUNCTION_BASE = process.env.MYAPI_FUNCTION_URL ?? GATEWAY;
19
+ exports.PAYMENTS_BASE = process.env.MYAPI_PAYMENTS_URL ?? GATEWAY;
20
+ exports.CONTAINER_BASE = process.env.MYAPI_CONTAINER_URL ?? GATEWAY;
19
21
  exports.IMAGE_BASE = process.env.MYAPI_IMAGE_URL ?? 'https://api.myimageapi.com';
20
22
  exports.WEBHOOK_BASE = process.env.MYAPI_WEBHOOK_URL ?? 'https://api.mywebhookapi.com';
21
23
  exports.WORKFLOW_BASE = process.env.MYAPI_WORKFLOW_URL ?? 'https://api.myworkflowapi.com';
@@ -0,0 +1,48 @@
1
+ import type { Exposes } from './exposes';
2
+ export declare const EXPOSES: Exposes;
3
+ export type ContainerType = 'service' | 'worker' | 'job';
4
+ export interface Container {
5
+ id: string;
6
+ org_id: string;
7
+ name: string;
8
+ type: ContainerType;
9
+ cron_schedule?: string;
10
+ env: Record<string, unknown>;
11
+ cpu: string;
12
+ memory: string;
13
+ min_instances: number;
14
+ max_instances: number;
15
+ port: number;
16
+ url?: string;
17
+ status: string;
18
+ created_at: string;
19
+ updated_at: string;
20
+ }
21
+ export interface CreatePayload {
22
+ name: string;
23
+ type?: ContainerType;
24
+ cron_schedule?: string;
25
+ env?: Record<string, unknown>;
26
+ cpu?: string;
27
+ memory?: string;
28
+ min_instances?: number;
29
+ max_instances?: number;
30
+ port?: number;
31
+ }
32
+ export interface CreateResponse {
33
+ container: Container;
34
+ scoped_api_key: string;
35
+ scoped_api_key_id: string;
36
+ }
37
+ export interface DeployResponse {
38
+ container_id: string;
39
+ revision_id: string;
40
+ url: string;
41
+ status: string;
42
+ scoped_api_key: string;
43
+ }
44
+ export declare function createContainer(apiKey: string, orgId: string, payload: CreatePayload): Promise<CreateResponse>;
45
+ export declare function listContainers(apiKey: string, orgId: string): Promise<Container[]>;
46
+ export declare function getContainer(apiKey: string, orgId: string, containerId: string): Promise<Container>;
47
+ export declare function deleteContainer(apiKey: string, orgId: string, containerId: string): Promise<void>;
48
+ export declare function deployContainer(apiKey: string, orgId: string, containerId: string, image: string): Promise<DeployResponse>;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EXPOSES = void 0;
4
+ exports.createContainer = createContainer;
5
+ exports.listContainers = listContainers;
6
+ exports.getContainer = getContainer;
7
+ exports.deleteContainer = deleteContainer;
8
+ exports.deployContainer = deployContainer;
9
+ const client_1 = require("./client");
10
+ const config_1 = require("./config");
11
+ // Backend: my-container-api per myapi-hq/internal/routes/container/. Phase 1
12
+ // is metadata + scoped API key issuance; the Cloud Run build/deploy pipeline
13
+ // is Phase 2 — `deployContainer` returns RUNTIME_UNAVAILABLE until it lands.
14
+ exports.EXPOSES = [
15
+ 'POST /container/orgs/{org_id}/containers',
16
+ 'GET /container/orgs/{org_id}/containers',
17
+ 'GET /container/orgs/{org_id}/containers/{id}',
18
+ 'DELETE /container/orgs/{org_id}/containers/{id}',
19
+ 'POST /container/orgs/{org_id}/containers/{id}/deploy',
20
+ ];
21
+ async function createContainer(apiKey, orgId, payload) {
22
+ return (0, client_1.request)('POST', `${config_1.CONTAINER_BASE}/container/orgs/${encodeURIComponent(orgId)}/containers`, apiKey, payload);
23
+ }
24
+ async function listContainers(apiKey, orgId) {
25
+ return (0, client_1.request)('GET', `${config_1.CONTAINER_BASE}/container/orgs/${encodeURIComponent(orgId)}/containers`, apiKey);
26
+ }
27
+ async function getContainer(apiKey, orgId, containerId) {
28
+ return (0, client_1.request)('GET', `${config_1.CONTAINER_BASE}/container/orgs/${encodeURIComponent(orgId)}/containers/${encodeURIComponent(containerId)}`, apiKey);
29
+ }
30
+ async function deleteContainer(apiKey, orgId, containerId) {
31
+ return (0, client_1.request)('DELETE', `${config_1.CONTAINER_BASE}/container/orgs/${encodeURIComponent(orgId)}/containers/${encodeURIComponent(containerId)}`, apiKey);
32
+ }
33
+ // deployContainer ships a revision from a pre-built image ref to Cloud Run
34
+ // (source builds land in a later backend slice). Rotates the scoped key.
35
+ async function deployContainer(apiKey, orgId, containerId, image) {
36
+ return (0, client_1.request)('POST', `${config_1.CONTAINER_BASE}/container/orgs/${encodeURIComponent(orgId)}/containers/${encodeURIComponent(containerId)}/deploy`, apiKey, { image });
37
+ }
@@ -21,7 +21,23 @@ export interface CreateResponse {
21
21
  scoped_api_key: string;
22
22
  scoped_api_key_id: string;
23
23
  }
24
+ export interface DeployResponse {
25
+ function: Fn;
26
+ invocation_url: string;
27
+ scoped_api_key: string;
28
+ }
29
+ export interface FunctionRun {
30
+ id: string;
31
+ function_id: string;
32
+ invoked_at: string;
33
+ duration_ms?: number;
34
+ status?: string;
35
+ error_message?: string;
36
+ }
24
37
  export declare function createFunction(apiKey: string, orgId: string, payload: CreatePayload): Promise<CreateResponse>;
25
38
  export declare function listFunctions(apiKey: string, orgId: string): Promise<Fn[]>;
26
39
  export declare function getFunction(apiKey: string, orgId: string, fnId: string): Promise<Fn>;
27
40
  export declare function deleteFunction(apiKey: string, orgId: string, fnId: string): Promise<void>;
41
+ export declare function uploadBundle(apiKey: string, orgId: string, fnId: string, bundle: Blob | Buffer | string, filename?: string): Promise<DeployResponse>;
42
+ export declare function setFunctionEnv(apiKey: string, orgId: string, fnId: string, name: string, value: string): Promise<void>;
43
+ export declare function listFunctionRuns(apiKey: string, orgId: string, fnId: string): Promise<FunctionRun[]>;
package/dist/function.js CHANGED
@@ -5,18 +5,22 @@ exports.createFunction = createFunction;
5
5
  exports.listFunctions = listFunctions;
6
6
  exports.getFunction = getFunction;
7
7
  exports.deleteFunction = deleteFunction;
8
+ exports.uploadBundle = uploadBundle;
9
+ exports.setFunctionEnv = setFunctionEnv;
10
+ exports.listFunctionRuns = listFunctionRuns;
8
11
  const client_1 = require("./client");
9
12
  const config_1 = require("./config");
10
- // Backend: Story 1 (per myapi-hq/internal/routes/function/crud.go). Metadata
11
- // + scoped API key issuance only — Cloudflare Worker upload, /logs, and /env
12
- // land in Story 2-5. The SDK surface stays minimal until those endpoints
13
- // exist; do not add forward-compat fields here that the backend will silently
14
- // ignore.
13
+ // Backend: Story 1 (metadata + scoped API key) and Story 2/4/5 (deploy,
14
+ // runs, env) per myapi-hq/internal/routes/function/. The /logs endpoint is
15
+ // still pending do not add forward-compat fields the backend will ignore.
15
16
  exports.EXPOSES = [
16
17
  'POST /function/orgs/{org_id}/functions',
17
18
  'GET /function/orgs/{org_id}/functions',
18
19
  'GET /function/orgs/{org_id}/functions/{id}',
19
20
  'DELETE /function/orgs/{org_id}/functions/{id}',
21
+ 'POST /function/orgs/{org_id}/functions/{id}/bundle',
22
+ 'POST /function/orgs/{org_id}/functions/{id}/env',
23
+ 'GET /function/orgs/{org_id}/functions/{id}/runs',
20
24
  ];
21
25
  async function createFunction(apiKey, orgId, payload) {
22
26
  return (0, client_1.request)('POST', `${config_1.FUNCTION_BASE}/function/orgs/${encodeURIComponent(orgId)}/functions`, apiKey, payload);
@@ -30,3 +34,36 @@ async function getFunction(apiKey, orgId, fnId) {
30
34
  async function deleteFunction(apiKey, orgId, fnId) {
31
35
  return (0, client_1.request)('DELETE', `${config_1.FUNCTION_BASE}/function/orgs/${encodeURIComponent(orgId)}/functions/${encodeURIComponent(fnId)}`, apiKey);
32
36
  }
37
+ // uploadBundle deploys a single-file JS bundle (Story 2). The backend
38
+ // wraps it with the MYAPI shim and uploads to Cloudflare Workers. The
39
+ // multipart field MUST be named `bundle`. Raw upload cap is 4MB.
40
+ async function uploadBundle(apiKey, orgId, fnId, bundle, filename = 'bundle.js') {
41
+ const formData = new FormData();
42
+ formData.append('bundle', new Blob([bundle], { type: 'application/javascript' }), filename);
43
+ const response = await fetch(`${config_1.FUNCTION_BASE}/function/orgs/${encodeURIComponent(orgId)}/functions/${encodeURIComponent(fnId)}/bundle`, { method: 'POST', headers: { Authorization: `Bearer ${apiKey}` }, body: formData });
44
+ let result;
45
+ try {
46
+ result = await response.json();
47
+ }
48
+ catch {
49
+ throw new client_1.MyApiError('invalid_json_response', response.status);
50
+ }
51
+ if (!response.ok || !result?.success) {
52
+ const err = result?.error;
53
+ const code = typeof err === 'object' ? (err?.code || 'unknown_error') : (err || 'unknown_error');
54
+ const detail = typeof err === 'object' ? err?.message : undefined;
55
+ throw new client_1.MyApiError(code, response.status, detail, typeof err === 'object' ? err : undefined);
56
+ }
57
+ return result.data;
58
+ }
59
+ // setFunctionEnv writes a secret (Stripe key, etc.) as a Cloudflare Worker
60
+ // Secret on the deployed script (Story 5). The function must already be
61
+ // deployed. The value is never stored in MyAPI Postgres or returned.
62
+ async function setFunctionEnv(apiKey, orgId, fnId, name, value) {
63
+ return (0, client_1.request)('POST', `${config_1.FUNCTION_BASE}/function/orgs/${encodeURIComponent(orgId)}/functions/${encodeURIComponent(fnId)}/env`, apiKey, { name, value });
64
+ }
65
+ // listFunctionRuns returns recent invocation records, most recent first
66
+ // (Story 4). Capped at 100 server-side.
67
+ async function listFunctionRuns(apiKey, orgId, fnId) {
68
+ return (0, client_1.request)('GET', `${config_1.FUNCTION_BASE}/function/orgs/${encodeURIComponent(orgId)}/functions/${encodeURIComponent(fnId)}/runs`, apiKey);
69
+ }
package/dist/funnel.d.ts CHANGED
@@ -49,3 +49,21 @@ export declare function verifyFunnel(apiKey: string, orgId: string, funnelId: st
49
49
  html?: string;
50
50
  slug?: string;
51
51
  }): Promise<VerifyResult>;
52
+ export interface PublishFile {
53
+ path: string;
54
+ content: Blob | Buffer | string;
55
+ }
56
+ export interface PublishOptions {
57
+ env?: 'dev' | 'prod';
58
+ spaMode?: boolean;
59
+ apiFunctionId?: string;
60
+ }
61
+ export interface PublishResult {
62
+ manifest_id: string;
63
+ channel: 'dev' | 'prod';
64
+ file_count: number;
65
+ size_bytes: number;
66
+ spa_mode: boolean;
67
+ published_url: string;
68
+ }
69
+ export declare function publishFiles(apiKey: string, orgId: string, funnelId: string, files: PublishFile[], opts?: PublishOptions): Promise<PublishResult>;
package/dist/funnel.js CHANGED
@@ -8,6 +8,7 @@ exports.deleteFunnel = deleteFunnel;
8
8
  exports.pushFunnelPage = pushFunnelPage;
9
9
  exports.listFunnelPages = listFunnelPages;
10
10
  exports.verifyFunnel = verifyFunnel;
11
+ exports.publishFiles = publishFiles;
11
12
  const client_1 = require("./client");
12
13
  const config_1 = require("./config");
13
14
  exports.EXPOSES = [
@@ -18,6 +19,7 @@ exports.EXPOSES = [
18
19
  'POST /funnel/orgs/{org_id}/funnels/{funnel_id}/push-page',
19
20
  'POST /funnel/orgs/{org_id}/funnels/{funnel_id}/verify',
20
21
  'GET /funnel/orgs/{org_id}/funnels/{funnel_id}/pages',
22
+ 'POST /funnel/orgs/{org_id}/funnels/{funnel_id}/files',
21
23
  ];
22
24
  async function createFunnel(apiKey, orgId, opts) {
23
25
  // v2: accept optional name for N-funnels-per-org. Backend rejects names
@@ -48,3 +50,33 @@ async function listFunnelPages(apiKey, orgId, funnelId) {
48
50
  async function verifyFunnel(apiKey, orgId, funnelId, opts) {
49
51
  return (0, client_1.request)('POST', `${config_1.FUNNEL_BASE}/funnel/orgs/${encodeURIComponent(orgId)}/funnels/${encodeURIComponent(funnelId)}/verify`, apiKey, opts || {});
50
52
  }
53
+ // publishFiles is the my-funnel-api v2 directory publish. Every file is a
54
+ // multipart part named `files`; the part's filename carries the site path.
55
+ // 25MB total cap server-side.
56
+ async function publishFiles(apiKey, orgId, funnelId, files, opts = {}) {
57
+ const formData = new FormData();
58
+ for (const f of files) {
59
+ formData.append('files', new Blob([f.content]), f.path);
60
+ }
61
+ if (opts.env)
62
+ formData.append('env', opts.env);
63
+ if (opts.spaMode !== undefined)
64
+ formData.append('spa_mode', String(opts.spaMode));
65
+ if (opts.apiFunctionId)
66
+ formData.append('api_function_id', opts.apiFunctionId);
67
+ const response = await fetch(`${config_1.FUNNEL_BASE}/funnel/orgs/${encodeURIComponent(orgId)}/funnels/${encodeURIComponent(funnelId)}/files`, { method: 'POST', headers: { Authorization: `Bearer ${apiKey}` }, body: formData });
68
+ let result;
69
+ try {
70
+ result = await response.json();
71
+ }
72
+ catch {
73
+ throw new client_1.MyApiError('invalid_json_response', response.status);
74
+ }
75
+ if (!response.ok || !result?.success) {
76
+ const err = result?.error;
77
+ const code = typeof err === 'object' ? (err?.code || 'unknown_error') : (err || 'unknown_error');
78
+ const detail = typeof err === 'object' ? err?.message : undefined;
79
+ throw new client_1.MyApiError(code, response.status, detail, typeof err === 'object' ? err : undefined);
80
+ }
81
+ return result.data;
82
+ }
package/dist/hq.d.ts CHANGED
@@ -39,6 +39,25 @@ export interface AccountInfo {
39
39
  account_id: string;
40
40
  email?: string;
41
41
  is_anonymous?: boolean;
42
+ spend_cap_cents?: number;
43
+ current_period_spend_cents?: number;
44
+ }
45
+ export type GrantAccess = 'read' | 'write';
46
+ export type Grants = Record<string, GrantAccess>;
47
+ export declare const GRANTABLE_SLOTS: readonly ["domain", "email", "funnel", "storage", "image", "webhook", "workflow", "function", "url", "people", "company", "audience", "llm", "database", "crm"];
48
+ export type KeyKind = 'account' | 'function' | 'manual';
49
+ export type SpendCapPeriod = 'month' | 'day' | 'none';
50
+ export interface ApiKey {
51
+ id: string;
52
+ name: string;
53
+ prefix: string;
54
+ kind: KeyKind;
55
+ org_id: string | null;
56
+ grants: Grants;
57
+ spend_cap_cents: number | null;
58
+ spend_cap_period: string;
59
+ current_period_spend_cents?: number;
60
+ api_key?: string;
42
61
  }
43
62
  export declare function createAnonymousAccount(): Promise<AuthResult & {
44
63
  subdomain_url: string;
@@ -55,19 +74,21 @@ export type FreeTierEntry = {
55
74
  };
56
75
  export declare function getFreeTier(apiKey: string): Promise<FreeTierEntry[] | null>;
57
76
  export declare function getAccount(apiKey: string): Promise<AccountInfo>;
58
- export declare function createApiKey(apiKey: string, name: string): Promise<{
59
- api_key: string;
60
- id: string;
61
- prefix: string;
62
- }>;
63
- export declare function listApiKeys(apiKey: string): Promise<{
64
- id: string;
65
- name: string;
66
- prefix: string;
67
- created_at: string;
68
- last_used_at?: string;
69
- }[]>;
77
+ export interface CreateApiKeyOptions {
78
+ grants?: Grants;
79
+ orgId?: string;
80
+ spendCapCents?: number;
81
+ }
82
+ export declare function createApiKey(apiKey: string, name: string, opts?: CreateApiKeyOptions): Promise<ApiKey>;
83
+ export declare function listApiKeys(apiKey: string): Promise<ApiKey[]>;
70
84
  export declare function revokeApiKey(apiKey: string, keyId: string): Promise<void>;
85
+ export declare function revokeAllKeys(apiKey: string, kind?: KeyKind): Promise<{
86
+ revoked: number;
87
+ }>;
88
+ export declare function setAccountSpendCap(apiKey: string, spendCapCents: number | null, period?: SpendCapPeriod): Promise<{
89
+ spend_cap_cents: number | null;
90
+ spend_cap_period: string;
91
+ }>;
71
92
  export declare function createOrg(apiKey: string, payload: OrgPayload): Promise<Org>;
72
93
  export declare function importOrg(apiKey: string, orgId: string, domain: string, autoAccept?: boolean): Promise<{
73
94
  job_id: string;
@@ -93,6 +114,18 @@ export declare function getBillingHistory(apiKey: string): Promise<{
93
114
  status: string;
94
115
  created_at: string;
95
116
  }[]>;
117
+ export interface ServiceUsage {
118
+ service: string;
119
+ requests: number;
120
+ cost_display: string;
121
+ }
122
+ export interface BillingUsage {
123
+ period: 'month' | '30d';
124
+ since: string;
125
+ services: ServiceUsage[];
126
+ total_display: string;
127
+ }
128
+ export declare function getBillingUsage(apiKey: string, period?: 'month' | '30d'): Promise<BillingUsage>;
96
129
  export declare function setupPayment(apiKey: string): Promise<{
97
130
  url: string;
98
131
  }>;
package/dist/hq.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EXPOSES = void 0;
3
+ exports.GRANTABLE_SLOTS = exports.EXPOSES = void 0;
4
4
  exports.createAnonymousAccount = createAnonymousAccount;
5
5
  exports.sendCode = sendCode;
6
6
  exports.verifyCode = verifyCode;
@@ -10,6 +10,8 @@ exports.getAccount = getAccount;
10
10
  exports.createApiKey = createApiKey;
11
11
  exports.listApiKeys = listApiKeys;
12
12
  exports.revokeApiKey = revokeApiKey;
13
+ exports.revokeAllKeys = revokeAllKeys;
14
+ exports.setAccountSpendCap = setAccountSpendCap;
13
15
  exports.createOrg = createOrg;
14
16
  exports.importOrg = importOrg;
15
17
  exports.getOrgImportStatus = getOrgImportStatus;
@@ -20,6 +22,7 @@ exports.updateOrg = updateOrg;
20
22
  exports.deleteOrg = deleteOrg;
21
23
  exports.getBalance = getBalance;
22
24
  exports.getBillingHistory = getBillingHistory;
25
+ exports.getBillingUsage = getBillingUsage;
23
26
  exports.setupPayment = setupPayment;
24
27
  exports.topUp = topUp;
25
28
  const client_1 = require("./client");
@@ -33,7 +36,9 @@ exports.EXPOSES = [
33
36
  'GET /hq/account/free-tier',
34
37
  'POST /hq/account/create/key',
35
38
  'GET /hq/account/keys',
39
+ 'POST /hq/account/keys/revoke-all',
36
40
  'DELETE /hq/account/delete/key/{key_id}',
41
+ 'PATCH /hq/account/spend-cap',
37
42
  'POST /hq/orgs',
38
43
  'GET /hq/orgs',
39
44
  'GET /hq/orgs/{org_id}',
@@ -44,9 +49,17 @@ exports.EXPOSES = [
44
49
  'POST /hq/org-imports/{import_id}/confirm',
45
50
  'GET /hq/billing/balance',
46
51
  'GET /hq/billing/history',
52
+ 'GET /hq/billing/usage',
47
53
  'POST /hq/billing/setup-payment',
48
54
  'POST /hq/billing/topup',
49
55
  ];
56
+ // The closed grantable-slot vocabulary. Mirrors `iam.GrantableSlots` in the
57
+ // backend — keep in sync. Used to validate `--grant` client-side before the
58
+ // network call. "*" is also valid in a Grants map but is not a slot name.
59
+ exports.GRANTABLE_SLOTS = [
60
+ 'domain', 'email', 'funnel', 'storage', 'image', 'webhook', 'workflow',
61
+ 'function', 'url', 'people', 'company', 'audience', 'llm', 'database', 'crm',
62
+ ];
50
63
  async function createAnonymousAccount() {
51
64
  return (0, client_1.request)('POST', `${config_1.HQ_BASE}/hq/account/anonymous`, undefined, {});
52
65
  }
@@ -65,8 +78,18 @@ async function getFreeTier(apiKey) {
65
78
  async function getAccount(apiKey) {
66
79
  return (0, client_1.request)('GET', `${config_1.HQ_BASE}/hq/account/me`, apiKey);
67
80
  }
68
- async function createApiKey(apiKey, name) {
69
- return (0, client_1.request)('POST', `${config_1.HQ_BASE}/hq/account/create/key`, apiKey, { name });
81
+ // Mints a manual API key. The requested (grants, org, spend cap) must be a
82
+ // subset of the calling key's authority the backend rejects escalation
83
+ // with 403 SCOPE_FORBIDDEN. The full `api_key` is in the response ONCE.
84
+ async function createApiKey(apiKey, name, opts = {}) {
85
+ const body = { name };
86
+ if (opts.grants)
87
+ body.grants = opts.grants;
88
+ if (opts.orgId)
89
+ body.org_id = opts.orgId;
90
+ if (opts.spendCapCents != null)
91
+ body.spend_cap_cents = opts.spendCapCents;
92
+ return (0, client_1.request)('POST', `${config_1.HQ_BASE}/hq/account/create/key`, apiKey, body);
70
93
  }
71
94
  async function listApiKeys(apiKey) {
72
95
  return (0, client_1.request)('GET', `${config_1.HQ_BASE}/hq/account/keys`, apiKey);
@@ -74,6 +97,20 @@ async function listApiKeys(apiKey) {
74
97
  async function revokeApiKey(apiKey, keyId) {
75
98
  return (0, client_1.request)('DELETE', `${config_1.HQ_BASE}/hq/account/delete/key/${encodeURIComponent(keyId)}`, apiKey);
76
99
  }
100
+ // The kill switch. With no `kind`, revokes every active key in the account —
101
+ // including the caller's own; recovery is re-auth via login. A `kind` narrows
102
+ // it to one provenance class.
103
+ async function revokeAllKeys(apiKey, kind) {
104
+ return (0, client_1.request)('POST', `${config_1.HQ_BASE}/hq/account/keys/revoke-all`, apiKey, kind ? { kind } : {});
105
+ }
106
+ // Sets or clears the account-level spend ceiling (IAM "Layer 2"). Pass
107
+ // `null` to clear. `period` defaults to 'month' server-side.
108
+ async function setAccountSpendCap(apiKey, spendCapCents, period) {
109
+ const body = { spend_cap_cents: spendCapCents };
110
+ if (period)
111
+ body.period = period;
112
+ return (0, client_1.request)('PATCH', `${config_1.HQ_BASE}/hq/account/spend-cap`, apiKey, body);
113
+ }
77
114
  async function createOrg(apiKey, payload) {
78
115
  return (0, client_1.request)('POST', `${config_1.HQ_BASE}/hq/orgs`, apiKey, payload);
79
116
  }
@@ -104,6 +141,12 @@ async function getBalance(apiKey) {
104
141
  async function getBillingHistory(apiKey) {
105
142
  return (0, client_1.request)('GET', `${config_1.HQ_BASE}/hq/billing/history`, apiKey);
106
143
  }
144
+ // getBillingUsage rolls up spend by service for a window: the current
145
+ // calendar month (default) or the trailing 30 days ('30d').
146
+ async function getBillingUsage(apiKey, period) {
147
+ const query = period ? `?period=${encodeURIComponent(period)}` : '';
148
+ return (0, client_1.request)('GET', `${config_1.HQ_BASE}/hq/billing/usage${query}`, apiKey);
149
+ }
107
150
  async function setupPayment(apiKey) {
108
151
  return (0, client_1.request)('POST', `${config_1.HQ_BASE}/hq/billing/setup-payment`, apiKey);
109
152
  }
package/dist/index.d.ts CHANGED
@@ -17,3 +17,5 @@ export * as llm from './llm';
17
17
  export * as database from './database';
18
18
  export * as crm from './crm';
19
19
  export * as fn from './function';
20
+ export * as payments from './payments';
21
+ export * as container from './container';
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ var __importStar = (this && this.__importStar) || (function () {
36
36
  };
37
37
  })();
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.fn = exports.crm = exports.database = exports.llm = exports.audience = exports.company = exports.people = exports.url = exports.workflow = exports.webhook = exports.storage = exports.pixel = exports.image = exports.funnel = exports.email = exports.domain = exports.hq = void 0;
39
+ exports.container = exports.payments = exports.fn = exports.crm = exports.database = exports.llm = exports.audience = exports.company = exports.people = exports.url = exports.workflow = exports.webhook = exports.storage = exports.pixel = exports.image = exports.funnel = exports.email = exports.domain = exports.hq = void 0;
40
40
  __exportStar(require("./types"), exports);
41
41
  __exportStar(require("./client"), exports);
42
42
  // Note: config constants (STORAGE_BASE etc.) are NOT re-exported from the
@@ -62,3 +62,5 @@ exports.llm = __importStar(require("./llm"));
62
62
  exports.database = __importStar(require("./database"));
63
63
  exports.crm = __importStar(require("./crm"));
64
64
  exports.fn = __importStar(require("./function"));
65
+ exports.payments = __importStar(require("./payments"));
66
+ exports.container = __importStar(require("./container"));
@@ -0,0 +1,44 @@
1
+ import type { Exposes } from './exposes';
2
+ export declare const EXPOSES: Exposes;
3
+ export interface ConnectStatus {
4
+ tier: string;
5
+ stripe_account_id: string;
6
+ onboarding_status: string;
7
+ application_fee_bps?: number;
8
+ }
9
+ export type ChargeInterval = 'month' | 'year';
10
+ export interface Charge {
11
+ id: string;
12
+ amount_cents: number;
13
+ currency: string;
14
+ every?: ChargeInterval;
15
+ description?: string;
16
+ customer_email?: string;
17
+ status: string;
18
+ created_at: string;
19
+ succeeded_at?: string;
20
+ refunded_at?: string;
21
+ }
22
+ export interface CreateChargeResponse {
23
+ payment_id: string;
24
+ checkout_url: string;
25
+ status: string;
26
+ }
27
+ export interface CreateChargePayload {
28
+ amount_cents: number;
29
+ currency?: string;
30
+ email?: string;
31
+ description?: string;
32
+ every?: ChargeInterval;
33
+ success_url?: string;
34
+ cancel_url?: string;
35
+ }
36
+ export declare function connect(apiKey: string, orgId: string, stripeSecretKey: string, tier?: 't0' | 't1'): Promise<ConnectStatus>;
37
+ export declare function getConnect(apiKey: string, orgId: string): Promise<ConnectStatus>;
38
+ export declare function createCharge(apiKey: string, orgId: string, payload: CreateChargePayload): Promise<CreateChargeResponse>;
39
+ export declare function listCharges(apiKey: string, orgId: string): Promise<Charge[]>;
40
+ export declare function getCharge(apiKey: string, orgId: string, chargeId: string): Promise<Charge>;
41
+ export declare function refundCharge(apiKey: string, orgId: string, chargeId: string): Promise<{
42
+ id: string;
43
+ status: string;
44
+ }>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EXPOSES = void 0;
4
+ exports.connect = connect;
5
+ exports.getConnect = getConnect;
6
+ exports.createCharge = createCharge;
7
+ exports.listCharges = listCharges;
8
+ exports.getCharge = getCharge;
9
+ exports.refundCharge = refundCharge;
10
+ const client_1 = require("./client");
11
+ const config_1 = require("./config");
12
+ // Backend: my-payments-api T0 (BYO Stripe) per
13
+ // myapi-hq/internal/routes/payments/. T1 (Connect Express) is deferred —
14
+ // connect with tier 't1' returns 501. The webhook receiver is public
15
+ // (Stripe signs it); it is listed here for parity but has no SDK function.
16
+ exports.EXPOSES = [
17
+ 'POST /payments/orgs/{org_id}/connect',
18
+ 'GET /payments/orgs/{org_id}/connect',
19
+ 'POST /payments/orgs/{org_id}/charges',
20
+ 'GET /payments/orgs/{org_id}/charges',
21
+ 'GET /payments/orgs/{org_id}/charges/{id}',
22
+ 'POST /payments/orgs/{org_id}/charges/{id}/refund',
23
+ 'POST /payments/webhook/{org_id}',
24
+ ];
25
+ // connect links the org's own Stripe account (T0 — BYO secret key). The
26
+ // key is validated live against Stripe and stored encrypted; it never
27
+ // touches MyAPI Postgres or a log line. Pass a 't1' tier to see the
28
+ // 501 T1_DEFERRED path.
29
+ async function connect(apiKey, orgId, stripeSecretKey, tier = 't0') {
30
+ return (0, client_1.request)('POST', `${config_1.PAYMENTS_BASE}/payments/orgs/${encodeURIComponent(orgId)}/connect`, apiKey, {
31
+ tier,
32
+ stripe_secret_key: stripeSecretKey,
33
+ });
34
+ }
35
+ // getConnect reads the org's connection status. Throws NOT_CONNECTED (404)
36
+ // when the org has not connected Stripe.
37
+ async function getConnect(apiKey, orgId) {
38
+ return (0, client_1.request)('GET', `${config_1.PAYMENTS_BASE}/payments/orgs/${encodeURIComponent(orgId)}/connect`, apiKey);
39
+ }
40
+ // createCharge opens a Stripe Checkout Session on the org's connected
41
+ // account. `every` makes it a subscription; otherwise a one-off payment.
42
+ async function createCharge(apiKey, orgId, payload) {
43
+ return (0, client_1.request)('POST', `${config_1.PAYMENTS_BASE}/payments/orgs/${encodeURIComponent(orgId)}/charges`, apiKey, payload);
44
+ }
45
+ async function listCharges(apiKey, orgId) {
46
+ return (0, client_1.request)('GET', `${config_1.PAYMENTS_BASE}/payments/orgs/${encodeURIComponent(orgId)}/charges`, apiKey);
47
+ }
48
+ async function getCharge(apiKey, orgId, chargeId) {
49
+ return (0, client_1.request)('GET', `${config_1.PAYMENTS_BASE}/payments/orgs/${encodeURIComponent(orgId)}/charges/${encodeURIComponent(chargeId)}`, apiKey);
50
+ }
51
+ // refundCharge issues a full refund (v1 — partial refunds out of scope).
52
+ async function refundCharge(apiKey, orgId, chargeId) {
53
+ return (0, client_1.request)('POST', `${config_1.PAYMENTS_BASE}/payments/orgs/${encodeURIComponent(orgId)}/charges/${encodeURIComponent(chargeId)}/refund`, apiKey);
54
+ }
package/dist/services.js CHANGED
@@ -143,7 +143,9 @@ exports.SERVICES = [
143
143
  {
144
144
  module: 'crm',
145
145
  skill: 'my-crm-api',
146
- domain: 'mycrmapi.com',
146
+ // Brand domain mycrmapi.com was unavailable; mypipelineapi.com chosen
147
+ // and acquired. (Skill stays my-crm-api — domain/skill mismatch accepted.)
148
+ domain: 'mypipelineapi.com',
147
149
  description: 'The canonical store of engaged people + companies. Auto-ingest from inbound webhooks (configurable dot-path). Fixed lifecycle_stage enum, soft delete, event timeline.',
148
150
  category: 'data',
149
151
  status: 'ga',
@@ -191,17 +193,47 @@ exports.SERVICES = [
191
193
  // CLI top-level command is `fn`; SDK namespace is `fn`; skill directory is
192
194
  // `my-function-api` (the agent-discoverable brand name).
193
195
  //
194
- // Backend status: Story 1 shipped (metadata + scoped API key issuance).
195
- // Story 2 (CF Workers upload, invocation URL), Story 4 (/logs), Story 5
196
- // (/env) pending. 'planned' reflects "partial backend, not stable GA."
196
+ // Backend status: deploy/env/runs shipped (CF Workers bundle upload,
197
+ // invocation URL, Worker Secrets, run history). /logs still pending —
198
+ // 'preview' reflects "usable, not yet stable GA."
197
199
  module: 'fn',
198
200
  skill: 'my-function-api',
199
201
  domain: 'myfunctionapi.com',
200
202
  description: 'Run JavaScript functions on the edge. HTTP or cron triggers. Pre-injected MYAPI SDK scoped to the org — no auth tokens in user code.',
201
203
  category: 'compute',
202
- status: 'planned',
204
+ status: 'preview',
203
205
  keywords: k('function', 'serverless', 'edge', 'cloudflare-workers', 'http-handler', 'cron'),
204
206
  },
205
- // Note: my-payments-api removed from registry — backend has no /payments/*
206
- // endpoints yet. Re-add when backend ships per tech-spec-my-payments-api-2026-05-14.md.
207
+ {
208
+ // CLI top-level command + SDK namespace are both `payments`; skill
209
+ // directory is `my-payments-api`.
210
+ //
211
+ // Backend status: T0 (BYO Stripe) shipped — connect, charges (Checkout
212
+ // Sessions), refunds, per-org webhook. T1 (Connect Express) is deferred
213
+ // (connect returns 501 T1_DEFERRED). 'preview' reflects "T0 usable, T1
214
+ // pending."
215
+ module: 'payments',
216
+ skill: 'my-payments-api',
217
+ domain: 'mypaymentsapi.com',
218
+ description: 'Take payments with Stripe Checkout. Connect your Stripe account, create one-off or recurring charges, and refund — hosted checkout, no card handling.',
219
+ category: 'compute',
220
+ status: 'preview',
221
+ keywords: k('payments', 'stripe', 'checkout', 'billing', 'subscription'),
222
+ },
223
+ {
224
+ // CLI top-level command + SDK namespace are both `container`; skill
225
+ // directory is `my-container-api`.
226
+ //
227
+ // Backend status: Phase 1 shipped (metadata + scoped API key). The
228
+ // Cloud Run build/deploy pipeline is Phase 2 — deploy returns
229
+ // RUNTIME_UNAVAILABLE until it lands. 'preview' reflects "usable
230
+ // surface, deploy not yet GA."
231
+ module: 'container',
232
+ skill: 'my-container-api',
233
+ domain: 'mycontainerapi.com',
234
+ description: '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.',
235
+ category: 'compute',
236
+ status: 'preview',
237
+ keywords: k('container', 'cloud-run', 'service', 'worker', 'job'),
238
+ },
207
239
  ];