totalum-sdk 0.1.0-dev.4 → 0.1.0-dev.5

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 (51) hide show
  1. package/README.md +7 -3
  2. package/dist/_types/billing.d-Cj9gNbAW.d.ts +38 -0
  3. package/dist/_types/coerce.d-C1KWvgPp.d.ts +6 -0
  4. package/dist/_types/errors.d-ZrZKjL3U.d.ts +2991 -0
  5. package/dist/_types/integrations.d-Cii20Vl4.d.ts +793 -0
  6. package/dist/_types/ops.d-BIgDkhpR.d.ts +117 -0
  7. package/dist/ai/index.d.ts +424 -0
  8. package/dist/ai/index.js +185 -0
  9. package/dist/analytics/index.d.ts +35 -0
  10. package/dist/analytics/index.js +15 -0
  11. package/dist/browser/index.d.ts +1442 -0
  12. package/dist/browser/index.js +168 -0
  13. package/dist/cron/index.d.ts +180 -0
  14. package/dist/cron/index.js +61 -0
  15. package/dist/d1/errors.js +5 -13
  16. package/dist/d1/index.d.ts +90 -5
  17. package/dist/d1/index.js +6 -10
  18. package/dist/email/index.d.ts +31 -0
  19. package/dist/email/index.js +30 -0
  20. package/dist/errors.js +35 -0
  21. package/dist/files/index.d.ts +119 -0
  22. package/dist/files/index.js +63 -0
  23. package/dist/http.js +85 -0
  24. package/dist/index.d.ts +73 -0
  25. package/dist/index.js +68 -0
  26. package/dist/logs/index.d.ts +51 -0
  27. package/dist/logs/index.js +18 -0
  28. package/dist/payments/index.d.ts +47 -0
  29. package/dist/payments/index.js +20 -0
  30. package/dist/pdf/index.d.ts +42 -0
  31. package/dist/pdf/index.js +17 -0
  32. package/dist/realtime/index.d.ts +68 -0
  33. package/dist/realtime/index.js +20 -0
  34. package/dist/scan/index.d.ts +46 -0
  35. package/dist/scan/index.js +12 -0
  36. package/dist/seo/index.d.ts +23 -0
  37. package/dist/seo/index.js +12 -0
  38. package/dist/speech/index.d.ts +41 -0
  39. package/dist/speech/index.js +22 -0
  40. package/dist/web/index.d.ts +170 -0
  41. package/dist/web/index.js +31 -0
  42. package/dist/webhooks/index.d.ts +48 -0
  43. package/dist/webhooks/index.js +61 -0
  44. package/package.json +77 -5
  45. package/totalum-sdk.md +1040 -0
  46. package/dist/d1/errors.d.ts +0 -27
  47. package/dist/d1/https.d.ts +0 -10
  48. package/dist/d1/lazy.d.ts +0 -7
  49. package/dist/d1/libsql.d.ts +0 -23
  50. package/dist/d1/sql.d.ts +0 -9
  51. package/dist/d1/types.d.ts +0 -72
package/totalum-sdk.md ADDED
@@ -0,0 +1,1040 @@
1
+ # totalum-sdk
2
+
3
+ > Generated by `scripts/gen-docs.mjs` from the types and JSDoc of `totalum-sdk`. Do not edit.
4
+
5
+ The package every Totalum v2 app — and the coding agent building it — uses for Totalum's built-in capabilities: the
6
+ project database (`totalum-sdk/d1`, used through Drizzle) and every integration over HTTPS. Never add a third-party
7
+ SDK or key for something listed here.
8
+
9
+ ## Install and configure
10
+
11
+ ```sh
12
+ npm install --save-exact totalum-sdk
13
+ ```
14
+
15
+ Server-side only (route handlers, server actions, cron handlers, `npx tsx scripts/<name>.ts`). Every namespace reads the
16
+ same environment at call time, never at import; an option of the same name wins:
17
+
18
+ | Variable | Option | Meaning |
19
+ |---|---|---|
20
+ | `TOTALUM_PROJECT_KEY` | `key` | The project key `tlm_pk_…`. Never `NEXT_PUBLIC_`. Missing → `SDK_NOT_CONFIGURED`. |
21
+ | `TOTALUM_SDK_API_URL` | `apiUrl` | Default `https://sdk-api.totalum.app`. |
22
+ | `TOTALUM_ENV` | `env` | `dev` or `live` (default), sent as `x-totalum-env`: the database `totalum-sdk/d1` targets over HTTPS, and dev vs live usage. |
23
+ | `TOTALUM_FILES_URL` | `filesUrl` | The public files host of `files.url()`. |
24
+ | `TOTALUM_AI_BASE_URL` | `aiBaseUrl` | The exact-OpenRouter gateway `ai.gatewayConfig()` returns. |
25
+ | `TOTALUM_WEBHOOK_SECRET` | argument | The secret `webhooks.verify` checks `Totalum-Signature` with. |
26
+
27
+ ```ts
28
+ import { totalum } from 'totalum-sdk'; // or one namespace: import { totalumFiles } from 'totalum-sdk/files';
29
+ const file = await totalum.files.upload(blob, { name: 'avatar.png' });
30
+ ```
31
+
32
+ ## Errors
33
+
34
+ Every failure throws `TotalumError` (`isTotalumError(e)`) with `errorCode` (frozen), `status`, `details` and
35
+ `requestId`; `TotalumD1Error` (`message` shaped like a native D1 error) and `TotalumWebhookError` extend it. A capped
36
+ or disabled feature (`FEATURE_LIMIT_REACHED` 429, `FEATURE_DISABLED` 403) refuses only its own namespace; at a zero
37
+ balance paid calls answer `INSUFFICIENT_CREDITS` 402.
38
+
39
+ **Node-only methods** throw `NODE_ONLY` inside a Worker (the preview and the published app both run on Cloudflare
40
+ Workers) and name the HTTPS replacement: `ai.video.wait()`.
41
+
42
+ Client-side codes: `SDK_NOT_CONFIGURED`, `NOT_SUPPORTED`, `BATCH_FOREIGN_STATEMENT`, `TRANSACTIONS_NOT_SUPPORTED`, `NETWORK_ERROR`, `TIMEOUT`, `RESPONSE_PARSE_ERROR`, `NODE_ONLY`, `WEBHOOK_SECRET_MISSING`, `WEBHOOK_SIGNATURE_INVALID`, `WEBHOOK_TIMESTAMP_EXPIRED`.
43
+
44
+ Server codes: `SERVICE_UNAUTHORIZED`, `SERVICE_REPLAY`, `ACTOR_MISMATCH`, `PAYLOAD_TOO_LARGE`, `VALIDATION_ERROR`, `PROJECT_NOT_FOUND`, `OPERATION_IN_PROGRESS`, `AGENT_RUNNING`, `PROJECT_MOVED`, `OBJECT_MIGRATING`, `INDEX_SHARD_UNAVAILABLE`, `RATE_LIMIT_EXCEEDED`, `PROJECT_PAUSED_RUNAWAY`, `PROJECT_PAUSED_BALANCE`, `PROJECT_SUSPENDED`, `PROJECT_HIBERNATED`, `PROJECT_DELETED`, `PROJECT_PAUSED_BY_USER`, `LIFECYCLE_NOT_APPLICABLE`, `PROJECT_NOT_PAUSED`, `PAUSE_DUMP_EXPIRED`, `PAUSE_VERIFICATION_FAILED`, `DEPLOYMENT_IN_PROGRESS`, `REACTIVATE_IMPORT_MISMATCH`, `RESUME_IMPORT_MISMATCH`, `INSUFFICIENT_CREDITS`, `VCAAS_INSUFFICIENT_CREDITS`, `PROJECT_CREDIT_LIMIT_REACHED`, `FREE_PROMPTS_DISABLED`, `PLAN_REQUIRED`, `FEATURE_LIMIT_REACHED`, `FEATURE_DISABLED`, `AGENT_ALREADY_RUNNING`, `IMPORT_IN_PROGRESS`, `TOO_MANY_RUN_REQUESTS`, `PROMPT_SECURITY_VIOLATION`, `NO_PROCESS_RUNNING`, `RUN_NOT_FOUND`, `DEPLOYMENT_RUNNING`, `ENGINE_NOT_SUPPORTED`, `ENGINE_V2_DISABLED`, `ENGINE_REQUEST_NOT_ELIGIBLE`, `ENGINE_MISMATCH`, `INVALID_ENGINE_VERSION`, `PROJECT_ENGINE_MISMATCH`, `ENGINE_UNAVAILABLE`, `PREVIEW_LABEL_TOO_LONG`, `PROJECT_ALREADY_EXISTS`, `CLOUDFLARE_API_ERROR`, `PROVISIONING_BUSY`, `UNAUTHORIZED`, `LEGACY_KEY_NOT_SUPPORTED`, `SANDBOX_KEY_EXPIRED`, `AUTH_RATE_LIMITED`, `FORBIDDEN_SCOPE`, `KEY_ENV_MISMATCH`, `KEY_LIMIT_EXCEEDED`, `LIVE_DB_READ_ONLY`, `DDL_NOT_ALLOWED`, `MIGRATION_IN_PROGRESS`, `MIGRATION_EDITED`, `SCHEMA_OUT_OF_SYNC`, `LIVE_MIGRATION_FAILED`, `DESTRUCTIVE_MIGRATION_NEEDS_CONFIRMATION`, `DEV_DATABASE_NOT_FOUND`, `DATABASE_ROLE_NOT_FOUND`, `SQL_ERROR`, `SQL_MULTI_STATEMENT`, `SQL_STATEMENT_TOO_LARGE`, `SQL_TOO_MANY_PARAMS`, `STATEMENT_NOT_ALLOWED`, `VIRTUAL_TABLES_NOT_SUPPORTED`, `USE_STORAGE_FOR_FILES`, `D1_TYPE_ERROR`, `MIGRATION_INVALID`, `SYSTEM_TABLE_READ_ONLY`, `SQL_READ_ONLY`, `RESULT_TOO_LARGE`, `QUERY_TIMEOUT`, `DB_OVERLOADED`, `D1_TRANSIENT`, `DB_FULL_NEAR_LIMIT`, `IDEMPOTENCY_KEY_REUSED`, `IDEMPOTENT_REPLAY_UNAVAILABLE`, `TABLE_NOT_FOUND`, `SCHEMA_TOO_LARGE_FOR_COUNTS`, `EXEC_REQUIRES_MIGRATE_MODE`, `MIGRATION_UNKNOWN_IN_DB`, `QUERY_LIMIT_EXCEEDED`, `STORAGE_LIMIT_EXCEEDED`, `METER_UNAVAILABLE`, `COLUMN_NOT_FOUND`, `VALUE_NOT_ALLOWED`, `COLUMN_REQUIRED`, `FILTER_TOO_COMPLEX`, `OFFSET_TOO_LARGE`, `BULK_TOO_LARGE`, `NOT_A_JUNCTION_TABLE`, `AMBIGUOUS_RELATION`, `LIVE_WRITE_CONFIRMATION_REQUIRED`, `RECORD_NOT_FOUND`, `DEV_NAME_GUARD`, `PROD_NAME_GUARD`, `INVALID_RUN_REQUEST`, `RUN_ALREADY_ACTIVE`, `RUN_CONFLICT`, `INVALID_CREDENTIALS`, `ADAPTER_UNAVAILABLE`, `DISK_FULL`, `DEPLOY_FIX_ATTEMPTS_EXHAUSTED`, `TOKEN_REVOKED`, `AM_UPDATE_DOWNLOAD_FAILED`, `AM_UPDATE_BAD_SHA`, `AM_UPDATE_BAD_SIGNATURE`, `AM_UPDATE_INCOMPATIBLE_IMAGE`, `AM_UPDATE_START_FAILED`, `AM_VERSION_UNAVAILABLE`, `AM_UPDATE_FAILED`, `RELEASE_CANARY_NOT_PASSED`, `RELEASE_NOT_FOUND`, `VISUAL_EDIT_PREVIEW_DEPLOYING`, `VISUAL_EDIT_NOT_PATCHABLE`, `VISUAL_EDIT_BASE_MISMATCH`, `VISUAL_EDIT_TYPECHECK_FAILED`, `INVALID_VISUAL_EDIT`, `IMAGE_VERSION_NOT_FOUND`, `IMAGE_VERSION_NOT_PROMOTABLE`, `REALTIME_TICKET_INVALID`, `REALTIME_TICKET_EXPIRED`, `REALTIME_PERMISSION_DENIED`, `REALTIME_MESSAGE_TOO_LARGE`, `REALTIME_MESSAGE_RATE_EXCEEDED`, `REALTIME_CONNECTION_LIMIT_REACHED`, `REALTIME_ROOM_LIMIT_REACHED`, `CONFIRMATION_REQUIRED`, `MIGRATION_NOT_REVERSIBLE`, `ALREADY_ON_PROVIDER`, `DATABASE_MIGRATING`, `LOGWATCH_INACTIVE`, `AGENT_LOG_READS_LIMIT`, `LOGS_UPSTREAM_ERROR`, `ANALYTICS_INVALID_QUERY`, `ANALYTICS_UPSTREAM_ERROR`, `ANALYTICS_WINDOW_OUT_OF_RETENTION`, `INVALID_CIDR`, `RATE_LIMIT_ABOVE_PLAN`, `RATE_LIMIT_DISABLE_NOT_ALLOWED`, `OWNER_ONLY`, `SIGNING_NOT_CONFIGURED`, `SIGNING_ALREADY_CONFIGURED`, `SIGNING_INVALID_KEYSTORE`, `SIGNING_INVALID_ASC_KEY`, `KEYSTORE_DOWNLOAD_EXPIRED`, `KEYSTORE_NOT_DOWNLOADABLE`, `MOBILE_BUILD_RUNNING`, `MOBILE_BUILD_NOT_FOUND`, `MOBILE_BUILD_NOT_READY`, `DOWNLOAD_EXPIRED`, `PROCESS_IN_PROGRESS`, `SANDBOX_NOT_RUNNING`, `MOBILE_LAYER_MISSING`, `MOBILE_BUILD_FAILED`, `MOBILE_ARTIFACT_INVALID`, `SIGNING_FINGERPRINT_MISMATCH`, `AM_RESTARTED`, `LIMIT_ABOVE_PLAN_CEILING`, `UNKNOWN_FEATURE`, `INVALID_LIMIT`, `FEATURE_NOT_DISABLABLE`, `USE_PUT_LIMITS`, `LIMIT_NOT_USER_EDITABLE`, `NOT_AVAILABLE_FOR_ENGINE`, `INVALID_AMOUNT`, `REFUND_EXCEEDS_CHARGES`, `IDEMPOTENCY_CONFLICT`, `ORGANIZATION_NOT_FOUND`, `ACCOUNT_NOT_FOUND`, `PROVIDER_UNAVAILABLE`, `URL_NOT_ALLOWED`, `JOB_NOT_FOUND`, `FILE_TOO_LARGE`, `UNSUPPORTED_FILE_TYPE`, `FILE_NOT_FOUND`, `FILE_KEY_FORBIDDEN`, `FILE_UPLOAD_ERROR`, `FILE_DOWNLOAD_ERROR`, `FILE_DELETE_ERROR`, `UPLOAD_NOT_COMPLETED`, `MISSING_URL`, `MISSING_INPUT`, `MISSING_EXTRACTION_CONFIG`, `MISSING_QUERY`, `SCRAPE_FAILED`, `EXTRACT_FAILED`, `SCREENSHOT_FAILED`, `SEARCH_FAILED`, `SCRAPE_BLOCKED`, `SESSION_NOT_FOUND`, `SESSION_EXPIRED`, `SESSION_BUSY`, `SESSION_LIMIT_REACHED`, `SESSION_ENDED_INSUFFICIENT_CREDITS`, `ACTION_TIMEOUT`, `ACTION_FAILED`, `UNKNOWN_COMMAND`, `BATCH_TOO_LARGE`, `SKIPPED`, `UPLOAD_TOO_LARGE`, `DOWNLOAD_TOO_LARGE`, `CAPTURE_LIMIT_REACHED`, `CAPTCHA_UNSOLVED`, `BROWSER_CDP_NODE_ONLY`, `DIALOG_NOT_OPEN`, `STEALTH_TIER_UNAVAILABLE`, `DOMAIN_NOT_ALLOWED`, `CONTEXT_SEED_UNSUPPORTED`, `EXTENSION_TOO_LARGE`, `NL_PROVIDER_UNAVAILABLE`, `PROGRAM_TOO_LARGE`, `PROGRAM_UNBOUNDED`, `UNKNOWN_STEP`, `PROGRAM_IN_FLIGHT`, `PROGRAM_TIMEOUT`, `PROGRAM_NOT_FOUND`, `PROGRAM_STEP_FAILED`, `PROGRAM_LIMIT_REACHED`, `CREATE_PDF_FROM_HTML_ERROR`, `GENERATE_PDF_BY_URL_ERROR`, `PDF_TIMEOUT`, `PDF_TOO_LARGE`, `FILENAME_REQUIRED`, `SCANUM_EYE_ARRAY_NOT_SUPPORTED`, `INVALID_EXTRA_FIELD_TYPE`, `SCANUM_EYE_PDF_NOT_SUPPORTED`, `UNSUPPORTED_SCAN_MODEL`, `SCAN_DOCUMENT_ERROR`, `SCAN_INVOICE_ERROR`, `OCR_IMAGE_PROCESSING_ERROR`, `OCR_PDF_PROCESSING_ERROR`, `SCAN_TOO_MANY_PAGES`, `SCAN_PDF_ENCRYPTED`, `SCAN_XFA_UNSUPPORTED`, `AUDIO_FILE_REQUIRED`, `AUDIO_FILE_TOO_LARGE`, `INVALID_AUDIO_FORMAT`, `AUDIO_TRANSCRIPTION_ERROR`, `TTS_TEXT_TOO_LONG`, `TTS_VOICE_UNKNOWN`, `TOO_MANY_AUDIO_TRANSCRIPTIONS`, `EMAIL_SEND_FAILED`, `TOO_MANY_ATTACHMENTS`, `INVALID_ATTACHMENT_URL`, `ATTACHMENT_TOO_LARGE`, `TOO_MANY_RECIPIENTS`, `EMAIL_RECIPIENT_SUPPRESSED`, `EMAIL_DOMAIN_NOT_VERIFIED`, `EMAIL_LOCAL_PART_TAKEN`, `EMAIL_SENDING_PAUSED`, `EMAIL_DOMAINS_REQUIRE_PAID_PLAN`, `SUPPRESSION_PERMANENT`, `DEV_RECIPIENT_NOT_ALLOWED`, `CRON_LIMIT_REACHED`, `INVALID_SCHEDULE`, `CRON_URL_NOT_ALLOWED`, `CRON_JOB_NOT_FOUND`, `CRON_REQUIRES_PUBLISHED_PROJECT`, `URL_NOT_PROJECT_HOST`, `INDEXNOW_ERROR`, `MCP_VERIFY_FAILED`, `MCP_NAME_RESERVED`, `MCP_LIMIT_REACHED`, `MCP_SERVER_NOT_FOUND`, `PAYMENTS_NOT_ENABLED`, `PAYMENTS_LIVE_ONBOARDING_REQUIRED`, `CARD_DATA_NOT_ACCEPTED`, `STRIPE_ERROR`, `STRIPE_RATE_LIMITED`, `PAYMENTS_WEBHOOK_SIGNATURE_INVALID`, `AI_MODEL_NOT_ALLOWED`, `AI_MODEL_UNKNOWN`, `AI_INVALID_SCHEMA`, `AI_CONTENT_BLOCKED`, `AI_CONTEXT_TOO_LONG`, `AI_PROVIDER_QUOTA`, `AI_PROVIDER_UNAVAILABLE`, `AI_STREAM_ERROR`, `AI_VIDEO_JOB_NOT_FOUND`, `AI_VIDEO_FAILED`, `MISSING_VIDEO_URL`, `MISSING_PROMPT`, `INVALID_VIDEO_URL`, `INVALID_VIDEO_URL_PROTOCOL`, `INVALID_MIME_TYPE_HINT`, `VIDEO_TOO_LARGE`, `VIDEO_URL_UNREACHABLE`, `VIDEO_URL_NOT_A_VIDEO`, `YOUTUBE_VIDEO_UNAVAILABLE`, `NO_PAYMENT_METHOD`, `DOMAIN_CONTACT_REQUIRED`, `DOMAIN_UNAVAILABLE`, `DOMAIN_PREMIUM_NOT_ALLOWED`, `TLD_NOT_ALLOWED`, `DOMAIN_LIMIT_REACHED`, `PRICE_CHANGED`, `PAYMENT_FAILED`, `REGISTRATION_FAILED`, `DOMAIN_NOT_RENEWABLE`, `DOMAIN_ALREADY_ATTACHED`, `DNS_RECORD_MANAGED`, `DNS_RECORD_CONFLICT`, `DNS_RECORD_LIMIT`, `DOMAIN_TRANSFER_LOCKED`, `DOMAIN_NOT_FOUND`, `DOMAIN_IN_USE`, `DOMAIN_ALREADY_ADDED`, `NO_DEPLOYMENT`, `REDIRECT_LIMIT_REACHED`, `REDIRECT_INVALID`, `APEX_NOT_FLATTENABLE`.
45
+
46
+ ## `totalum-sdk`
47
+
48
+ Every namespace below on one object (`totalum.files`, `totalum.ai`, …); the root entry also re-exports every subpath's exports, and each subpath can be imported alone (smaller bundles).
49
+
50
+ ### `createTotalum`
51
+
52
+ ```ts
53
+ createTotalum(options?: TotalumOptions)
54
+ ```
55
+
56
+ Every integration namespace on one object, each built on first access with the same options — no I/O
57
+ and no env read until a method is called. The database is `totalumD1()` from `totalum-sdk/d1`, not a namespace.
58
+
59
+ ```ts
60
+ const totalum = createTotalum({ env: 'dev' });
61
+ await totalum.email.send({ to: 'a@b.c', subject: 'Hi', html: '<p>Hi</p>' });
62
+ ```
63
+
64
+ ### `totalum`
65
+
66
+ ```ts
67
+ const totalum
68
+ ```
69
+
70
+ The default instance, configured from the environment (`TOTALUM_PROJECT_KEY`, `TOTALUM_SDK_API_URL`, `TOTALUM_ENV`).
71
+
72
+ ## `totalum-sdk/d1`
73
+
74
+ ### `totalumD1`
75
+
76
+ ```ts
77
+ totalumD1(options?: TotalumD1Options): D1Database
78
+ ```
79
+
80
+ A `D1Database` for the project's own database wherever the code runs: the bound
81
+ `TOTALUM_DB` inside a Worker, the libsql adapter when the environment moved to Turso, and an HTTPS client to
82
+ SDK-API everywhere else. Detection happens on the first statement, never at call time.
83
+
84
+ ## `totalum-sdk/files`
85
+
86
+ ### `totalumFiles`
87
+
88
+ ```ts
89
+ totalumFiles(options?: TotalumFilesOptions)
90
+ ```
91
+
92
+ `totalum.files` over HTTPS with the project key. Every call returns the file
93
+ descriptor `{key, fileName, fileSize, contentType, fileUrl, visibility, createdAt}` meant to be stored as-is in the
94
+ row's file column; failures throw `TotalumError` with SDK-API's frozen code.
95
+
96
+ #### `files.upload`
97
+
98
+ ```ts
99
+ files.upload(input: string | Blob | ArrayBuffer | Uint8Array<ArrayBufferLike>, opts?: UploadOptions): Promise<{ key: string; fileName: string; fileSize: number; contentType: string; fileUrl: string | null; visibility: 'public-by-link' | 'private'; createdAt: string; etag?: string | undefined; storageClass?: 'Standard' | 'InfrequentAccess' | undefined; name?: string | undefined; url?: string | null | undefined; size?: number | undefined; id?: string | undefined; fileNameId?: string | undefined; }>
100
+ ```
101
+
102
+ Up to 25 MB through SDK-API; larger files go through `getUploadUrl` + `complete`.
103
+
104
+ #### `files.getUploadUrl`
105
+
106
+ ```ts
107
+ files.getUploadUrl(input: { name: string; contentType: string; size: number; folder?: string | undefined; private?: boolean | undefined; }): Promise<{ uploadUrl: string; key: string; headers: Record<string, string>; expiresAt: string; }>
108
+ ```
109
+
110
+ A presigned PUT (15 min, bound to this type and size) for a direct browser/Node upload; then `complete(key)`.
111
+
112
+ #### `files.complete`
113
+
114
+ ```ts
115
+ files.complete(key: string): Promise<{ key: string; fileName: string; fileSize: number; contentType: string; fileUrl: string | null; visibility: 'public-by-link' | 'private'; createdAt: string; etag?: string | undefined; storageClass?: 'Standard' | 'InfrequentAccess' | undefined; name?: string | undefined; url?: string | null | undefined; size?: number | undefined; id?: string | undefined; fileNameId?: string | undefined; }>
116
+ ```
117
+
118
+ Registers a file uploaded with `getUploadUrl` and returns its descriptor.
119
+
120
+ #### `files.list`
121
+
122
+ ```ts
123
+ files.list(q?: Partial<Record<'name' | 'folder' | 'type' | 'createdFrom' | 'createdTo' | 'sizeFrom' | 'sizeTo' | 'cursor' | 'limit', string | number>>): Promise<{ items: { key: string; fileName: string; fileSize: number; contentType: string; fileUrl: string | null; visibility: 'public-by-link' | 'private'; createdAt: string; etag?: string | undefined; storageClass?: 'Standard' | 'InfrequentAccess' | undefined; name?: string | undefined; url?: string | null | undefined; size?: number | undefined; id?: string | undefined; fileNameId?: string | undefined; }[]; nextCursor: string | null; totalBytes: number; fileCount: number; }>
124
+ ```
125
+
126
+ One page of the project's files, newest first: filter by `folder`, `name`, `type`, created and size ranges; `cursor`
127
+ from the previous page's `nextCursor`.
128
+
129
+ #### `files.get`
130
+
131
+ ```ts
132
+ files.get(key: string): Promise<{ key: string; fileName: string; fileSize: number; contentType: string; fileUrl: string | null; visibility: 'public-by-link' | 'private'; createdAt: string; etag?: string | undefined; storageClass?: 'Standard' | 'InfrequentAccess' | undefined; name?: string | undefined; url?: string | null | undefined; size?: number | undefined; id?: string | undefined; fileNameId?: string | undefined; }>
133
+ ```
134
+
135
+ The descriptor of one file; `FILE_NOT_FOUND` (404) when it does not exist.
136
+
137
+ #### `files.getSignedUrl`
138
+
139
+ ```ts
140
+ files.getSignedUrl(key: string, opts?: { expiresInSeconds?: number | undefined; download?: boolean | undefined; }): Promise<string>
141
+ ```
142
+
143
+ A presigned GET that R2 verifies: 15 min by default, at most 7 days — the way to hand a private file to a browser.
144
+
145
+ #### `files.getDownloadUrl`
146
+
147
+ ```ts
148
+ files.getDownloadUrl(key: string, opts?: { expiresInSeconds?: number | undefined; download?: boolean | undefined; }): Promise<string>
149
+ ```
150
+
151
+ Same as `getSignedUrl`.
152
+
153
+ #### `files.presign`
154
+
155
+ ```ts
156
+ files.presign(keys: string[], opts?: { ttl?: number | undefined; download?: boolean | undefined; }): Promise<Record<string, string>>
157
+ ```
158
+
159
+ Signed GET URLs for many keys at once (`ttl` in seconds, ≤ 7 days).
160
+
161
+ #### `files.delete`
162
+
163
+ ```ts
164
+ files.delete(keys: string | string[]): Promise<void>
165
+ ```
166
+
167
+ Deletes one key, or up to 1000 keys at once.
168
+
169
+ #### `files.stream`
170
+
171
+ ```ts
172
+ files.stream(key: string, opts?: { range?: string | undefined; }): Promise<Response>
173
+ ```
174
+
175
+ The object itself (private files included), with `Range` support; errors throw like every other call.
176
+
177
+ #### `files.url`
178
+
179
+ ```ts
180
+ files.url(key: string): string
181
+ ```
182
+
183
+ Sync, no I/O: the public URL of a `p/` key, or the authenticated SDK-API URL of a private `pv/` key.
184
+
185
+ ## `totalum-sdk/payments`
186
+
187
+ ### `totalumPayments`
188
+
189
+ ```ts
190
+ totalumPayments(options?: TotalumClientOptions)
191
+ ```
192
+
193
+ `totalum.payments` over SDK-API `/v1/payments/*` with a project key (scope `payments`): Stripe
194
+ Connect direct charges on the project's own connected account. Card data never passes through here — send buyers to
195
+ the hosted Checkout `url` (SAQ-A); SDK-API refuses card fields with `CARD_DATA_NOT_ACCEPTED`.
196
+
197
+ #### `payments.getStatus`
198
+
199
+ ```ts
200
+ payments.getStatus(): Promise<{ enabled: boolean; mode: 'connect' | 'own_key'; accountId: string | null; livemode: boolean; chargesEnabled: boolean; payoutsEnabled: boolean; detailsSubmitted: boolean; requirements: { currentlyDue: string[]; pastDue: string[]; eventuallyDue: string[]; }; applicationFeeBps: number; }>
201
+ ```
202
+
203
+ Whether the project's Stripe account can take payments (charges, payouts, pending requirements).
204
+
205
+ #### `payments.onboardingLink`
206
+
207
+ ```ts
208
+ payments.onboardingLink(input: { returnUrl: string; refreshUrl: string; type?: 'account_onboarding' | 'account_update' | undefined; country?: string | undefined; }): Promise<{ url: string; expiresAt: string; }>
209
+ ```
210
+
211
+ Stripe's hosted onboarding for the project owner (single use; never for the agent's sandbox key).
212
+
213
+ #### `payments.createCheckout`
214
+
215
+ ```ts
216
+ payments.createCheckout(input: { mode: 'payment' | 'subscription' | 'setup'; successUrl: string; cancelUrl: string; lineItems?: ({ priceId: string; quantity: number; } | { name: string; unitAmount: number; currency: string; quantity: number; })[] | undefined; currency?: string | undefined; customerEmail?: string | undefined; customerId?: string | undefined; metadata?: Record<string, string> | undefined; allowPromotionCodes?: boolean | undefined; automaticTax?: boolean | undefined; trialDays?: number | undefined; clientReferenceId?: string | undefined; }): Promise<{ id: string; url: string; }>
217
+ ```
218
+
219
+ A hosted Checkout Session: `payment`, `subscription`, or `setup` (save a card for later). Redirect to `url`.
220
+
221
+ #### `payments.customerPortalLink`
222
+
223
+ ```ts
224
+ payments.customerPortalLink(input: { customerId: string; returnUrl: string; }): Promise<{ url: string; }>
225
+ ```
226
+
227
+ Stripe's hosted portal where a customer manages their subscriptions and saved cards.
228
+
229
+ ## `totalum-sdk/webhooks`
230
+
231
+ ### `verifyWebhook`
232
+
233
+ ```ts
234
+ verifyWebhook(rawBody: string, headers: Headers | Record<string, string | undefined>, secret?: string | undefined, now?: number): Promise<{ id: string; type: string; createdAt: string; projectId: string; env: 'dev' | 'live'; data: Record<string, unknown>; livemode?: boolean | undefined; }>
235
+ ```
236
+
237
+ `totalum.webhooks.verify`: checks `Totalum-Signature: t=…,v1=…` — HMAC-SHA256 keyed with the
238
+ endpoint's secret string over `${t}.${rawBody}` — within ±300 s, and returns the parsed event. Pass the body exactly
239
+ as received (`await request.text()`). `secret` defaults to `TOTALUM_WEBHOOK_SECRET`.
240
+
241
+ ```ts
242
+ const event = await verifyWebhook(await request.text(), request.headers);
243
+ ```
244
+
245
+ ### `totalumWebhooks`
246
+
247
+ ```ts
248
+ totalumWebhooks(options?: TotalumClientOptions)
249
+ ```
250
+
251
+ `totalum.webhooks` over SDK-API `/v1/webhooks` (a key with scope `*`): where the project receives its
252
+ signed events (payments, e-mail, browser programs, `project.credits.exhausted`) and the secret they are signed with.
253
+
254
+ #### `webhooks.verify`
255
+
256
+ ```ts
257
+ webhooks.verify(rawBody: string, headers: Headers | Record<string, string | undefined>, secret?: string | undefined, now?: number): Promise<{ id: string; type: string; createdAt: string; projectId: string; env: 'dev' | 'live'; data: Record<string, unknown>; livemode?: boolean | undefined; }>
258
+ ```
259
+
260
+ Same as `verifyWebhook`: checks `Totalum-Signature` and returns the parsed event.
261
+
262
+ #### `webhooks.get`
263
+
264
+ ```ts
265
+ webhooks.get(): Promise<{ url: string | null; enabled: boolean; secretPrefix: string | null; }>
266
+ ```
267
+
268
+ The endpoint and the first characters of its secret (the secret itself is shown only by `rotateSecret`).
269
+
270
+ #### `webhooks.setUrl`
271
+
272
+ ```ts
273
+ webhooks.setUrl(url: string): Promise<{ url: string | null; enabled: boolean; secretPrefix: string | null; }>
274
+ ```
275
+
276
+ Sets the `https://` URL the project's events are delivered to.
277
+
278
+ #### `webhooks.rotateSecret`
279
+
280
+ ```ts
281
+ webhooks.rotateSecret(): Promise<{ secret: string; }>
282
+ ```
283
+
284
+ A new signing secret, shown once; the old one keeps co-signing for 24 h. Store it as `TOTALUM_WEBHOOK_SECRET`.
285
+
286
+ ## `totalum-sdk/web`
287
+
288
+ ### `totalumWeb`
289
+
290
+ ```ts
291
+ totalumWeb(options?: TotalumClientOptions)
292
+ ```
293
+
294
+ `totalum.web` over SDK-API `/v1/web/*` (scope `web`): Firecrawl scrape/search/map/crawl and Browser
295
+ Run screenshots, charged provider cost × 28 — every result carries `usage.credits`.
296
+
297
+ #### `web.scrape`
298
+
299
+ ```ts
300
+ web.scrape(url: string, opts?: Omit<{ url: string; formats?: ('screenshot' | 'markdown' | 'html' | 'rawHtml' | 'links' | 'json' | 'summary')[] | undefined; onlyMainContent?: boolean | undefined; waitFor?: number | undefined; timeout?: number | undefined; proxy?: 'basic' | 'stealth' | 'auto' | undefined; location?: { country?: string | undefined; languages?: string[] | undefined; } | undefined; actions?: Record<string, unknown>[] | undefined; schema?: Record<string, unknown> | undefined; prompt?: string | undefined; cacheMaxAgeMs?: number | undefined; }, 'url'>): Promise<{ url: string; statusCode: number; metadata: { sourceURL: string; title?: string | undefined; description?: string | undefined; language?: string | undefined; }; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; markdown?: string | undefined; html?: string | undefined; rawHtml?: string | undefined; links?: string[] | undefined; screenshotUrl?: string | undefined; json?: unknown; summary?: string | undefined; contentUrl?: string | undefined; }>
301
+ ```
302
+
303
+ One page as `markdown`, `html`, `links`, … (Firecrawl).
304
+
305
+ ```ts
306
+ const { markdown } = await web.scrape('https://example.com', { formats: ['markdown'] });
307
+ ```
308
+
309
+ #### `web.search`
310
+
311
+ ```ts
312
+ web.search(query: string, opts?: Omit<{ query: string; limit?: number | undefined; sources?: ('web' | 'news' | 'images')[] | undefined; location?: { country?: string | undefined; city?: string | undefined; } | undefined; timeRange?: 'day' | 'month' | 'week' | 'year' | undefined; scrapeOptions?: { formats?: ('screenshot' | 'markdown' | 'html' | 'rawHtml' | 'links' | 'json' | 'summary')[] | undefined; onlyMainContent?: boolean | undefined; waitFor?: number | undefined; timeout?: number | undefined; proxy?: 'basic' | 'stealth' | 'auto' | undefined; location?: { country?: string | undefined; languages?: string[] | undefined; } | undefined; actions?: Record<string, unknown>[] | undefined; schema?: Record<string, unknown> | undefined; prompt?: string | undefined; cacheMaxAgeMs?: number | undefined; } | undefined; }, 'query'>): Promise<{ web: { title: string; url: string; position: number; snippet?: string | undefined; }[]; news?: { title: string; url: string; position: number; snippet?: string | undefined; }[] | undefined; images?: Record<string, unknown>[] | undefined; scraped?: { url: string; statusCode: number; metadata: { sourceURL: string; title?: string | undefined; description?: string | undefined; language?: string | undefined; }; markdown?: string | undefined; html?: string | undefined; rawHtml?: string | undefined; links?: string[] | undefined; screenshotUrl?: string | undefined; json?: unknown; summary?: string | undefined; contentUrl?: string | undefined; }[] | undefined; } & { usage: { vendor?: string | undefined; units?: number | undefined; credits: number; }; }>
313
+ ```
314
+
315
+ A web search; with `scrapeOptions` each result also carries its page content.
316
+
317
+ #### `web.map`
318
+
319
+ ```ts
320
+ web.map(url: string, opts?: Omit<{ url: string; search?: string | undefined; limit?: number | undefined; }, 'url'>): Promise<{ links: string[]; } & { usage: { vendor?: string | undefined; units?: number | undefined; credits: number; }; }>
321
+ ```
322
+
323
+ The URLs of a site (sitemap and links), without fetching the pages.
324
+
325
+ #### `web.crawl`
326
+
327
+ ```ts
328
+ web.crawl(url: string, opts?: Omit<{ url: string; limit?: number | undefined; maxDepth?: number | undefined; includePaths?: string[] | undefined; excludePaths?: string[] | undefined; scrapeOptions?: { formats?: ('screenshot' | 'markdown' | 'html' | 'rawHtml' | 'links' | 'json' | 'summary')[] | undefined; onlyMainContent?: boolean | undefined; waitFor?: number | undefined; timeout?: number | undefined; proxy?: 'basic' | 'stealth' | 'auto' | undefined; location?: { country?: string | undefined; languages?: string[] | undefined; } | undefined; actions?: Record<string, unknown>[] | undefined; schema?: Record<string, unknown> | undefined; prompt?: string | undefined; cacheMaxAgeMs?: number | undefined; } | undefined; webhook?: boolean | undefined; }, 'url'>): Promise<{ jobId: string; estimatedCredits?: number | undefined; }>
329
+ ```
330
+
331
+ `202 {jobId}`: poll `crawlStatus` until the job leaves `running`; that read settles its charge.
332
+
333
+ #### `web.crawlStatus`
334
+
335
+ ```ts
336
+ web.crawlStatus(jobId: string): Promise<{ jobId: string; status: 'completed' | 'queued' | 'running' | 'failed' | 'cancelled' | 'expired'; total: number; completed: number; creditsUsed: number; data: { url: string; statusCode: number; metadata: { sourceURL: string; title?: string | undefined; description?: string | undefined; language?: string | undefined; }; markdown?: string | undefined; html?: string | undefined; rawHtml?: string | undefined; links?: string[] | undefined; screenshotUrl?: string | undefined; json?: unknown; summary?: string | undefined; contentUrl?: string | undefined; }[]; next?: string | undefined; resultUrl?: string | undefined; }>
337
+ ```
338
+
339
+ The crawl job: `status`, pages so far and their content.
340
+
341
+ #### `web.cancelCrawl`
342
+
343
+ ```ts
344
+ web.cancelCrawl(jobId: string): Promise<{ jobId: string; status: 'completed' | 'queued' | 'running' | 'failed' | 'cancelled' | 'expired'; total: number; completed: number; creditsUsed: number; data: { url: string; statusCode: number; metadata: { sourceURL: string; title?: string | undefined; description?: string | undefined; language?: string | undefined; }; markdown?: string | undefined; html?: string | undefined; rawHtml?: string | undefined; links?: string[] | undefined; screenshotUrl?: string | undefined; json?: unknown; summary?: string | undefined; contentUrl?: string | undefined; }[]; next?: string | undefined; resultUrl?: string | undefined; }>
345
+ ```
346
+
347
+ Stops a running crawl; pages already crawled are charged.
348
+
349
+ #### `web.screenshot`
350
+
351
+ ```ts
352
+ web.screenshot(input: { url?: string | undefined; html?: string | undefined; fullPage?: boolean | undefined; viewport?: { width: number; height: number; } | undefined; format?: 'png' | 'jpeg' | 'webp' | undefined; waitForSelector?: string | undefined; inline?: boolean | undefined; }): Promise<{ key: string; url: string; format: 'png' | 'jpeg' | 'webp'; base64?: string | undefined; } & { usage: { vendor?: string | undefined; units?: number | undefined; credits: number; }; }>
353
+ ```
354
+
355
+ A screenshot of a `url` or of inline `html`, stored as a project file (`key`, `url`).
356
+
357
+ ## `totalum-sdk/pdf`
358
+
359
+ ### `totalumPdf`
360
+
361
+ ```ts
362
+ totalumPdf(options?: TotalumClientOptions)
363
+ ```
364
+
365
+ `totalum.pdf` over `/v1/pdf/*` (scope `files:write`): a new file in the project's storage each time.
366
+
367
+ #### `pdf.fromHtml`
368
+
369
+ ```ts
370
+ pdf.fromHtml(input: { name: string; html?: string | undefined; base64HtmlString?: string | undefined; options?: { format?: string | undefined; landscape?: boolean | undefined; margin?: Record<string, string> | undefined; printBackground?: boolean | undefined; headerTemplate?: string | undefined; footerTemplate?: string | undefined; displayHeaderFooter?: boolean | undefined; } | undefined; waitForSelector?: string | undefined; }): Promise<{ url: string; fileName: string; key: string; } & { usage: { vendor?: string | undefined; units?: number | undefined; credits: number; }; }>
371
+ ```
372
+
373
+ A PDF rendered from HTML, stored as a project file (`key`, `url`).
374
+
375
+ ```ts
376
+ const { url } = await pdf.fromHtml({ html: '<h1>Invoice 12</h1>', name: 'invoice-12' });
377
+ ```
378
+
379
+ #### `pdf.fromUrl`
380
+
381
+ ```ts
382
+ pdf.fromUrl(input: { url: string; name: string; options?: { format?: string | undefined; landscape?: boolean | undefined; margin?: Record<string, string> | undefined; printBackground?: boolean | undefined; headerTemplate?: string | undefined; footerTemplate?: string | undefined; displayHeaderFooter?: boolean | undefined; } | undefined; cookies?: Record<string, unknown>[] | undefined; headers?: Record<string, string> | undefined; }): Promise<{ url: string; fileName: string; key: string; } & { usage: { vendor?: string | undefined; units?: number | undefined; credits: number; }; }>
383
+ ```
384
+
385
+ A PDF of a web page, stored as a project file.
386
+
387
+ ## `totalum-sdk/scan`
388
+
389
+ ### `totalumScan`
390
+
391
+ ```ts
392
+ totalumScan(options?: TotalumClientOptions)
393
+ ```
394
+
395
+ `totalum.scan` over `/v1/scan/*` (scope `scan`): a vision model through Totalum's AI gateway.
396
+
397
+ #### `scan.document`
398
+
399
+ ```ts
400
+ scan.document(input: { properties: Record<string, Record<string, unknown>>; options?: { model?: 'scanum' | 'scanum-pro' | 'scanum-eye' | 'scanum-eye-pro' | undefined; removeFileAfterScan?: boolean | undefined; returnOcrFullResult?: boolean | undefined; scanDescription?: string | undefined; processEveryPdfPageAsDifferentScan?: boolean | undefined; maxPages?: number | undefined; pdfPages?: number[] | undefined; minimumConfidence?: number | undefined; } | undefined; fileName?: string | undefined; key?: string | undefined; url?: string | undefined; }): Promise<ScanDocumentResult>
401
+ ```
402
+
403
+ Extracts the fields described by `properties` from a document or image (one set per page on request).
404
+
405
+ #### `scan.ocr`
406
+
407
+ ```ts
408
+ scan.ocr(input: { pages?: number[] | undefined; fileName?: string | undefined; key?: string | undefined; url?: string | undefined; }): Promise<{ text: string; pages: { markdown: string; width: number; height: number; words?: { text: string; bbox: number[]; }[] | undefined; }[]; fullDetails?: unknown; } & { usage: { vendor?: string | undefined; units?: number | undefined; credits: number; }; }>
409
+ ```
410
+
411
+ The text of a document or image, per page as Markdown.
412
+
413
+ ## `totalum-sdk/speech`
414
+
415
+ ### `totalumSpeech`
416
+
417
+ ```ts
418
+ totalumSpeech(options?: TotalumClientOptions)
419
+ ```
420
+
421
+ `totalum.speech` over `/v1/speech/*` (scope `speech`): OpenRouter speech through Totalum.
422
+
423
+ #### `speech.transcribe`
424
+
425
+ ```ts
426
+ speech.transcribe(input: { audioBase64?: string | undefined; filename?: string | undefined; url?: string | undefined; language?: string | undefined; model?: 'fast' | 'accurate' | undefined; diarize?: boolean | undefined; timestamps?: 'word' | 'segment' | undefined; keyterms?: string[] | undefined; }): Promise<{ text: string; durationSec: number; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; language?: string | undefined; segments?: { start: number; end: number; text: string; }[] | undefined; words?: { word: string; start: number; end: number; }[] | undefined; }>
427
+ ```
428
+
429
+ Speech to text from `audioBase64` or a `url`; optional language, word timestamps and speakers.
430
+
431
+ #### `speech.synthesize`
432
+
433
+ ```ts
434
+ speech.synthesize(input: { text: string; voice?: string | undefined; language?: string | undefined; model?: 'standard' | 'premium' | undefined; format?: 'mp3' | 'wav' | 'opus' | undefined; speed?: number | undefined; store?: boolean | undefined; }): Promise<{ key: string; url: string; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; } | { audio: ArrayBuffer; contentType: string; credits: number; }>
435
+ ```
436
+
437
+ The audio bytes, or with `store: true` the stored file `{key, url, usage}`; `credits` is the call's hold.
438
+
439
+ ## `totalum-sdk/ai`
440
+
441
+ ### `totalumAi`
442
+
443
+ ```ts
444
+ totalumAi(options?: TotalumAiOptions)
445
+ ```
446
+
447
+ `totalum.ai` over SDK-API `/v1/ai/*` (scope `ai`): aliases `cheap|normal|best` or any
448
+ OpenRouter slug, every call priced `usage.cost × 28` and returned with its credits. No `ai.agent()` — the
449
+ agent loop is the template's `src/agents/` on the Vercel AI SDK, pointed at `gatewayConfig()`.
450
+
451
+ #### `ai.chat`
452
+
453
+ ```ts
454
+ ai.chat(req: Omit<{ messages: { [x: string]: unknown; role: 'user' | 'system' | 'assistant' | 'tool' | 'developer'; content: unknown; }[]; model?: string | undefined; tools?: Record<string, unknown>[] | undefined; toolChoice?: unknown; parallelToolCalls?: boolean | undefined; responseFormat?: Record<string, unknown> | undefined; temperature?: number | undefined; maxTokens?: number | undefined; reasoning?: { effort: string; } | undefined; serverTools?: ('web_search' | 'image_generation' | 'web_fetch' | 'datetime')[] | undefined; maxToolCalls?: number | undefined; stream?: boolean | undefined; cache?: { ttlSec: number; } | undefined; zdr?: boolean | undefined; fastMode?: boolean | undefined; user?: string | undefined; }, 'stream'>): Promise<ChatResult>
455
+ ```
456
+
457
+ A chat completion; `model` is an alias (`cheap`, `normal`, `best`) or any OpenRouter slug.
458
+
459
+ ```ts
460
+ const { text } = await ai.chat({ model: 'cheap', messages: [{ role: 'user', content: 'Hi' }] });
461
+ ```
462
+
463
+ #### `ai.chat.stream`
464
+
465
+ ```ts
466
+ ai.chat.stream(req: Omit<{ messages: { [x: string]: unknown; role: 'user' | 'system' | 'assistant' | 'tool' | 'developer'; content: unknown; }[]; model?: string | undefined; tools?: Record<string, unknown>[] | undefined; toolChoice?: unknown; parallelToolCalls?: boolean | undefined; responseFormat?: Record<string, unknown> | undefined; temperature?: number | undefined; maxTokens?: number | undefined; reasoning?: { effort: string; } | undefined; serverTools?: ('web_search' | 'image_generation' | 'web_fetch' | 'datetime')[] | undefined; maxToolCalls?: number | undefined; stream?: boolean | undefined; cache?: { ttlSec: number; } | undefined; zdr?: boolean | undefined; fastMode?: boolean | undefined; user?: string | undefined; }, 'stream'>): Promise<ChatStream>
467
+ ```
468
+
469
+ The same request streamed: `raw` is the OpenAI-format SSE (return it from a route), `text()` its deltas,
470
+ `result()` the final result with its credits.
471
+
472
+ #### `ai.generateObject`
473
+
474
+ ```ts
475
+ ai.generateObject(req: { schema: Record<string, unknown>; prompt?: string | undefined; messages?: { [x: string]: unknown; role: 'user' | 'system' | 'assistant' | 'tool' | 'developer'; content: unknown; }[] | undefined; model?: string | undefined; healing?: boolean | undefined; }): Promise<{ object: unknown; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; }>
476
+ ```
477
+
478
+ A JSON object matching `schema` (JSON Schema).
479
+
480
+ #### `ai.classify`
481
+
482
+ ```ts
483
+ ai.classify(req: { input: string; options: readonly string[]; model?: string | undefined; instructions?: string | undefined; }): Promise<{ label: string; }>
484
+ ```
485
+
486
+ Sugar over `generateObject`: one of `options`, chosen by the model.
487
+
488
+ #### `ai.embed`
489
+
490
+ ```ts
491
+ ai.embed(req: { input: string | string[]; model?: string | undefined; }): Promise<{ embeddings: number[][]; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; }>
492
+ ```
493
+
494
+ Embedding vectors for one or more texts.
495
+
496
+ #### `ai.image.generate`
497
+
498
+ ```ts
499
+ ai.image.generate(req: { prompt: string; model?: string | undefined; aspectRatio?: string | undefined; resolution?: '1K' | '2K' | '4K' | '512' | undefined; quality?: string | undefined; outputFormat?: 'png' | 'jpeg' | 'webp' | undefined; background?: string | undefined; n?: number | undefined; references?: string[] | undefined; fileName?: string | undefined; store?: boolean | undefined; }): Promise<{ images: { key: string; url: string; mediaType: string; width?: number | undefined; height?: number | undefined; }[]; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; fileName?: string | undefined; imageUrl?: string | undefined; }>
500
+ ```
501
+
502
+ Images from a prompt; `store: true` keeps them as project files.
503
+
504
+ #### `ai.image.edit`
505
+
506
+ ```ts
507
+ ai.image.edit(req: { prompt: string; images: string[]; mask?: string | undefined; fileName?: string | undefined; size?: string | undefined; quality?: string | undefined; outputFormat?: 'png' | 'jpeg' | 'webp' | undefined; background?: string | undefined; inputFidelity?: string | undefined; }): Promise<{ images: { key: string; url: string; mediaType: string; width?: number | undefined; height?: number | undefined; }[]; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; fileName?: string | undefined; imageUrl?: string | undefined; }>
508
+ ```
509
+
510
+ An image edited by a prompt.
511
+
512
+ #### `ai.video.generate`
513
+
514
+ ```ts
515
+ ai.video.generate(req: { prompt: string; durationSec: number; model?: string | undefined; resolution?: string | undefined; aspectRatio?: string | undefined; firstFrame?: string | undefined; lastFrame?: string | undefined; references?: string[] | undefined; generateAudio?: boolean | undefined; seed?: number | undefined; webhook?: boolean | undefined; }): Promise<{ jobId: string; status: 'queued'; estimatedCredits: number; }>
516
+ ```
517
+
518
+ `202`: the job and the credits reserved for it; poll `get(jobId)` (the clip is stored when it completes).
519
+
520
+ #### `ai.video.get`
521
+
522
+ ```ts
523
+ ai.video.get(jobId: string): Promise<{ jobId: string; status: 'completed' | 'queued' | 'running' | 'failed' | 'cancelled' | 'expired'; progress?: number | undefined; video?: { key: string; url: string; } | undefined; usage?: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; } | undefined; error?: { code: string; message: string; } | undefined; }>
524
+ ```
525
+
526
+ The video job: `status`, and the stored clip once completed.
527
+
528
+ #### `ai.video.wait`
529
+
530
+ ```ts
531
+ ai.video.wait(jobId: string, opts?: { intervalMs?: number | undefined; timeoutMs?: number | undefined; }): Promise<{ jobId: string; status: 'completed' | 'queued' | 'running' | 'failed' | 'cancelled' | 'expired'; progress?: number | undefined; video?: { key: string; url: string; } | undefined; usage?: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; } | undefined; error?: { code: string; message: string; } | undefined; }>
532
+ ```
533
+
534
+ ⚠ NODE-ONLY: polls `get(jobId)` until the job leaves `queued`/`running` (default every 5 s, at most 10 min).
535
+ In a Worker it throws `NODE_ONLY` — store the `jobId` and read `get(jobId)` later instead.
536
+
537
+ #### `ai.vision.describe`
538
+
539
+ ```ts
540
+ ai.vision.describe(req: { image: string; prompt?: string | undefined; model?: string | undefined; }): Promise<{ text: string; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; }>
541
+ ```
542
+
543
+ A text description of an image (URL, data URL or project file key).
544
+
545
+ #### `ai.speech.speak`
546
+
547
+ ```ts
548
+ ai.speech.speak(input: { text: string; voice?: string | undefined; language?: string | undefined; model?: 'standard' | 'premium' | undefined; format?: 'mp3' | 'wav' | 'opus' | undefined; speed?: number | undefined; store?: boolean | undefined; }): Promise<{ key: string; url: string; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; } | { audio: ArrayBuffer; contentType: string; credits: number; }>
549
+ ```
550
+
551
+ Same as `speech.synthesize`.
552
+
553
+ #### `ai.speech.transcribe`
554
+
555
+ ```ts
556
+ ai.speech.transcribe(input: { audioBase64?: string | undefined; filename?: string | undefined; url?: string | undefined; language?: string | undefined; model?: 'fast' | 'accurate' | undefined; diarize?: boolean | undefined; timestamps?: 'word' | 'segment' | undefined; keyterms?: string[] | undefined; }): Promise<{ text: string; durationSec: number; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; language?: string | undefined; segments?: { start: number; end: number; text: string; }[] | undefined; words?: { word: string; start: number; end: number; }[] | undefined; }>
557
+ ```
558
+
559
+ Same as `speech.transcribe`.
560
+
561
+ #### `ai.models.list`
562
+
563
+ ```ts
564
+ ai.models.list(): Promise<{ aliases: { cheap: string; normal: string; best: string; }; models: { slug: string; name: string; inputModalities: string[]; pricing: Record<string, unknown>; contextLength: number; }[]; denylist?: string[] | undefined; }>
565
+ ```
566
+
567
+ The model aliases and the models a project may call, with their prices.
568
+
569
+ #### `ai.gatewayConfig`
570
+
571
+ ```ts
572
+ ai.gatewayConfig(): { baseURL: string; apiKey: string; }
573
+ ```
574
+
575
+ The exact OpenRouter API for any OpenRouter/OpenAI client: `new OpenAI(ai.gatewayConfig())`. Server-side only.
576
+
577
+ ## `totalum-sdk/email`
578
+
579
+ ### `totalumEmail`
580
+
581
+ ```ts
582
+ totalumEmail(options?: TotalumClientOptions)
583
+ ```
584
+
585
+ `totalum.email` over SDK-API `/v1/email/*` (scope `email`): Resend, HTML sent byte for byte, charged
586
+ per recipient. On dev only allow-listed recipients are accepted (`DEV_RECIPIENT_NOT_ALLOWED`).
587
+
588
+ #### `email.send`
589
+
590
+ ```ts
591
+ email.send(msg: { to: string | string[]; subject: string; html?: string | undefined; text?: string | undefined; from?: { name?: string | undefined; localPart?: string | undefined; domain?: string | undefined; } | undefined; replyTo?: string | string[] | undefined; cc?: string | string[] | undefined; bcc?: string | string[] | undefined; headers?: Record<string, string> | undefined; attachments?: { filename: string; url?: string | undefined; content?: string | undefined; contentType?: string | undefined; }[] | undefined; tags?: { name: string; value: string; }[] | undefined; scheduledAt?: string | undefined; idempotencyKey?: string | undefined; bulk?: boolean | undefined; }): Promise<{ success: true; message: 'Email sent successfully'; messageId: string; id: string; status: 'queued' | 'sent'; }>
592
+ ```
593
+
594
+ Sends one e-mail (HTML byte for byte); charged per recipient.
595
+
596
+ ```ts
597
+ await email.send({ to: 'ana@example.com', subject: 'Welcome', html: '<p>Hi Ana</p>' });
598
+ ```
599
+
600
+ #### `email.get`
601
+
602
+ ```ts
603
+ email.get(id: string): Promise<{ id: string; from: string; to: string[]; subject: string; status: 'queued' | 'failed' | 'sent' | 'delivered' | 'delayed' | 'bounced' | 'complained' | 'suppressed'; lastEventAt: string | null; events: { type: string; at: string; detail?: unknown; }[]; } | null>
604
+ ```
605
+
606
+ `null` when the e-mail is not this project's.
607
+
608
+ ## `totalum-sdk/cron`
609
+
610
+ ### `totalumCron`
611
+
612
+ ```ts
613
+ totalumCron(options?: TotalumClientOptions)
614
+ ```
615
+
616
+ `totalum.cron` over SDK-API `/v1/cron/*` (scope `cron`): HTTP jobs against the project's own host,
617
+ fired by Totalum's Scheduler; limits per plan (`429 CRON_LIMIT_REACHED {limit, plan}`, `400 INVALID_SCHEDULE
618
+ {minIntervalSeconds}`). Executions cost nothing.
619
+
620
+ #### `cron.create`
621
+
622
+ ```ts
623
+ cron.create(input: { name: string; schedule: string | { everyMinutes: number; }; request: { method: 'GET' | 'POST'; url: string; headers?: Record<string, string> | undefined; body?: string | undefined; timeoutMs?: number | undefined; }; enabled?: boolean | undefined; description?: string | undefined; env?: 'dev' | 'live' | undefined; }): Promise<{ id: string; name: string; schedule: string | { everyMinutes: number; }; request: { method: 'GET' | 'POST'; url: string; headers?: Record<string, string> | undefined; body?: string | undefined; timeoutMs?: number | undefined; }; enabled: boolean; status: 'active' | 'paused' | 'paused_failures'; nextRunAt: string | null; createdAt: string; env: 'dev' | 'live'; lastRun?: { at: string; status: number | 'timeout' | 'error' | 'skipped'; latencyMs: number; } | undefined; description?: string | undefined; }>
624
+ ```
625
+
626
+ A job that calls a URL of the project's own host on a cron `schedule` (or `{ everyMinutes }`).
627
+
628
+ ```ts
629
+ await cron.create({
630
+ name: 'daily-report',
631
+ schedule: '0 8 * * *',
632
+ request: { method: 'POST', url: 'https://my-app.totalum-project.com/api/cron/report' },
633
+ });
634
+ ```
635
+
636
+ #### `cron.list`
637
+
638
+ ```ts
639
+ cron.list(): Promise<{ id: string; name: string; schedule: string | { everyMinutes: number; }; request: { method: 'GET' | 'POST'; url: string; headers?: Record<string, string> | undefined; body?: string | undefined; timeoutMs?: number | undefined; }; enabled: boolean; status: 'active' | 'paused' | 'paused_failures'; nextRunAt: string | null; createdAt: string; env: 'dev' | 'live'; lastRun?: { at: string; status: number | 'timeout' | 'error' | 'skipped'; latencyMs: number; } | undefined; description?: string | undefined; }[]>
640
+ ```
641
+
642
+ Every job of the project.
643
+
644
+ #### `cron.get`
645
+
646
+ ```ts
647
+ cron.get(id: string): Promise<{ id: string; name: string; schedule: string | { everyMinutes: number; }; request: { method: 'GET' | 'POST'; url: string; headers?: Record<string, string> | undefined; body?: string | undefined; timeoutMs?: number | undefined; }; enabled: boolean; status: 'active' | 'paused' | 'paused_failures'; nextRunAt: string | null; createdAt: string; env: 'dev' | 'live'; lastRun?: { at: string; status: number | 'timeout' | 'error' | 'skipped'; latencyMs: number; } | undefined; description?: string | undefined; } | null>
648
+ ```
649
+
650
+ `null` when the job is not this project's.
651
+
652
+ #### `cron.update`
653
+
654
+ ```ts
655
+ cron.update(id: string, patch: { name?: string | undefined; schedule?: string | { everyMinutes: number; } | undefined; request?: { method: 'GET' | 'POST'; url: string; headers?: Record<string, string> | undefined; body?: string | undefined; timeoutMs?: number | undefined; } | undefined; enabled?: boolean | undefined; description?: string | undefined; env?: 'dev' | 'live' | undefined; }): Promise<{ id: string; name: string; schedule: string | { everyMinutes: number; }; request: { method: 'GET' | 'POST'; url: string; headers?: Record<string, string> | undefined; body?: string | undefined; timeoutMs?: number | undefined; }; enabled: boolean; status: 'active' | 'paused' | 'paused_failures'; nextRunAt: string | null; createdAt: string; env: 'dev' | 'live'; lastRun?: { at: string; status: number | 'timeout' | 'error' | 'skipped'; latencyMs: number; } | undefined; description?: string | undefined; }>
656
+ ```
657
+
658
+ Changes any field of a job (`schedule`, `request`, `enabled`, …).
659
+
660
+ #### `cron.delete`
661
+
662
+ ```ts
663
+ cron.delete(id: string): Promise<void>
664
+ ```
665
+
666
+ Deletes a job.
667
+
668
+ #### `cron.pause`
669
+
670
+ ```ts
671
+ cron.pause(id: string): Promise<{ id: string; name: string; schedule: string | { everyMinutes: number; }; request: { method: 'GET' | 'POST'; url: string; headers?: Record<string, string> | undefined; body?: string | undefined; timeoutMs?: number | undefined; }; enabled: boolean; status: 'active' | 'paused' | 'paused_failures'; nextRunAt: string | null; createdAt: string; env: 'dev' | 'live'; lastRun?: { at: string; status: number | 'timeout' | 'error' | 'skipped'; latencyMs: number; } | undefined; description?: string | undefined; }>
672
+ ```
673
+
674
+ Stops a job from firing until `resume`.
675
+
676
+ #### `cron.resume`
677
+
678
+ ```ts
679
+ cron.resume(id: string): Promise<{ id: string; name: string; schedule: string | { everyMinutes: number; }; request: { method: 'GET' | 'POST'; url: string; headers?: Record<string, string> | undefined; body?: string | undefined; timeoutMs?: number | undefined; }; enabled: boolean; status: 'active' | 'paused' | 'paused_failures'; nextRunAt: string | null; createdAt: string; env: 'dev' | 'live'; lastRun?: { at: string; status: number | 'timeout' | 'error' | 'skipped'; latencyMs: number; } | undefined; description?: string | undefined; }>
680
+ ```
681
+
682
+ Lets a paused job fire again.
683
+
684
+ #### `cron.runs`
685
+
686
+ ```ts
687
+ cron.runs(id: string, opts?: { limit?: number | undefined; cursor?: string | undefined; }): Promise<{ items: { id: string; scheduledFor: string; startedAt: string | null; status: number | 'timeout' | 'error' | 'skipped'; latencyMs: number | null; error?: string | undefined; responseSnippet?: string | undefined; }[]; nextCursor: string | null; }>
688
+ ```
689
+
690
+ A job's executions, newest first (30 days).
691
+
692
+ #### `cron.trigger`
693
+
694
+ ```ts
695
+ cron.trigger(id: string): Promise<{ runId: string; }>
696
+ ```
697
+
698
+ Fires a job now, outside its schedule.
699
+
700
+ ## `totalum-sdk/seo`
701
+
702
+ ### `totalumSeo`
703
+
704
+ ```ts
705
+ totalumSeo(options?: TotalumClientOptions)
706
+ ```
707
+
708
+ `totalum.seo` over SDK-API `/v1/seo/*` (scope `seo`): IndexNow for verified custom domains, free.
709
+
710
+ #### `seo.notifyChanged`
711
+
712
+ ```ts
713
+ seo.notifyChanged(urls: string[]): Promise<{ accepted: number; indexNow: 'error' | 'sent' | 'skipped_no_custom_domain'; sitemapsPinged: boolean; }>
714
+ ```
715
+
716
+ Tells search engines (IndexNow) that these URLs of the project's custom domains changed.
717
+
718
+ #### `seo.indexNowKey`
719
+
720
+ ```ts
721
+ seo.indexNowKey(): Promise<{ key: string; keyLocation: string; }>
722
+ ```
723
+
724
+ The key the template serves at `/<key>.txt`.
725
+
726
+ ## `totalum-sdk/browser`
727
+
728
+ ### `totalumBrowser`
729
+
730
+ ```ts
731
+ totalumBrowser(options?: TotalumClientOptions)
732
+ ```
733
+
734
+ `totalum.browser` over SDK-API `/v1/browser/*` (scope `browser`): Browserbase sessions driven entirely
735
+ over HTTPS, so every command works from a Worker. A command's refusal throws `TotalumError` with its frozen
736
+ code (`ACTION_TIMEOUT`, `ACTION_FAILED`, …); `actions()` returns every result instead.
737
+
738
+ #### `browser.session`
739
+
740
+ ```ts
741
+ browser.session(opts?: { proxy?: { enabled: boolean; country?: string | undefined; state?: string | undefined; city?: string | undefined; routes?: { domainPattern: string; mode: 'totalum' | 'none' | 'external'; country?: string | undefined; state?: string | undefined; city?: string | undefined; server?: string | undefined; username?: string | undefined; password?: string | undefined; }[] | undefined; } | undefined; solveCaptchas?: boolean | undefined; captcha?: { imageSelector?: string | undefined; inputSelector?: string | undefined; } | undefined; stealth?: 'basic' | 'off' | 'verified' | undefined; fingerprintOs?: 'mobile' | 'windows' | 'mac' | 'linux' | 'tablet' | undefined; timeoutMinutes?: number | undefined; keepAlive?: boolean | undefined; context?: { id: string; persist?: boolean | undefined; } | undefined; contextId?: string | undefined; blockAds?: boolean | undefined; allowedDomains?: string[] | undefined; ignoreCertificateErrors?: boolean | undefined; caCertificateIds?: string[] | undefined; extensionId?: string | undefined; metadata?: Record<string, string> | undefined; logSession?: boolean | undefined; recordSession?: boolean | undefined; region?: 'eu' | 'us-west-2' | 'us-east-1' | 'eu-central-1' | 'ap-southeast-1' | 'us' | undefined; locale?: string | undefined; timezone?: string | undefined; geolocation?: { latitude: number; longitude: number; accuracy?: number | undefined; } | undefined; userAgent?: string | undefined; extraHeaders?: Record<string, string> | undefined; blockResources?: ('image' | 'media' | 'font')[] | undefined; device?: string | undefined; captureDownloads?: boolean | undefined; viewport?: { width: number; height: number; } | undefined; }): Promise<BrowserSession>
742
+ ```
743
+
744
+ Opens a session with the vendor options and the Totalum-synthesised ones.
745
+
746
+ #### `browser.sessions.list`
747
+
748
+ ```ts
749
+ browser.sessions.list(q?: { status?: string | undefined; metadata?: string | undefined; limit?: number | undefined; cursor?: string | undefined; }): Promise<{ items: ({ id: string; status: 'running' | 'failed' | 'expired' | 'ended'; startedAt: string; minutes: number; proxyMb: number; captchas: number; credits: number; expiresAt: string; } & { region: string; metadata: Record<string, string> | null; })[]; nextCursor?: string | undefined; }>
750
+ ```
751
+
752
+ The project's sessions, filtered by `status` or `metadata`.
753
+
754
+ #### `browser.sessions.get`
755
+
756
+ ```ts
757
+ browser.sessions.get(id: string): BrowserSession
758
+ ```
759
+
760
+ A handle on an existing session (no call is made).
761
+
762
+ #### `browser.programs.get`
763
+
764
+ ```ts
765
+ browser.programs.get(programId: string): Promise<{ programId: string; sessionId: string; status: 'completed' | 'running' | 'failed' | 'pending' | 'timed_out'; steps: { index: number; type: string; ok: boolean; data?: unknown; error?: { code: 'SERVICE_UNAUTHORIZED' | 'SERVICE_REPLAY' | 'ACTOR_MISMATCH' | 'PAYLOAD_TOO_LARGE' | 'VALIDATION_ERROR' | 'PROJECT_NOT_FOUND' | 'OPERATION_IN_PROGRESS' | 'AGENT_RUNNING' | 'PROJECT_MOVED' | 'OBJECT_MIGRATING' | 'INDEX_SHARD_UNAVAILABLE' | 'RATE_LIMIT_EXCEEDED' | 'PROJECT_PAUSED_RUNAWAY' | 'PROJECT_PAUSED_BALANCE' | 'PROJECT_SUSPENDED' | 'PROJECT_HIBERNATED' | 'PROJECT_DELETED' | 'PROJECT_PAUSED_BY_USER' | 'LIFECYCLE_NOT_APPLICABLE' | 'PROJECT_NOT_PAUSED' | 'PAUSE_DUMP_EXPIRED' | 'PAUSE_VERIFICATION_FAILED' | 'DEPLOYMENT_IN_PROGRESS' | 'REACTIVATE_IMPORT_MISMATCH' | 'RESUME_IMPORT_MISMATCH' | 'INSUFFICIENT_CREDITS' | 'VCAAS_INSUFFICIENT_CREDITS' | 'PROJECT_CREDIT_LIMIT_REACHED' | 'FREE_PROMPTS_DISABLED' | 'PLAN_REQUIRED' | 'FEATURE_LIMIT_REACHED' | 'FEATURE_DISABLED' | 'AGENT_ALREADY_RUNNING' | 'IMPORT_IN_PROGRESS' | 'TOO_MANY_RUN_REQUESTS' | 'PROMPT_SECURITY_VIOLATION' | 'NO_PROCESS_RUNNING' | 'RUN_NOT_FOUND' | 'DEPLOYMENT_RUNNING' | 'ENGINE_NOT_SUPPORTED' | 'ENGINE_V2_DISABLED' | 'ENGINE_REQUEST_NOT_ELIGIBLE' | 'ENGINE_MISMATCH' | 'INVALID_ENGINE_VERSION' | 'PROJECT_ENGINE_MISMATCH' | 'ENGINE_UNAVAILABLE' | 'PREVIEW_LABEL_TOO_LONG' | 'PROJECT_ALREADY_EXISTS' | 'CLOUDFLARE_API_ERROR' | 'PROVISIONING_BUSY' | 'UNAUTHORIZED' | 'LEGACY_KEY_NOT_SUPPORTED' | 'SANDBOX_KEY_EXPIRED' | 'AUTH_RATE_LIMITED' | 'FORBIDDEN_SCOPE' | 'KEY_ENV_MISMATCH' | 'KEY_LIMIT_EXCEEDED' | 'LIVE_DB_READ_ONLY' | 'DDL_NOT_ALLOWED' | 'MIGRATION_IN_PROGRESS' | 'MIGRATION_EDITED' | 'SCHEMA_OUT_OF_SYNC' | 'LIVE_MIGRATION_FAILED' | 'DESTRUCTIVE_MIGRATION_NEEDS_CONFIRMATION' | 'DEV_DATABASE_NOT_FOUND' | 'DATABASE_ROLE_NOT_FOUND' | 'SQL_ERROR' | 'SQL_MULTI_STATEMENT' | 'SQL_STATEMENT_TOO_LARGE' | 'SQL_TOO_MANY_PARAMS' | 'STATEMENT_NOT_ALLOWED' | 'VIRTUAL_TABLES_NOT_SUPPORTED' | 'USE_STORAGE_FOR_FILES' | 'D1_TYPE_ERROR' | 'MIGRATION_INVALID' | 'SYSTEM_TABLE_READ_ONLY' | 'SQL_READ_ONLY' | 'RESULT_TOO_LARGE' | 'QUERY_TIMEOUT' | 'DB_OVERLOADED' | 'D1_TRANSIENT' | 'DB_FULL_NEAR_LIMIT' | 'IDEMPOTENCY_KEY_REUSED' | 'IDEMPOTENT_REPLAY_UNAVAILABLE' | 'TABLE_NOT_FOUND' | 'SCHEMA_TOO_LARGE_FOR_COUNTS' | 'EXEC_REQUIRES_MIGRATE_MODE' | 'MIGRATION_UNKNOWN_IN_DB' | 'QUERY_LIMIT_EXCEEDED' | 'STORAGE_LIMIT_EXCEEDED' | 'METER_UNAVAILABLE' | 'COLUMN_NOT_FOUND' | 'VALUE_NOT_ALLOWED' | 'COLUMN_REQUIRED' | 'FILTER_TOO_COMPLEX' | 'OFFSET_TOO_LARGE' | 'BULK_TOO_LARGE' | 'NOT_A_JUNCTION_TABLE' | 'AMBIGUOUS_RELATION' | 'LIVE_WRITE_CONFIRMATION_REQUIRED' | 'RECORD_NOT_FOUND' | 'DEV_NAME_GUARD' | 'PROD_NAME_GUARD' | 'INVALID_RUN_REQUEST' | 'RUN_ALREADY_ACTIVE' | 'RUN_CONFLICT' | 'INVALID_CREDENTIALS' | 'ADAPTER_UNAVAILABLE' | 'DISK_FULL' | 'DEPLOY_FIX_ATTEMPTS_EXHAUSTED' | 'TOKEN_REVOKED' | 'AM_UPDATE_DOWNLOAD_FAILED' | 'AM_UPDATE_BAD_SHA' | 'AM_UPDATE_BAD_SIGNATURE' | 'AM_UPDATE_INCOMPATIBLE_IMAGE' | 'AM_UPDATE_START_FAILED' | 'AM_VERSION_UNAVAILABLE' | 'AM_UPDATE_FAILED' | 'RELEASE_CANARY_NOT_PASSED' | 'RELEASE_NOT_FOUND' | 'VISUAL_EDIT_PREVIEW_DEPLOYING' | 'VISUAL_EDIT_NOT_PATCHABLE' | 'VISUAL_EDIT_BASE_MISMATCH' | 'VISUAL_EDIT_TYPECHECK_FAILED' | 'INVALID_VISUAL_EDIT' | 'IMAGE_VERSION_NOT_FOUND' | 'IMAGE_VERSION_NOT_PROMOTABLE' | 'REALTIME_TICKET_INVALID' | 'REALTIME_TICKET_EXPIRED' | 'REALTIME_PERMISSION_DENIED' | 'REALTIME_MESSAGE_TOO_LARGE' | 'REALTIME_MESSAGE_RATE_EXCEEDED' | 'REALTIME_CONNECTION_LIMIT_REACHED' | 'REALTIME_ROOM_LIMIT_REACHED' | 'CONFIRMATION_REQUIRED' | 'MIGRATION_NOT_REVERSIBLE' | 'ALREADY_ON_PROVIDER' | 'DATABASE_MIGRATING' | 'LOGWATCH_INACTIVE' | 'AGENT_LOG_READS_LIMIT' | 'LOGS_UPSTREAM_ERROR' | 'ANALYTICS_INVALID_QUERY' | 'ANALYTICS_UPSTREAM_ERROR' | 'ANALYTICS_WINDOW_OUT_OF_RETENTION' | 'INVALID_CIDR' | 'RATE_LIMIT_ABOVE_PLAN' | 'RATE_LIMIT_DISABLE_NOT_ALLOWED' | 'OWNER_ONLY' | 'SIGNING_NOT_CONFIGURED' | 'SIGNING_ALREADY_CONFIGURED' | 'SIGNING_INVALID_KEYSTORE' | 'SIGNING_INVALID_ASC_KEY' | 'KEYSTORE_DOWNLOAD_EXPIRED' | 'KEYSTORE_NOT_DOWNLOADABLE' | 'MOBILE_BUILD_RUNNING' | 'MOBILE_BUILD_NOT_FOUND' | 'MOBILE_BUILD_NOT_READY' | 'DOWNLOAD_EXPIRED' | 'PROCESS_IN_PROGRESS' | 'SANDBOX_NOT_RUNNING' | 'MOBILE_LAYER_MISSING' | 'MOBILE_BUILD_FAILED' | 'MOBILE_ARTIFACT_INVALID' | 'SIGNING_FINGERPRINT_MISMATCH' | 'AM_RESTARTED' | 'LIMIT_ABOVE_PLAN_CEILING' | 'UNKNOWN_FEATURE' | 'INVALID_LIMIT' | 'FEATURE_NOT_DISABLABLE' | 'USE_PUT_LIMITS' | 'LIMIT_NOT_USER_EDITABLE' | 'NOT_AVAILABLE_FOR_ENGINE' | 'INVALID_AMOUNT' | 'REFUND_EXCEEDS_CHARGES' | 'IDEMPOTENCY_CONFLICT' | 'ORGANIZATION_NOT_FOUND' | 'ACCOUNT_NOT_FOUND' | 'PROVIDER_UNAVAILABLE' | 'URL_NOT_ALLOWED' | 'JOB_NOT_FOUND' | 'FILE_TOO_LARGE' | 'UNSUPPORTED_FILE_TYPE' | 'FILE_NOT_FOUND' | 'FILE_KEY_FORBIDDEN' | 'FILE_UPLOAD_ERROR' | 'FILE_DOWNLOAD_ERROR' | 'FILE_DELETE_ERROR' | 'UPLOAD_NOT_COMPLETED' | 'MISSING_URL' | 'MISSING_INPUT' | 'MISSING_EXTRACTION_CONFIG' | 'MISSING_QUERY' | 'SCRAPE_FAILED' | 'EXTRACT_FAILED' | 'SCREENSHOT_FAILED' | 'SEARCH_FAILED' | 'SCRAPE_BLOCKED' | 'SESSION_NOT_FOUND' | 'SESSION_EXPIRED' | 'SESSION_BUSY' | 'SESSION_LIMIT_REACHED' | 'SESSION_ENDED_INSUFFICIENT_CREDITS' | 'ACTION_TIMEOUT' | 'ACTION_FAILED' | 'UNKNOWN_COMMAND' | 'BATCH_TOO_LARGE' | 'SKIPPED' | 'UPLOAD_TOO_LARGE' | 'DOWNLOAD_TOO_LARGE' | 'CAPTURE_LIMIT_REACHED' | 'CAPTCHA_UNSOLVED' | 'BROWSER_CDP_NODE_ONLY' | 'DIALOG_NOT_OPEN' | 'STEALTH_TIER_UNAVAILABLE' | 'DOMAIN_NOT_ALLOWED' | 'CONTEXT_SEED_UNSUPPORTED' | 'EXTENSION_TOO_LARGE' | 'NL_PROVIDER_UNAVAILABLE' | 'PROGRAM_TOO_LARGE' | 'PROGRAM_UNBOUNDED' | 'UNKNOWN_STEP' | 'PROGRAM_IN_FLIGHT' | 'PROGRAM_TIMEOUT' | 'PROGRAM_NOT_FOUND' | 'PROGRAM_STEP_FAILED' | 'PROGRAM_LIMIT_REACHED' | 'CREATE_PDF_FROM_HTML_ERROR' | 'GENERATE_PDF_BY_URL_ERROR' | 'PDF_TIMEOUT' | 'PDF_TOO_LARGE' | 'FILENAME_REQUIRED' | 'SCANUM_EYE_ARRAY_NOT_SUPPORTED' | 'INVALID_EXTRA_FIELD_TYPE' | 'SCANUM_EYE_PDF_NOT_SUPPORTED' | 'UNSUPPORTED_SCAN_MODEL' | 'SCAN_DOCUMENT_ERROR' | 'SCAN_INVOICE_ERROR' | 'OCR_IMAGE_PROCESSING_ERROR' | 'OCR_PDF_PROCESSING_ERROR' | 'SCAN_TOO_MANY_PAGES' | 'SCAN_PDF_ENCRYPTED' | 'SCAN_XFA_UNSUPPORTED' | 'AUDIO_FILE_REQUIRED' | 'AUDIO_FILE_TOO_LARGE' | 'INVALID_AUDIO_FORMAT' | 'AUDIO_TRANSCRIPTION_ERROR' | 'TTS_TEXT_TOO_LONG' | 'TTS_VOICE_UNKNOWN' | 'TOO_MANY_AUDIO_TRANSCRIPTIONS' | 'EMAIL_SEND_FAILED' | 'TOO_MANY_ATTACHMENTS' | 'INVALID_ATTACHMENT_URL' | 'ATTACHMENT_TOO_LARGE' | 'TOO_MANY_RECIPIENTS' | 'EMAIL_RECIPIENT_SUPPRESSED' | 'EMAIL_DOMAIN_NOT_VERIFIED' | 'EMAIL_LOCAL_PART_TAKEN' | 'EMAIL_SENDING_PAUSED' | 'EMAIL_DOMAINS_REQUIRE_PAID_PLAN' | 'SUPPRESSION_PERMANENT' | 'DEV_RECIPIENT_NOT_ALLOWED' | 'CRON_LIMIT_REACHED' | 'INVALID_SCHEDULE' | 'CRON_URL_NOT_ALLOWED' | 'CRON_JOB_NOT_FOUND' | 'CRON_REQUIRES_PUBLISHED_PROJECT' | 'URL_NOT_PROJECT_HOST' | 'INDEXNOW_ERROR' | 'MCP_VERIFY_FAILED' | 'MCP_NAME_RESERVED' | 'MCP_LIMIT_REACHED' | 'MCP_SERVER_NOT_FOUND' | 'PAYMENTS_NOT_ENABLED' | 'PAYMENTS_LIVE_ONBOARDING_REQUIRED' | 'CARD_DATA_NOT_ACCEPTED' | 'STRIPE_ERROR' | 'STRIPE_RATE_LIMITED' | 'PAYMENTS_WEBHOOK_SIGNATURE_INVALID' | 'AI_MODEL_NOT_ALLOWED' | 'AI_MODEL_UNKNOWN' | 'AI_INVALID_SCHEMA' | 'AI_CONTENT_BLOCKED' | 'AI_CONTEXT_TOO_LONG' | 'AI_PROVIDER_QUOTA' | 'AI_PROVIDER_UNAVAILABLE' | 'AI_STREAM_ERROR' | 'AI_VIDEO_JOB_NOT_FOUND' | 'AI_VIDEO_FAILED' | 'MISSING_VIDEO_URL' | 'MISSING_PROMPT' | 'INVALID_VIDEO_URL' | 'INVALID_VIDEO_URL_PROTOCOL' | 'INVALID_MIME_TYPE_HINT' | 'VIDEO_TOO_LARGE' | 'VIDEO_URL_UNREACHABLE' | 'VIDEO_URL_NOT_A_VIDEO' | 'YOUTUBE_VIDEO_UNAVAILABLE' | 'NO_PAYMENT_METHOD' | 'DOMAIN_CONTACT_REQUIRED' | 'DOMAIN_UNAVAILABLE' | 'DOMAIN_PREMIUM_NOT_ALLOWED' | 'TLD_NOT_ALLOWED' | 'DOMAIN_LIMIT_REACHED' | 'PRICE_CHANGED' | 'PAYMENT_FAILED' | 'REGISTRATION_FAILED' | 'DOMAIN_NOT_RENEWABLE' | 'DOMAIN_ALREADY_ATTACHED' | 'DNS_RECORD_MANAGED' | 'DNS_RECORD_CONFLICT' | 'DNS_RECORD_LIMIT' | 'DOMAIN_TRANSFER_LOCKED' | 'DOMAIN_NOT_FOUND' | 'DOMAIN_IN_USE' | 'DOMAIN_ALREADY_ADDED' | 'NO_DEPLOYMENT' | 'REDIRECT_LIMIT_REACHED' | 'REDIRECT_INVALID' | 'APEX_NOT_FLATTENABLE'; message?: string | undefined; } | undefined; }[]; vars: Record<string, unknown>; startedAt: string; credits: number; result?: unknown; endedAt?: string | undefined; }>
766
+ ```
767
+
768
+ A program's status and, once finished, its results.
769
+
770
+ #### `browser.programs.wait`
771
+
772
+ ```ts
773
+ browser.programs.wait(programId: string, opts?: { intervalMs?: number | undefined; timeoutMs?: number | undefined; }): Promise<{ programId: string; sessionId: string; status: 'completed' | 'running' | 'failed' | 'pending' | 'timed_out'; steps: { index: number; type: string; ok: boolean; data?: unknown; error?: { code: 'SERVICE_UNAUTHORIZED' | 'SERVICE_REPLAY' | 'ACTOR_MISMATCH' | 'PAYLOAD_TOO_LARGE' | 'VALIDATION_ERROR' | 'PROJECT_NOT_FOUND' | 'OPERATION_IN_PROGRESS' | 'AGENT_RUNNING' | 'PROJECT_MOVED' | 'OBJECT_MIGRATING' | 'INDEX_SHARD_UNAVAILABLE' | 'RATE_LIMIT_EXCEEDED' | 'PROJECT_PAUSED_RUNAWAY' | 'PROJECT_PAUSED_BALANCE' | 'PROJECT_SUSPENDED' | 'PROJECT_HIBERNATED' | 'PROJECT_DELETED' | 'PROJECT_PAUSED_BY_USER' | 'LIFECYCLE_NOT_APPLICABLE' | 'PROJECT_NOT_PAUSED' | 'PAUSE_DUMP_EXPIRED' | 'PAUSE_VERIFICATION_FAILED' | 'DEPLOYMENT_IN_PROGRESS' | 'REACTIVATE_IMPORT_MISMATCH' | 'RESUME_IMPORT_MISMATCH' | 'INSUFFICIENT_CREDITS' | 'VCAAS_INSUFFICIENT_CREDITS' | 'PROJECT_CREDIT_LIMIT_REACHED' | 'FREE_PROMPTS_DISABLED' | 'PLAN_REQUIRED' | 'FEATURE_LIMIT_REACHED' | 'FEATURE_DISABLED' | 'AGENT_ALREADY_RUNNING' | 'IMPORT_IN_PROGRESS' | 'TOO_MANY_RUN_REQUESTS' | 'PROMPT_SECURITY_VIOLATION' | 'NO_PROCESS_RUNNING' | 'RUN_NOT_FOUND' | 'DEPLOYMENT_RUNNING' | 'ENGINE_NOT_SUPPORTED' | 'ENGINE_V2_DISABLED' | 'ENGINE_REQUEST_NOT_ELIGIBLE' | 'ENGINE_MISMATCH' | 'INVALID_ENGINE_VERSION' | 'PROJECT_ENGINE_MISMATCH' | 'ENGINE_UNAVAILABLE' | 'PREVIEW_LABEL_TOO_LONG' | 'PROJECT_ALREADY_EXISTS' | 'CLOUDFLARE_API_ERROR' | 'PROVISIONING_BUSY' | 'UNAUTHORIZED' | 'LEGACY_KEY_NOT_SUPPORTED' | 'SANDBOX_KEY_EXPIRED' | 'AUTH_RATE_LIMITED' | 'FORBIDDEN_SCOPE' | 'KEY_ENV_MISMATCH' | 'KEY_LIMIT_EXCEEDED' | 'LIVE_DB_READ_ONLY' | 'DDL_NOT_ALLOWED' | 'MIGRATION_IN_PROGRESS' | 'MIGRATION_EDITED' | 'SCHEMA_OUT_OF_SYNC' | 'LIVE_MIGRATION_FAILED' | 'DESTRUCTIVE_MIGRATION_NEEDS_CONFIRMATION' | 'DEV_DATABASE_NOT_FOUND' | 'DATABASE_ROLE_NOT_FOUND' | 'SQL_ERROR' | 'SQL_MULTI_STATEMENT' | 'SQL_STATEMENT_TOO_LARGE' | 'SQL_TOO_MANY_PARAMS' | 'STATEMENT_NOT_ALLOWED' | 'VIRTUAL_TABLES_NOT_SUPPORTED' | 'USE_STORAGE_FOR_FILES' | 'D1_TYPE_ERROR' | 'MIGRATION_INVALID' | 'SYSTEM_TABLE_READ_ONLY' | 'SQL_READ_ONLY' | 'RESULT_TOO_LARGE' | 'QUERY_TIMEOUT' | 'DB_OVERLOADED' | 'D1_TRANSIENT' | 'DB_FULL_NEAR_LIMIT' | 'IDEMPOTENCY_KEY_REUSED' | 'IDEMPOTENT_REPLAY_UNAVAILABLE' | 'TABLE_NOT_FOUND' | 'SCHEMA_TOO_LARGE_FOR_COUNTS' | 'EXEC_REQUIRES_MIGRATE_MODE' | 'MIGRATION_UNKNOWN_IN_DB' | 'QUERY_LIMIT_EXCEEDED' | 'STORAGE_LIMIT_EXCEEDED' | 'METER_UNAVAILABLE' | 'COLUMN_NOT_FOUND' | 'VALUE_NOT_ALLOWED' | 'COLUMN_REQUIRED' | 'FILTER_TOO_COMPLEX' | 'OFFSET_TOO_LARGE' | 'BULK_TOO_LARGE' | 'NOT_A_JUNCTION_TABLE' | 'AMBIGUOUS_RELATION' | 'LIVE_WRITE_CONFIRMATION_REQUIRED' | 'RECORD_NOT_FOUND' | 'DEV_NAME_GUARD' | 'PROD_NAME_GUARD' | 'INVALID_RUN_REQUEST' | 'RUN_ALREADY_ACTIVE' | 'RUN_CONFLICT' | 'INVALID_CREDENTIALS' | 'ADAPTER_UNAVAILABLE' | 'DISK_FULL' | 'DEPLOY_FIX_ATTEMPTS_EXHAUSTED' | 'TOKEN_REVOKED' | 'AM_UPDATE_DOWNLOAD_FAILED' | 'AM_UPDATE_BAD_SHA' | 'AM_UPDATE_BAD_SIGNATURE' | 'AM_UPDATE_INCOMPATIBLE_IMAGE' | 'AM_UPDATE_START_FAILED' | 'AM_VERSION_UNAVAILABLE' | 'AM_UPDATE_FAILED' | 'RELEASE_CANARY_NOT_PASSED' | 'RELEASE_NOT_FOUND' | 'VISUAL_EDIT_PREVIEW_DEPLOYING' | 'VISUAL_EDIT_NOT_PATCHABLE' | 'VISUAL_EDIT_BASE_MISMATCH' | 'VISUAL_EDIT_TYPECHECK_FAILED' | 'INVALID_VISUAL_EDIT' | 'IMAGE_VERSION_NOT_FOUND' | 'IMAGE_VERSION_NOT_PROMOTABLE' | 'REALTIME_TICKET_INVALID' | 'REALTIME_TICKET_EXPIRED' | 'REALTIME_PERMISSION_DENIED' | 'REALTIME_MESSAGE_TOO_LARGE' | 'REALTIME_MESSAGE_RATE_EXCEEDED' | 'REALTIME_CONNECTION_LIMIT_REACHED' | 'REALTIME_ROOM_LIMIT_REACHED' | 'CONFIRMATION_REQUIRED' | 'MIGRATION_NOT_REVERSIBLE' | 'ALREADY_ON_PROVIDER' | 'DATABASE_MIGRATING' | 'LOGWATCH_INACTIVE' | 'AGENT_LOG_READS_LIMIT' | 'LOGS_UPSTREAM_ERROR' | 'ANALYTICS_INVALID_QUERY' | 'ANALYTICS_UPSTREAM_ERROR' | 'ANALYTICS_WINDOW_OUT_OF_RETENTION' | 'INVALID_CIDR' | 'RATE_LIMIT_ABOVE_PLAN' | 'RATE_LIMIT_DISABLE_NOT_ALLOWED' | 'OWNER_ONLY' | 'SIGNING_NOT_CONFIGURED' | 'SIGNING_ALREADY_CONFIGURED' | 'SIGNING_INVALID_KEYSTORE' | 'SIGNING_INVALID_ASC_KEY' | 'KEYSTORE_DOWNLOAD_EXPIRED' | 'KEYSTORE_NOT_DOWNLOADABLE' | 'MOBILE_BUILD_RUNNING' | 'MOBILE_BUILD_NOT_FOUND' | 'MOBILE_BUILD_NOT_READY' | 'DOWNLOAD_EXPIRED' | 'PROCESS_IN_PROGRESS' | 'SANDBOX_NOT_RUNNING' | 'MOBILE_LAYER_MISSING' | 'MOBILE_BUILD_FAILED' | 'MOBILE_ARTIFACT_INVALID' | 'SIGNING_FINGERPRINT_MISMATCH' | 'AM_RESTARTED' | 'LIMIT_ABOVE_PLAN_CEILING' | 'UNKNOWN_FEATURE' | 'INVALID_LIMIT' | 'FEATURE_NOT_DISABLABLE' | 'USE_PUT_LIMITS' | 'LIMIT_NOT_USER_EDITABLE' | 'NOT_AVAILABLE_FOR_ENGINE' | 'INVALID_AMOUNT' | 'REFUND_EXCEEDS_CHARGES' | 'IDEMPOTENCY_CONFLICT' | 'ORGANIZATION_NOT_FOUND' | 'ACCOUNT_NOT_FOUND' | 'PROVIDER_UNAVAILABLE' | 'URL_NOT_ALLOWED' | 'JOB_NOT_FOUND' | 'FILE_TOO_LARGE' | 'UNSUPPORTED_FILE_TYPE' | 'FILE_NOT_FOUND' | 'FILE_KEY_FORBIDDEN' | 'FILE_UPLOAD_ERROR' | 'FILE_DOWNLOAD_ERROR' | 'FILE_DELETE_ERROR' | 'UPLOAD_NOT_COMPLETED' | 'MISSING_URL' | 'MISSING_INPUT' | 'MISSING_EXTRACTION_CONFIG' | 'MISSING_QUERY' | 'SCRAPE_FAILED' | 'EXTRACT_FAILED' | 'SCREENSHOT_FAILED' | 'SEARCH_FAILED' | 'SCRAPE_BLOCKED' | 'SESSION_NOT_FOUND' | 'SESSION_EXPIRED' | 'SESSION_BUSY' | 'SESSION_LIMIT_REACHED' | 'SESSION_ENDED_INSUFFICIENT_CREDITS' | 'ACTION_TIMEOUT' | 'ACTION_FAILED' | 'UNKNOWN_COMMAND' | 'BATCH_TOO_LARGE' | 'SKIPPED' | 'UPLOAD_TOO_LARGE' | 'DOWNLOAD_TOO_LARGE' | 'CAPTURE_LIMIT_REACHED' | 'CAPTCHA_UNSOLVED' | 'BROWSER_CDP_NODE_ONLY' | 'DIALOG_NOT_OPEN' | 'STEALTH_TIER_UNAVAILABLE' | 'DOMAIN_NOT_ALLOWED' | 'CONTEXT_SEED_UNSUPPORTED' | 'EXTENSION_TOO_LARGE' | 'NL_PROVIDER_UNAVAILABLE' | 'PROGRAM_TOO_LARGE' | 'PROGRAM_UNBOUNDED' | 'UNKNOWN_STEP' | 'PROGRAM_IN_FLIGHT' | 'PROGRAM_TIMEOUT' | 'PROGRAM_NOT_FOUND' | 'PROGRAM_STEP_FAILED' | 'PROGRAM_LIMIT_REACHED' | 'CREATE_PDF_FROM_HTML_ERROR' | 'GENERATE_PDF_BY_URL_ERROR' | 'PDF_TIMEOUT' | 'PDF_TOO_LARGE' | 'FILENAME_REQUIRED' | 'SCANUM_EYE_ARRAY_NOT_SUPPORTED' | 'INVALID_EXTRA_FIELD_TYPE' | 'SCANUM_EYE_PDF_NOT_SUPPORTED' | 'UNSUPPORTED_SCAN_MODEL' | 'SCAN_DOCUMENT_ERROR' | 'SCAN_INVOICE_ERROR' | 'OCR_IMAGE_PROCESSING_ERROR' | 'OCR_PDF_PROCESSING_ERROR' | 'SCAN_TOO_MANY_PAGES' | 'SCAN_PDF_ENCRYPTED' | 'SCAN_XFA_UNSUPPORTED' | 'AUDIO_FILE_REQUIRED' | 'AUDIO_FILE_TOO_LARGE' | 'INVALID_AUDIO_FORMAT' | 'AUDIO_TRANSCRIPTION_ERROR' | 'TTS_TEXT_TOO_LONG' | 'TTS_VOICE_UNKNOWN' | 'TOO_MANY_AUDIO_TRANSCRIPTIONS' | 'EMAIL_SEND_FAILED' | 'TOO_MANY_ATTACHMENTS' | 'INVALID_ATTACHMENT_URL' | 'ATTACHMENT_TOO_LARGE' | 'TOO_MANY_RECIPIENTS' | 'EMAIL_RECIPIENT_SUPPRESSED' | 'EMAIL_DOMAIN_NOT_VERIFIED' | 'EMAIL_LOCAL_PART_TAKEN' | 'EMAIL_SENDING_PAUSED' | 'EMAIL_DOMAINS_REQUIRE_PAID_PLAN' | 'SUPPRESSION_PERMANENT' | 'DEV_RECIPIENT_NOT_ALLOWED' | 'CRON_LIMIT_REACHED' | 'INVALID_SCHEDULE' | 'CRON_URL_NOT_ALLOWED' | 'CRON_JOB_NOT_FOUND' | 'CRON_REQUIRES_PUBLISHED_PROJECT' | 'URL_NOT_PROJECT_HOST' | 'INDEXNOW_ERROR' | 'MCP_VERIFY_FAILED' | 'MCP_NAME_RESERVED' | 'MCP_LIMIT_REACHED' | 'MCP_SERVER_NOT_FOUND' | 'PAYMENTS_NOT_ENABLED' | 'PAYMENTS_LIVE_ONBOARDING_REQUIRED' | 'CARD_DATA_NOT_ACCEPTED' | 'STRIPE_ERROR' | 'STRIPE_RATE_LIMITED' | 'PAYMENTS_WEBHOOK_SIGNATURE_INVALID' | 'AI_MODEL_NOT_ALLOWED' | 'AI_MODEL_UNKNOWN' | 'AI_INVALID_SCHEMA' | 'AI_CONTENT_BLOCKED' | 'AI_CONTEXT_TOO_LONG' | 'AI_PROVIDER_QUOTA' | 'AI_PROVIDER_UNAVAILABLE' | 'AI_STREAM_ERROR' | 'AI_VIDEO_JOB_NOT_FOUND' | 'AI_VIDEO_FAILED' | 'MISSING_VIDEO_URL' | 'MISSING_PROMPT' | 'INVALID_VIDEO_URL' | 'INVALID_VIDEO_URL_PROTOCOL' | 'INVALID_MIME_TYPE_HINT' | 'VIDEO_TOO_LARGE' | 'VIDEO_URL_UNREACHABLE' | 'VIDEO_URL_NOT_A_VIDEO' | 'YOUTUBE_VIDEO_UNAVAILABLE' | 'NO_PAYMENT_METHOD' | 'DOMAIN_CONTACT_REQUIRED' | 'DOMAIN_UNAVAILABLE' | 'DOMAIN_PREMIUM_NOT_ALLOWED' | 'TLD_NOT_ALLOWED' | 'DOMAIN_LIMIT_REACHED' | 'PRICE_CHANGED' | 'PAYMENT_FAILED' | 'REGISTRATION_FAILED' | 'DOMAIN_NOT_RENEWABLE' | 'DOMAIN_ALREADY_ATTACHED' | 'DNS_RECORD_MANAGED' | 'DNS_RECORD_CONFLICT' | 'DNS_RECORD_LIMIT' | 'DOMAIN_TRANSFER_LOCKED' | 'DOMAIN_NOT_FOUND' | 'DOMAIN_IN_USE' | 'DOMAIN_ALREADY_ADDED' | 'NO_DEPLOYMENT' | 'REDIRECT_LIMIT_REACHED' | 'REDIRECT_INVALID' | 'APEX_NOT_FLATTENABLE'; message?: string | undefined; } | undefined; }[]; vars: Record<string, unknown>; startedAt: string; credits: number; result?: unknown; endedAt?: string | undefined; }>
774
+ ```
775
+
776
+ Polls until the program leaves `pending`/`running` (the `browser.program.completed` webhook is the push twin).
777
+
778
+ ## `totalum-sdk/realtime`
779
+
780
+ ### `totalumRealtime`
781
+
782
+ ```ts
783
+ totalumRealtime(options?: TotalumClientOptions)
784
+ ```
785
+
786
+ `totalum.realtime` server side over SDK-API `/v1/realtime/*` (scope `realtime`). The app's own
787
+ server mints a short-lived ticket after its own auth check and hands `{ticket, url}` to the page; the page opens the
788
+ `wss://` `url` and never holds a key. A room costs awake room-minutes × 4, never connections or messages.
789
+
790
+ #### `realtime.ticket`
791
+
792
+ ```ts
793
+ realtime.ticket(input: { room: string; identity: { id: string; name?: string | undefined; metadata?: Record<string, unknown> | undefined; }; permissions?: { subscribe?: boolean | undefined; publish?: boolean | undefined; } | undefined; ttl?: number | undefined; }): Promise<{ ticket: string; url: string; room: string; identity: { id: string; name?: string | undefined; metadata?: Record<string, unknown> | undefined; }; permissions: { subscribe: boolean; publish: boolean; }; expiresAt: string; }>
794
+ ```
795
+
796
+ A ticket for one room, one identity and one permission set (default subscribe only), valid to join for `ttl`
797
+ seconds (5–300, default 60).
798
+
799
+ ```ts
800
+ const { url } = await realtime.ticket({ room: `chat:${orgId}`, identity: { id: user.id }, permissions: { publish: true } });
801
+ ```
802
+
803
+ ## `totalum-sdk/logs`
804
+
805
+ ### `totalumLogs`
806
+
807
+ ```ts
808
+ totalumLogs(options?: TotalumClientOptions)
809
+ ```
810
+
811
+ `totalum.logs` over SDK-API `/v1/logs` (scope `logs:read`; the agent's sandbox key reads its dev
812
+ preview for free): the Worker invocations of the published app (`env: 'live'`) or the preview (`'dev'`). Free.
813
+
814
+ #### `logs.query`
815
+
816
+ ```ts
817
+ logs.query(q?: LogsQuery): Promise<{ items: { ts: string; level: 'error' | 'log' | 'debug' | 'info' | 'warn'; message: string; requestId: string | null; method: string | null; path: string | null; status: number | null; cpuMs: number | null; wallMs: number | null; outcome: string; exception?: { name: string; message: string; stack?: string | undefined; } | undefined; }[]; window: { from: string; to: string; source: 'live' | 'buffer'; }; nextCursor: string | null; sampled: boolean; hint?: string | undefined; }>
818
+ ```
819
+
820
+ Up to `limit` (≤ 500) log lines, newest first; `window` is always the window actually searched.
821
+
822
+ ```ts
823
+ const { items } = await logs.query({ level: 'error', env: 'live' });
824
+ ```
825
+
826
+ ## `totalum-sdk/analytics`
827
+
828
+ ### `totalumAnalytics`
829
+
830
+ ```ts
831
+ totalumAnalytics(options?: TotalumClientOptions)
832
+ ```
833
+
834
+ `totalum.analytics` over SDK-API `/v1/analytics/site` (scope `analytics:read`): the site's own traffic. Free.
835
+
836
+ #### `analytics.site`
837
+
838
+ ```ts
839
+ analytics.site(q?: SiteAnalyticsQuery): Promise<{ window: { from: string; to: string; granularity: 'day' | 'hour' | 'minute'; }; source: 'wae'; approximate: { uniques: boolean; }; cachedAt: string; series?: { [x: string]: number; t: string; }[] | undefined; top?: { [x: string]: number; key: string; share: number; }[] | undefined; }>
840
+ ```
841
+
842
+ Page views, visits, uniques, errors, bytes or TTFB as a series or a top-N.
843
+
844
+ ```ts
845
+ const { top } = await analytics.site({ dimension: 'path', metric: 'page_views', limit: 10 });
846
+ ```
847
+
848
+ ## Types
849
+
850
+ ### `BrowserSession`
851
+
852
+ ```ts
853
+ type BrowserSession = {
854
+ id: string;
855
+ liveViewUrl: string;
856
+ expiresAt: string;
857
+ actions: (batch: { [x: string]: unknown; type: 'pdf' | 'type' | 'waitFor' | 'screenshot' | 'content' | 'captcha.solve' | 'upload' | 'goto' | 'back' | 'forward' | 'reload' | 'pageInfo' | 'click' | 'dblclick' | 'press' | 'hover' | 'scroll' | 'dragAndDrop' | 'select' | 'frames.list' | 'frames.use' | 'tabs.list' | 'tabs.new' | 'tabs.use' | 'tabs.close' | 'evaluate' | 'extract' | 'cookies.get' | 'cookies.set' | 'cookies.clear' | 'storage.get' | 'storage.set' | 'storage.clear' | 'context.save' | 'downloads.list' | 'downloads.get' | 'network.capture' | 'network.log' | 'network.har' | 'network.intercept' | 'network.setHeaders' | 'emulate.viewport' | 'emulate.device' | 'emulate.geolocation' | 'emulate.timezone' | 'emulate.locale' | 'emulate.userAgent' | 'captcha.events' | 'proxy.usage' | 'stealth.get' | 'session.status' | 'session.liveView' | 'session.recording' | 'dialog.handle' | 'page.addInitScript' | 'page.exposeFunction' | 'emulate.media' | 'emulate.network' | 'emulate.cpu' | 'permissions.grant' | 'clipboard.read' | 'clipboard.write' | 'act' | 'observe' | 'session.release' | 'network.subscribe' | 'accessibility.snapshot'; frame?: string | undefined; tabId?: string | undefined; timeoutMs?: number | undefined; }[], opts?: { stopOnError?: boolean | undefined; } | undefined) => Promise<{ ok: boolean; data?: unknown; error?: { code: 'SERVICE_UNAUTHORIZED' | 'SERVICE_REPLAY' | 'ACTOR_MISMATCH' | 'PAYLOAD_TOO_LARGE' | 'VALIDATION_ERROR' | 'PROJECT_NOT_FOUND' | 'OPERATION_IN_PROGRESS' | 'AGENT_RUNNING' | 'PROJECT_MOVED' | 'OBJECT_MIGRATING' | 'INDEX_SHARD_UNAVAILABLE' | 'RATE_LIMIT_EXCEEDED' | 'PROJECT_PAUSED_RUNAWAY' | 'PROJECT_PAUSED_BALANCE' | 'PROJECT_SUSPENDED' | 'PROJECT_HIBERNATED' | 'PROJECT_DELETED' | 'PROJECT_PAUSED_BY_USER' | 'LIFECYCLE_NOT_APPLICABLE' | 'PROJECT_NOT_PAUSED' | 'PAUSE_DUMP_EXPIRED' | 'PAUSE_VERIFICATION_FAILED' | 'DEPLOYMENT_IN_PROGRESS' | 'REACTIVATE_IMPORT_MISMATCH' | 'RESUME_IMPORT_MISMATCH' | 'INSUFFICIENT_CREDITS' | 'VCAAS_INSUFFICIENT_CREDITS' | 'PROJECT_CREDIT_LIMIT_REACHED' | 'FREE_PROMPTS_DISABLED' | 'PLAN_REQUIRED' | 'FEATURE_LIMIT_REACHED' | 'FEATURE_DISABLED' | 'AGENT_ALREADY_RUNNING' | 'IMPORT_IN_PROGRESS' | 'TOO_MANY_RUN_REQUESTS' | 'PROMPT_SECURITY_VIOLATION' | 'NO_PROCESS_RUNNING' | 'RUN_NOT_FOUND' | 'DEPLOYMENT_RUNNING' | 'ENGINE_NOT_SUPPORTED' | 'ENGINE_V2_DISABLED' | 'ENGINE_REQUEST_NOT_ELIGIBLE' | 'ENGINE_MISMATCH' | 'INVALID_ENGINE_VERSION' | 'PROJECT_ENGINE_MISMATCH' | 'ENGINE_UNAVAILABLE' | 'PREVIEW_LABEL_TOO_LONG' | 'PROJECT_ALREADY_EXISTS' | 'CLOUDFLARE_API_ERROR' | 'PROVISIONING_BUSY' | 'UNAUTHORIZED' | 'LEGACY_KEY_NOT_SUPPORTED' | 'SANDBOX_KEY_EXPIRED' | 'AUTH_RATE_LIMITED' | 'FORBIDDEN_SCOPE' | 'KEY_ENV_MISMATCH' | 'KEY_LIMIT_EXCEEDED' | 'LIVE_DB_READ_ONLY' | 'DDL_NOT_ALLOWED' | 'MIGRATION_IN_PROGRESS' | 'MIGRATION_EDITED' | 'SCHEMA_OUT_OF_SYNC' | 'LIVE_MIGRATION_FAILED' | 'DESTRUCTIVE_MIGRATION_NEEDS_CONFIRMATION' | 'DEV_DATABASE_NOT_FOUND' | 'DATABASE_ROLE_NOT_FOUND' | 'SQL_ERROR' | 'SQL_MULTI_STATEMENT' | 'SQL_STATEMENT_TOO_LARGE' | 'SQL_TOO_MANY_PARAMS' | 'STATEMENT_NOT_ALLOWED' | 'VIRTUAL_TABLES_NOT_SUPPORTED' | 'USE_STORAGE_FOR_FILES' | 'D1_TYPE_ERROR' | 'MIGRATION_INVALID' | 'SYSTEM_TABLE_READ_ONLY' | 'SQL_READ_ONLY' | 'RESULT_TOO_LARGE' | 'QUERY_TIMEOUT' | 'DB_OVERLOADED' | 'D1_TRANSIENT' | 'DB_FULL_NEAR_LIMIT' | 'IDEMPOTENCY_KEY_REUSED' | 'IDEMPOTENT_REPLAY_UNAVAILABLE' | 'TABLE_NOT_FOUND' | 'SCHEMA_TOO_LARGE_FOR_COUNTS' | 'EXEC_REQUIRES_MIGRATE_MODE' | 'MIGRATION_UNKNOWN_IN_DB' | 'QUERY_LIMIT_EXCEEDED' | 'STORAGE_LIMIT_EXCEEDED' | 'METER_UNAVAILABLE' | 'COLUMN_NOT_FOUND' | 'VALUE_NOT_ALLOWED' | 'COLUMN_REQUIRED' | 'FILTER_TOO_COMPLEX' | 'OFFSET_TOO_LARGE' | 'BULK_TOO_LARGE' | 'NOT_A_JUNCTION_TABLE' | 'AMBIGUOUS_RELATION' | 'LIVE_WRITE_CONFIRMATION_REQUIRED' | 'RECORD_NOT_FOUND' | 'DEV_NAME_GUARD' | 'PROD_NAME_GUARD' | 'INVALID_RUN_REQUEST' | 'RUN_ALREADY_ACTIVE' | 'RUN_CONFLICT' | 'INVALID_CREDENTIALS' | 'ADAPTER_UNAVAILABLE' | 'DISK_FULL' | 'DEPLOY_FIX_ATTEMPTS_EXHAUSTED' | 'TOKEN_REVOKED' | 'AM_UPDATE_DOWNLOAD_FAILED' | 'AM_UPDATE_BAD_SHA' | 'AM_UPDATE_BAD_SIGNATURE' | 'AM_UPDATE_INCOMPATIBLE_IMAGE' | 'AM_UPDATE_START_FAILED' | 'AM_VERSION_UNAVAILABLE' | 'AM_UPDATE_FAILED' | 'RELEASE_CANARY_NOT_PASSED' | 'RELEASE_NOT_FOUND' | 'VISUAL_EDIT_PREVIEW_DEPLOYING' | 'VISUAL_EDIT_NOT_PATCHABLE' | 'VISUAL_EDIT_BASE_MISMATCH' | 'VISUAL_EDIT_TYPECHECK_FAILED' | 'INVALID_VISUAL_EDIT' | 'IMAGE_VERSION_NOT_FOUND' | 'IMAGE_VERSION_NOT_PROMOTABLE' | 'REALTIME_TICKET_INVALID' | 'REALTIME_TICKET_EXPIRED' | 'REALTIME_PERMISSION_DENIED' | 'REALTIME_MESSAGE_TOO_LARGE' | 'REALTIME_MESSAGE_RATE_EXCEEDED' | 'REALTIME_CONNECTION_LIMIT_REACHED' | 'REALTIME_ROOM_LIMIT_REACHED' | 'CONFIRMATION_REQUIRED' | 'MIGRATION_NOT_REVERSIBLE' | 'ALREADY_ON_PROVIDER' | 'DATABASE_MIGRATING' | 'LOGWATCH_INACTIVE' | 'AGENT_LOG_READS_LIMIT' | 'LOGS_UPSTREAM_ERROR' | 'ANALYTICS_INVALID_QUERY' | 'ANALYTICS_UPSTREAM_ERROR' | 'ANALYTICS_WINDOW_OUT_OF_RETENTION' | 'INVALID_CIDR' | 'RATE_LIMIT_ABOVE_PLAN' | 'RATE_LIMIT_DISABLE_NOT_ALLOWED' | 'OWNER_ONLY' | 'SIGNING_NOT_CONFIGURED' | 'SIGNING_ALREADY_CONFIGURED' | 'SIGNING_INVALID_KEYSTORE' | 'SIGNING_INVALID_ASC_KEY' | 'KEYSTORE_DOWNLOAD_EXPIRED' | 'KEYSTORE_NOT_DOWNLOADABLE' | 'MOBILE_BUILD_RUNNING' | 'MOBILE_BUILD_NOT_FOUND' | 'MOBILE_BUILD_NOT_READY' | 'DOWNLOAD_EXPIRED' | 'PROCESS_IN_PROGRESS' | 'SANDBOX_NOT_RUNNING' | 'MOBILE_LAYER_MISSING' | 'MOBILE_BUILD_FAILED' | 'MOBILE_ARTIFACT_INVALID' | 'SIGNING_FINGERPRINT_MISMATCH' | 'AM_RESTARTED' | 'LIMIT_ABOVE_PLAN_CEILING' | 'UNKNOWN_FEATURE' | 'INVALID_LIMIT' | 'FEATURE_NOT_DISABLABLE' | 'USE_PUT_LIMITS' | 'LIMIT_NOT_USER_EDITABLE' | 'NOT_AVAILABLE_FOR_ENGINE' | 'INVALID_AMOUNT' | 'REFUND_EXCEEDS_CHARGES' | 'IDEMPOTENCY_CONFLICT' | 'ORGANIZATION_NOT_FOUND' | 'ACCOUNT_NOT_FOUND' | 'PROVIDER_UNAVAILABLE' | 'URL_NOT_ALLOWED' | 'JOB_NOT_FOUND' | 'FILE_TOO_LARGE' | 'UNSUPPORTED_FILE_TYPE' | 'FILE_NOT_FOUND' | 'FILE_KEY_FORBIDDEN' | 'FILE_UPLOAD_ERROR' | 'FILE_DOWNLOAD_ERROR' | 'FILE_DELETE_ERROR' | 'UPLOAD_NOT_COMPLETED' | 'MISSING_URL' | 'MISSING_INPUT' | 'MISSING_EXTRACTION_CONFIG' | 'MISSING_QUERY' | 'SCRAPE_FAILED' | 'EXTRACT_FAILED' | 'SCREENSHOT_FAILED' | 'SEARCH_FAILED' | 'SCRAPE_BLOCKED' | 'SESSION_NOT_FOUND' | 'SESSION_EXPIRED' | 'SESSION_BUSY' | 'SESSION_LIMIT_REACHED' | 'SESSION_ENDED_INSUFFICIENT_CREDITS' | 'ACTION_TIMEOUT' | 'ACTION_FAILED' | 'UNKNOWN_COMMAND' | 'BATCH_TOO_LARGE' | 'SKIPPED' | 'UPLOAD_TOO_LARGE' | 'DOWNLOAD_TOO_LARGE' | 'CAPTURE_LIMIT_REACHED' | 'CAPTCHA_UNSOLVED' | 'BROWSER_CDP_NODE_ONLY' | 'DIALOG_NOT_OPEN' | 'STEALTH_TIER_UNAVAILABLE' | 'DOMAIN_NOT_ALLOWED' | 'CONTEXT_SEED_UNSUPPORTED' | 'EXTENSION_TOO_LARGE' | 'NL_PROVIDER_UNAVAILABLE' | 'PROGRAM_TOO_LARGE' | 'PROGRAM_UNBOUNDED' | 'UNKNOWN_STEP' | 'PROGRAM_IN_FLIGHT' | 'PROGRAM_TIMEOUT' | 'PROGRAM_NOT_FOUND' | 'PROGRAM_STEP_FAILED' | 'PROGRAM_LIMIT_REACHED' | 'CREATE_PDF_FROM_HTML_ERROR' | 'GENERATE_PDF_BY_URL_ERROR' | 'PDF_TIMEOUT' | 'PDF_TOO_LARGE' | 'FILENAME_REQUIRED' | 'SCANUM_EYE_ARRAY_NOT_SUPPORTED' | 'INVALID_EXTRA_FIELD_TYPE' | 'SCANUM_EYE_PDF_NOT_SUPPORTED' | 'UNSUPPORTED_SCAN_MODEL' | 'SCAN_DOCUMENT_ERROR' | 'SCAN_INVOICE_ERROR' | 'OCR_IMAGE_PROCESSING_ERROR' | 'OCR_PDF_PROCESSING_ERROR' | 'SCAN_TOO_MANY_PAGES' | 'SCAN_PDF_ENCRYPTED' | 'SCAN_XFA_UNSUPPORTED' | 'AUDIO_FILE_REQUIRED' | 'AUDIO_FILE_TOO_LARGE' | 'INVALID_AUDIO_FORMAT' | 'AUDIO_TRANSCRIPTION_ERROR' | 'TTS_TEXT_TOO_LONG' | 'TTS_VOICE_UNKNOWN' | 'TOO_MANY_AUDIO_TRANSCRIPTIONS' | 'EMAIL_SEND_FAILED' | 'TOO_MANY_ATTACHMENTS' | 'INVALID_ATTACHMENT_URL' | 'ATTACHMENT_TOO_LARGE' | 'TOO_MANY_RECIPIENTS' | 'EMAIL_RECIPIENT_SUPPRESSED' | 'EMAIL_DOMAIN_NOT_VERIFIED' | 'EMAIL_LOCAL_PART_TAKEN' | 'EMAIL_SENDING_PAUSED' | 'EMAIL_DOMAINS_REQUIRE_PAID_PLAN' | 'SUPPRESSION_PERMANENT' | 'DEV_RECIPIENT_NOT_ALLOWED' | 'CRON_LIMIT_REACHED' | 'INVALID_SCHEDULE' | 'CRON_URL_NOT_ALLOWED' | 'CRON_JOB_NOT_FOUND' | 'CRON_REQUIRES_PUBLISHED_PROJECT' | 'URL_NOT_PROJECT_HOST' | 'INDEXNOW_ERROR' | 'MCP_VERIFY_FAILED' | 'MCP_NAME_RESERVED' | 'MCP_LIMIT_REACHED' | 'MCP_SERVER_NOT_FOUND' | 'PAYMENTS_NOT_ENABLED' | 'PAYMENTS_LIVE_ONBOARDING_REQUIRED' | 'CARD_DATA_NOT_ACCEPTED' | 'STRIPE_ERROR' | 'STRIPE_RATE_LIMITED' | 'PAYMENTS_WEBHOOK_SIGNATURE_INVALID' | 'AI_MODEL_NOT_ALLOWED' | 'AI_MODEL_UNKNOWN' | 'AI_INVALID_SCHEMA' | 'AI_CONTENT_BLOCKED' | 'AI_CONTEXT_TOO_LONG' | 'AI_PROVIDER_QUOTA' | 'AI_PROVIDER_UNAVAILABLE' | 'AI_STREAM_ERROR' | 'AI_VIDEO_JOB_NOT_FOUND' | 'AI_VIDEO_FAILED' | 'MISSING_VIDEO_URL' | 'MISSING_PROMPT' | 'INVALID_VIDEO_URL' | 'INVALID_VIDEO_URL_PROTOCOL' | 'INVALID_MIME_TYPE_HINT' | 'VIDEO_TOO_LARGE' | 'VIDEO_URL_UNREACHABLE' | 'VIDEO_URL_NOT_A_VIDEO' | 'YOUTUBE_VIDEO_UNAVAILABLE' | 'NO_PAYMENT_METHOD' | 'DOMAIN_CONTACT_REQUIRED' | 'DOMAIN_UNAVAILABLE' | 'DOMAIN_PREMIUM_NOT_ALLOWED' | 'TLD_NOT_ALLOWED' | 'DOMAIN_LIMIT_REACHED' | 'PRICE_CHANGED' | 'PAYMENT_FAILED' | 'REGISTRATION_FAILED' | 'DOMAIN_NOT_RENEWABLE' | 'DOMAIN_ALREADY_ATTACHED' | 'DNS_RECORD_MANAGED' | 'DNS_RECORD_CONFLICT' | 'DNS_RECORD_LIMIT' | 'DOMAIN_TRANSFER_LOCKED' | 'DOMAIN_NOT_FOUND' | 'DOMAIN_IN_USE' | 'DOMAIN_ALREADY_ADDED' | 'NO_DEPLOYMENT' | 'REDIRECT_LIMIT_REACHED' | 'REDIRECT_INVALID' | 'APEX_NOT_FLATTENABLE'; message?: string | undefined; } | undefined; }[]>;
858
+ program: (program: { steps: BrowserStep[]; vars?: Record<string, unknown> | undefined; timeoutSec?: number | undefined; webhookUrl?: string | undefined; }) => Promise<{ programId: string; status: 'pending'; pollUrl: string; }>;
859
+ status: () => Promise<{ id: string; status: 'running' | 'failed' | 'expired' | 'ended'; startedAt: string; minutes: number; proxyMb: number; captchas: number; credits: number; expiresAt: string; }>;
860
+ close: () => Promise<{ minutes: number; proxyMb: number; captchas: number; creditsUsed: number; recordingUrl?: string | undefined; }>;
861
+ }
862
+ ```
863
+
864
+ One method per command, named like the command; the leading arguments are the command's main parameters (`goto(url, rest?)`, `click(target, rest?)`, `type(target, text, rest?)`, …) and the last argument is the rest of its parameters; each resolves to the command's result: `accessibility.snapshot`, `act`, `back`, `captcha.solve`, `click`, `clipboard.read`, `content`, `context.save`, `cookies.get`, `dblclick`, `dialog.handle`, `downloads.list`, `dragAndDrop`, `emulate.viewport`, `evaluate`, `extract`, `forward`, `frames.list`, `goto`, `hover`, `network.capture`, `observe`, `page.addInitScript`, `pageInfo`, `pdf`, `permissions.grant`, `press`, `proxy.usage`, `reload`, `screenshot`, `scroll`, `select`, `session.status`, `stealth.get`, `storage.get`, `tabs.list`, `type`, `upload`, `waitFor`.
865
+
866
+ ### `ChatResult`
867
+
868
+ ```ts
869
+ type ChatResult = {
870
+ id: string;
871
+ model: string;
872
+ text: string;
873
+ toolCalls: ToolCall[];
874
+ finishReason: string | null;
875
+ usage: ChatUsage;
876
+ raw: unknown;
877
+ }
878
+ ```
879
+
880
+ ### `ChatStream`
881
+
882
+ ```ts
883
+ type ChatStream = {
884
+ raw: ReadableStream<Uint8Array<ArrayBufferLike>>;
885
+ text: () => AsyncIterable<string>;
886
+ result: () => Promise<ChatResult>;
887
+ }
888
+ ```
889
+
890
+ ### `D1Database`
891
+
892
+ ```ts
893
+ type D1Database = {
894
+ prepare: (sql: string) => D1PreparedStatement;
895
+ batch: <T = unknown>(statements: D1PreparedStatement[]) => Promise<D1Result<T>[]>;
896
+ exec: (sql: string) => Promise<D1ExecResult>;
897
+ dump: () => Promise<ArrayBuffer>;
898
+ withSession: (constraintOrBookmark?: string | undefined) => D1DatabaseSession;
899
+ }
900
+ ```
901
+
902
+ ### `LogsQuery`
903
+
904
+ ```ts
905
+ type LogsQuery = {
906
+ limit?: number;
907
+ env?: 'dev' | 'live';
908
+ requestId?: string;
909
+ status?: string;
910
+ to?: string;
911
+ from?: string;
912
+ source?: 'live' | 'auto' | 'buffer';
913
+ level?: 'error' | 'log' | 'debug' | 'info' | 'warn';
914
+ q?: string;
915
+ path?: string;
916
+ }
917
+ ```
918
+
919
+ ### `ScanDocumentResult`
920
+
921
+ ```ts
922
+ type ScanDocumentResult = {
923
+ data: Record<string, unknown> | Record<string, unknown>[];
924
+ metadata: { usageUnits: number; exactUsageUnits: number; pages: number; provider: string; credits: number; };
925
+ }
926
+ ```
927
+
928
+ ### `SiteAnalyticsQuery`
929
+
930
+ ```ts
931
+ type SiteAnalyticsQuery = {
932
+ /** ISO; default the last 7 days. */
933
+ from?: string;
934
+ to?: string;
935
+ /** `minute` only within the last 30 minutes. */
936
+ granularity?: 'day' | 'hour' | 'minute';
937
+ /** Up to 4. */
938
+ metric?: 'uniques' | 'bytes' | 'errors' | 'page_views' | 'hits' | 'ttfb_p50' | 'ttfb_p95' | ('uniques' | 'bytes' | 'errors' | 'page_views' | 'hits' | 'ttfb_p50' | 'ttfb_p95')[];
939
+ /** Omit for a time series (`series`); set for a top-N (`top`). */
940
+ dimension?: 'browser' | 'country' | 'status' | 'device' | 'path' | 'hostname' | 'os' | 'referrer';
941
+ /** Top-N, ≤ 100. */
942
+ limit?: number;
943
+ bots?: 'exclude' | 'include' | 'only';
944
+ /** `dev` = the preview host, `live` = the published and custom hosts; omitted = both. */
945
+ env?: 'dev' | 'live';
946
+ }
947
+ ```
948
+
949
+ ### `TotalumAiOptions`
950
+
951
+ ```ts
952
+ type TotalumAiOptions = {
953
+ /** The exact-OpenRouter gateway `gatewayConfig()` returns; default `TOTALUM_AI_BASE_URL`, else `https://ai.totalum.app/api/v1`. */
954
+ aiBaseUrl?: string;
955
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
956
+ key?: string;
957
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
958
+ apiUrl?: string;
959
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
960
+ env?: 'dev' | 'live';
961
+ }
962
+ ```
963
+
964
+ ### `TotalumClientOptions`
965
+
966
+ ```ts
967
+ type TotalumClientOptions = {
968
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
969
+ key?: string;
970
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
971
+ apiUrl?: string;
972
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
973
+ env?: 'dev' | 'live';
974
+ }
975
+ ```
976
+
977
+ ### `TotalumD1Options`
978
+
979
+ ```ts
980
+ type TotalumD1Options = {
981
+ /** `'migrate'` (scripts/migrate.ts only) sends `x-totalum-migrate: 1` and enables `exec()`; default `'query'`. */
982
+ mode?: 'query' | 'migrate';
983
+ /** Migrate mode only: sends `x-totalum-migrate-destructive: 1`. */
984
+ destructive?: boolean;
985
+ /** An explicit binding wins over detection (plain Workers: `env.TOTALUM_DB`; tests: a Miniflare D1). */
986
+ binding?: D1Database;
987
+ /** `'https'` forces the HTTPS path even inside a Worker (the conformance corpus); default `'auto'`. */
988
+ transport?: 'auto' | 'https';
989
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
990
+ key?: string;
991
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
992
+ apiUrl?: string;
993
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
994
+ env?: 'dev' | 'live';
995
+ }
996
+ ```
997
+
998
+ ### `TotalumFilesOptions`
999
+
1000
+ ```ts
1001
+ type TotalumFilesOptions = {
1002
+ /** The public files host; default `TOTALUM_FILES_URL`, else `https://files.totalum-project.com`. */
1003
+ filesUrl?: string;
1004
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
1005
+ key?: string;
1006
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
1007
+ apiUrl?: string;
1008
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
1009
+ env?: 'dev' | 'live';
1010
+ }
1011
+ ```
1012
+
1013
+ ### `TotalumOptions`
1014
+
1015
+ ```ts
1016
+ type TotalumOptions = {
1017
+ /** The exact-OpenRouter gateway `gatewayConfig()` returns; default `TOTALUM_AI_BASE_URL`, else `https://ai.totalum.app/api/v1`. */
1018
+ aiBaseUrl?: string;
1019
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
1020
+ key?: string;
1021
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
1022
+ apiUrl?: string;
1023
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
1024
+ env?: 'dev' | 'live';
1025
+ /** The public files host; default `TOTALUM_FILES_URL`, else `https://files.totalum-project.com`. */
1026
+ filesUrl?: string;
1027
+ }
1028
+ ```
1029
+
1030
+ ### `UploadOptions`
1031
+
1032
+ ```ts
1033
+ type UploadOptions = {
1034
+ name?: string;
1035
+ contentType?: string;
1036
+ /** `true` stores the file under the private prefix: no public URL, read it through `getSignedUrl`. */
1037
+ private?: boolean;
1038
+ folder?: string;
1039
+ }
1040
+ ```