totalum-sdk 0.1.0-dev.10

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 (53) hide show
  1. package/README.md +18 -0
  2. package/dist/_types/billing.d-BbSZh1wY.d.ts +38 -0
  3. package/dist/_types/coerce.d-C0KIW76L.d.ts +6 -0
  4. package/dist/_types/errors.d-Cu3q_E_r.d.ts +3093 -0
  5. package/dist/_types/integrations.d-BNGV70e3.d.ts +793 -0
  6. package/dist/_types/ops.d-C9375KIG.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 +1595 -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 +31 -0
  16. package/dist/d1/https.js +103 -0
  17. package/dist/d1/index.d.ts +107 -0
  18. package/dist/d1/index.js +73 -0
  19. package/dist/d1/lazy.js +112 -0
  20. package/dist/d1/libsql.js +125 -0
  21. package/dist/d1/session.js +38 -0
  22. package/dist/d1/sql.js +87 -0
  23. package/dist/d1/types.js +1 -0
  24. package/dist/email/index.d.ts +31 -0
  25. package/dist/email/index.js +30 -0
  26. package/dist/errors.js +35 -0
  27. package/dist/files/index.d.ts +119 -0
  28. package/dist/files/index.js +63 -0
  29. package/dist/http.js +85 -0
  30. package/dist/index.d.ts +73 -0
  31. package/dist/index.js +68 -0
  32. package/dist/logs/index.d.ts +51 -0
  33. package/dist/logs/index.js +18 -0
  34. package/dist/payments/index.d.ts +47 -0
  35. package/dist/payments/index.js +20 -0
  36. package/dist/pdf/index.d.ts +42 -0
  37. package/dist/pdf/index.js +17 -0
  38. package/dist/react/index.d.ts +91 -0
  39. package/dist/react/index.js +178 -0
  40. package/dist/realtime/index.d.ts +103 -0
  41. package/dist/realtime/index.js +30 -0
  42. package/dist/scan/index.d.ts +46 -0
  43. package/dist/scan/index.js +12 -0
  44. package/dist/seo/index.d.ts +23 -0
  45. package/dist/seo/index.js +12 -0
  46. package/dist/speech/index.d.ts +41 -0
  47. package/dist/speech/index.js +22 -0
  48. package/dist/web/index.d.ts +170 -0
  49. package/dist/web/index.js +31 -0
  50. package/dist/webhooks/index.d.ts +48 -0
  51. package/dist/webhooks/index.js +61 -0
  52. package/package.json +146 -0
  53. package/totalum-sdk.md +1088 -0
package/totalum-sdk.md ADDED
@@ -0,0 +1,1088 @@
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`, `AUTO_EXECUTION_ALREADY_ACTIVE`, `REBUILD_RUNNING`, `SECRET_ALREADY_EXISTS`, `SECRET_LIMIT_EXCEEDED`, `RESERVED_SECRET_NAME`, `DUMP_NOT_FOUND`, `DUMP_INVALID`, `RESTORE_TARGET_NOT_EMPTY`, `ENGINE_NOT_SUPPORTED`, `ENGINE_V2_DISABLED`, `V2_TEMPORARILY_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`, `LIVE_WRITE_NEEDS_CONFIRMATION`, `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`, `BOOKMARK_NOT_FOUND`, `BACKUP_NOT_FOUND`, `BACKUP_NOT_DELETABLE`, `BACKUP_RATE_LIMITED`, `PRE_RESTORE_BACKUP_FAILED`, `RESTORE_VERIFY_FAILED`, `RUN_NOT_LATEST`, `DEV_DATABASE_EXISTS`, `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`, `NL_QUERY_UNANSWERABLE`, `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`, `RELEASE_ROLLOUT_ACTIVE`, `RELEASE_GUARD_PAUSED`, `RELEASE_BUILD_UNAVAILABLE`, `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`, `SECOND_FACTOR_NOT_CONFIGURED`, `PASSWORD_REQUIRED`, `PASSWORD_INCORRECT`, `TOO_MANY_ATTEMPTS`, `CONFIRMATION_MISMATCH`, `INVALID_TOKEN`, `MISSING_PERMISSIONS`, `REPO_NOT_FOUND`, `REPO_MISSING_BRANCHES`, `UNKNOWN`, `SANDBOX_NOT_READY`, `SYNC_FAILED`, `TOKEN_EXPIRED`, `GITHUB_NOT_CONNECTED`, `FIGMA_TOKEN_MISSING`, `FIGMA_TOKEN_MALFORMED`, `FIGMA_TOKEN_INVALID`, `FIGMA_TOKEN_FORBIDDEN`, `FIGMA_RATE_LIMITED`, `FIGMA_UNREACHABLE`, `INVALID_IMPORT_CODE`, `IMPORT_SOURCE_GONE`, `PROJECT_NOT_IMPORTABLE`, `PROJECT_IMPORT_LIMIT_REACHED`, `PROJECT_EXPORT_LIMIT_REACHED`, `VERSION_NOT_FOUND`, `INVALID_CODE_EDIT`, `CODE_EDIT_FAILED`, `BADGE_IN_SOURCE`.
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, the local D1 that
82
+ `initOpenNextCloudflareForDev()` binds under `next dev`, and an HTTPS client to SDK-API everywhere else.
83
+ Detection happens on the first statement, never at call time.
84
+
85
+ ## `totalum-sdk/files`
86
+
87
+ ### `totalumFiles`
88
+
89
+ ```ts
90
+ totalumFiles(options?: TotalumFilesOptions)
91
+ ```
92
+
93
+ `totalum.files` over HTTPS with the project key. Every call returns the file
94
+ descriptor `{key, fileName, fileSize, contentType, fileUrl, visibility, createdAt}` meant to be stored as-is in the
95
+ row's file column; failures throw `TotalumError` with SDK-API's frozen code.
96
+
97
+ #### `files.upload`
98
+
99
+ ```ts
100
+ 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; }>
101
+ ```
102
+
103
+ Up to 25 MB through SDK-API; larger files go through `getUploadUrl` + `complete`.
104
+
105
+ #### `files.getUploadUrl`
106
+
107
+ ```ts
108
+ 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; }>
109
+ ```
110
+
111
+ A presigned PUT (15 min, bound to this type and size) for a direct browser/Node upload; then `complete(key)`.
112
+
113
+ #### `files.complete`
114
+
115
+ ```ts
116
+ 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; }>
117
+ ```
118
+
119
+ Registers a file uploaded with `getUploadUrl` and returns its descriptor.
120
+
121
+ #### `files.list`
122
+
123
+ ```ts
124
+ 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; }>
125
+ ```
126
+
127
+ One page of the project's files, newest first: filter by `folder`, `name`, `type`, created and size ranges; `cursor`
128
+ from the previous page's `nextCursor`.
129
+
130
+ #### `files.get`
131
+
132
+ ```ts
133
+ 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; }>
134
+ ```
135
+
136
+ The descriptor of one file; `FILE_NOT_FOUND` (404) when it does not exist.
137
+
138
+ #### `files.getSignedUrl`
139
+
140
+ ```ts
141
+ files.getSignedUrl(key: string, opts?: { expiresInSeconds?: number | undefined; download?: boolean | undefined; }): Promise<string>
142
+ ```
143
+
144
+ A presigned GET that R2 verifies: 15 min by default, at most 7 days — the way to hand a private file to a browser.
145
+
146
+ #### `files.getDownloadUrl`
147
+
148
+ ```ts
149
+ files.getDownloadUrl(key: string, opts?: { expiresInSeconds?: number | undefined; download?: boolean | undefined; }): Promise<string>
150
+ ```
151
+
152
+ Same as `getSignedUrl`.
153
+
154
+ #### `files.presign`
155
+
156
+ ```ts
157
+ files.presign(keys: string[], opts?: { ttl?: number | undefined; download?: boolean | undefined; }): Promise<Record<string, string>>
158
+ ```
159
+
160
+ Signed GET URLs for many keys at once (`ttl` in seconds, ≤ 7 days).
161
+
162
+ #### `files.delete`
163
+
164
+ ```ts
165
+ files.delete(keys: string | string[]): Promise<void>
166
+ ```
167
+
168
+ Deletes one key, or up to 1000 keys at once.
169
+
170
+ #### `files.stream`
171
+
172
+ ```ts
173
+ files.stream(key: string, opts?: { range?: string | undefined; }): Promise<Response>
174
+ ```
175
+
176
+ The object itself (private files included), with `Range` support; errors throw like every other call.
177
+
178
+ #### `files.url`
179
+
180
+ ```ts
181
+ files.url(key: string): string
182
+ ```
183
+
184
+ Sync, no I/O: the public URL of a `p/` key, or the authenticated SDK-API URL of a private `pv/` key.
185
+
186
+ ## `totalum-sdk/payments`
187
+
188
+ ### `totalumPayments`
189
+
190
+ ```ts
191
+ totalumPayments(options?: TotalumClientOptions)
192
+ ```
193
+
194
+ `totalum.payments` over SDK-API `/v1/payments/*` with a project key (scope `payments`): Stripe
195
+ Connect direct charges on the project's own connected account. Card data never passes through here — send buyers to
196
+ the hosted Checkout `url` (SAQ-A); SDK-API refuses card fields with `CARD_DATA_NOT_ACCEPTED`.
197
+
198
+ #### `payments.getStatus`
199
+
200
+ ```ts
201
+ 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; }>
202
+ ```
203
+
204
+ Whether the project's Stripe account can take payments (charges, payouts, pending requirements).
205
+
206
+ #### `payments.onboardingLink`
207
+
208
+ ```ts
209
+ payments.onboardingLink(input: { returnUrl: string; refreshUrl: string; type?: 'account_onboarding' | 'account_update' | undefined; country?: string | undefined; }): Promise<{ url: string; expiresAt: string; }>
210
+ ```
211
+
212
+ Stripe's hosted onboarding for the project owner (single use; never for the agent's sandbox key).
213
+
214
+ #### `payments.createCheckout`
215
+
216
+ ```ts
217
+ 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; }>
218
+ ```
219
+
220
+ A hosted Checkout Session: `payment`, `subscription`, or `setup` (save a card for later). Redirect to `url`.
221
+
222
+ #### `payments.customerPortalLink`
223
+
224
+ ```ts
225
+ payments.customerPortalLink(input: { customerId: string; returnUrl: string; }): Promise<{ url: string; }>
226
+ ```
227
+
228
+ Stripe's hosted portal where a customer manages their subscriptions and saved cards.
229
+
230
+ ## `totalum-sdk/webhooks`
231
+
232
+ ### `verifyWebhook`
233
+
234
+ ```ts
235
+ 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; }>
236
+ ```
237
+
238
+ `totalum.webhooks.verify`: checks `Totalum-Signature: t=…,v1=…` — HMAC-SHA256 keyed with the
239
+ endpoint's secret string over `${t}.${rawBody}` — within ±300 s, and returns the parsed event. Pass the body exactly
240
+ as received (`await request.text()`). `secret` defaults to `TOTALUM_WEBHOOK_SECRET`.
241
+
242
+ ```ts
243
+ const event = await verifyWebhook(await request.text(), request.headers);
244
+ ```
245
+
246
+ ### `totalumWebhooks`
247
+
248
+ ```ts
249
+ totalumWebhooks(options?: TotalumClientOptions)
250
+ ```
251
+
252
+ `totalum.webhooks` over SDK-API `/v1/webhooks` (a key with scope `*`): where the project receives its
253
+ signed events (payments, e-mail, browser programs, `project.credits.exhausted`) and the secret they are signed with.
254
+
255
+ #### `webhooks.verify`
256
+
257
+ ```ts
258
+ 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; }>
259
+ ```
260
+
261
+ Same as `verifyWebhook`: checks `Totalum-Signature` and returns the parsed event.
262
+
263
+ #### `webhooks.get`
264
+
265
+ ```ts
266
+ webhooks.get(): Promise<{ url: string | null; enabled: boolean; secretPrefix: string | null; }>
267
+ ```
268
+
269
+ The endpoint and the first characters of its secret (the secret itself is shown only by `rotateSecret`).
270
+
271
+ #### `webhooks.setUrl`
272
+
273
+ ```ts
274
+ webhooks.setUrl(url: string): Promise<{ url: string | null; enabled: boolean; secretPrefix: string | null; }>
275
+ ```
276
+
277
+ Sets the `https://` URL the project's events are delivered to.
278
+
279
+ #### `webhooks.rotateSecret`
280
+
281
+ ```ts
282
+ webhooks.rotateSecret(): Promise<{ secret: string; }>
283
+ ```
284
+
285
+ A new signing secret, shown once; the old one keeps co-signing for 24 h. Store it as `TOTALUM_WEBHOOK_SECRET`.
286
+
287
+ ## `totalum-sdk/web`
288
+
289
+ ### `totalumWeb`
290
+
291
+ ```ts
292
+ totalumWeb(options?: TotalumClientOptions)
293
+ ```
294
+
295
+ `totalum.web` over SDK-API `/v1/web/*` (scope `web`): Firecrawl scrape/search/map/crawl and Browser
296
+ Run screenshots, charged provider cost × 28 — every result carries `usage.credits`.
297
+
298
+ #### `web.scrape`
299
+
300
+ ```ts
301
+ 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; }>
302
+ ```
303
+
304
+ One page as `markdown`, `html`, `links`, … (Firecrawl).
305
+
306
+ ```ts
307
+ const { markdown } = await web.scrape('https://example.com', { formats: ['markdown'] });
308
+ ```
309
+
310
+ #### `web.search`
311
+
312
+ ```ts
313
+ 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; }; }>
314
+ ```
315
+
316
+ A web search; with `scrapeOptions` each result also carries its page content.
317
+
318
+ #### `web.map`
319
+
320
+ ```ts
321
+ 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; }; }>
322
+ ```
323
+
324
+ The URLs of a site (sitemap and links), without fetching the pages.
325
+
326
+ #### `web.crawl`
327
+
328
+ ```ts
329
+ 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; }>
330
+ ```
331
+
332
+ `202 {jobId}`: poll `crawlStatus` until the job leaves `running`; that read settles its charge.
333
+
334
+ #### `web.crawlStatus`
335
+
336
+ ```ts
337
+ 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; }>
338
+ ```
339
+
340
+ The crawl job: `status`, pages so far and their content.
341
+
342
+ #### `web.cancelCrawl`
343
+
344
+ ```ts
345
+ 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; }>
346
+ ```
347
+
348
+ Stops a running crawl; pages already crawled are charged.
349
+
350
+ #### `web.screenshot`
351
+
352
+ ```ts
353
+ 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; }; }>
354
+ ```
355
+
356
+ A screenshot of a `url` or of inline `html`, stored as a project file (`key`, `url`).
357
+
358
+ ## `totalum-sdk/pdf`
359
+
360
+ ### `totalumPdf`
361
+
362
+ ```ts
363
+ totalumPdf(options?: TotalumClientOptions)
364
+ ```
365
+
366
+ `totalum.pdf` over `/v1/pdf/*` (scope `files:write`): a new file in the project's storage each time.
367
+
368
+ #### `pdf.fromHtml`
369
+
370
+ ```ts
371
+ 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; }; }>
372
+ ```
373
+
374
+ A PDF rendered from HTML, stored as a project file (`key`, `url`).
375
+
376
+ ```ts
377
+ const { url } = await pdf.fromHtml({ html: '<h1>Invoice 12</h1>', name: 'invoice-12' });
378
+ ```
379
+
380
+ #### `pdf.fromUrl`
381
+
382
+ ```ts
383
+ 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; }; }>
384
+ ```
385
+
386
+ A PDF of a web page, stored as a project file.
387
+
388
+ ## `totalum-sdk/scan`
389
+
390
+ ### `totalumScan`
391
+
392
+ ```ts
393
+ totalumScan(options?: TotalumClientOptions)
394
+ ```
395
+
396
+ `totalum.scan` over `/v1/scan/*` (scope `scan`): a vision model through Totalum's AI gateway.
397
+
398
+ #### `scan.document`
399
+
400
+ ```ts
401
+ 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>
402
+ ```
403
+
404
+ Extracts the fields described by `properties` from a document or image (one set per page on request).
405
+
406
+ #### `scan.ocr`
407
+
408
+ ```ts
409
+ 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; }; }>
410
+ ```
411
+
412
+ The text of a document or image, per page as Markdown.
413
+
414
+ ## `totalum-sdk/speech`
415
+
416
+ ### `totalumSpeech`
417
+
418
+ ```ts
419
+ totalumSpeech(options?: TotalumClientOptions)
420
+ ```
421
+
422
+ `totalum.speech` over `/v1/speech/*` (scope `speech`): OpenRouter speech through Totalum.
423
+
424
+ #### `speech.transcribe`
425
+
426
+ ```ts
427
+ 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; }>
428
+ ```
429
+
430
+ Speech to text from `audioBase64` or a `url`; optional language, word timestamps and speakers.
431
+
432
+ #### `speech.synthesize`
433
+
434
+ ```ts
435
+ 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; }>
436
+ ```
437
+
438
+ The audio bytes, or with `store: true` the stored file `{key, url, usage}`; `credits` is the call's hold.
439
+
440
+ ## `totalum-sdk/ai`
441
+
442
+ ### `totalumAi`
443
+
444
+ ```ts
445
+ totalumAi(options?: TotalumAiOptions)
446
+ ```
447
+
448
+ `totalum.ai` over SDK-API `/v1/ai/*` (scope `ai`): aliases `cheap|normal|best` or any
449
+ OpenRouter slug, every call priced `usage.cost × 28` and returned with its credits. No `ai.agent()` — the
450
+ agent loop is the template's `src/agents/` on the Vercel AI SDK, pointed at `gatewayConfig()`.
451
+
452
+ #### `ai.chat`
453
+
454
+ ```ts
455
+ 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>
456
+ ```
457
+
458
+ A chat completion; `model` is an alias (`cheap`, `normal`, `best`) or any OpenRouter slug.
459
+
460
+ ```ts
461
+ const { text } = await ai.chat({ model: 'cheap', messages: [{ role: 'user', content: 'Hi' }] });
462
+ ```
463
+
464
+ #### `ai.chat.stream`
465
+
466
+ ```ts
467
+ 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>
468
+ ```
469
+
470
+ The same request streamed: `raw` is the OpenAI-format SSE (return it from a route), `text()` its deltas,
471
+ `result()` the final result with its credits.
472
+
473
+ #### `ai.generateObject`
474
+
475
+ ```ts
476
+ 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; }; }>
477
+ ```
478
+
479
+ A JSON object matching `schema` (JSON Schema).
480
+
481
+ #### `ai.classify`
482
+
483
+ ```ts
484
+ ai.classify(req: { input: string; options: readonly string[]; model?: string | undefined; instructions?: string | undefined; }): Promise<{ label: string; }>
485
+ ```
486
+
487
+ Sugar over `generateObject`: one of `options`, chosen by the model.
488
+
489
+ #### `ai.embed`
490
+
491
+ ```ts
492
+ ai.embed(req: { input: string | string[]; model?: string | undefined; }): Promise<{ embeddings: number[][]; usage: { credits: number; vendor?: string | undefined; units?: number | undefined; vendorCostUsd?: number | undefined; }; }>
493
+ ```
494
+
495
+ Embedding vectors for one or more texts.
496
+
497
+ #### `ai.image.generate`
498
+
499
+ ```ts
500
+ 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; }>
501
+ ```
502
+
503
+ Images from a prompt; `store: true` keeps them as project files.
504
+
505
+ #### `ai.image.edit`
506
+
507
+ ```ts
508
+ 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; }>
509
+ ```
510
+
511
+ An image edited by a prompt.
512
+
513
+ #### `ai.video.generate`
514
+
515
+ ```ts
516
+ 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; }>
517
+ ```
518
+
519
+ `202`: the job and the credits reserved for it; poll `get(jobId)` (the clip is stored when it completes).
520
+
521
+ #### `ai.video.get`
522
+
523
+ ```ts
524
+ 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; }>
525
+ ```
526
+
527
+ The video job: `status`, and the stored clip once completed.
528
+
529
+ #### `ai.video.wait`
530
+
531
+ ```ts
532
+ 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; }>
533
+ ```
534
+
535
+ ⚠ NODE-ONLY: polls `get(jobId)` until the job leaves `queued`/`running` (default every 5 s, at most 10 min).
536
+ In a Worker it throws `NODE_ONLY` — store the `jobId` and read `get(jobId)` later instead.
537
+
538
+ #### `ai.vision.describe`
539
+
540
+ ```ts
541
+ 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; }; }>
542
+ ```
543
+
544
+ A text description of an image (URL, data URL or project file key).
545
+
546
+ #### `ai.speech.speak`
547
+
548
+ ```ts
549
+ 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; }>
550
+ ```
551
+
552
+ Same as `speech.synthesize`.
553
+
554
+ #### `ai.speech.transcribe`
555
+
556
+ ```ts
557
+ 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; }>
558
+ ```
559
+
560
+ Same as `speech.transcribe`.
561
+
562
+ #### `ai.models.list`
563
+
564
+ ```ts
565
+ 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; }>
566
+ ```
567
+
568
+ The model aliases and the models a project may call, with their prices.
569
+
570
+ #### `ai.gatewayConfig`
571
+
572
+ ```ts
573
+ ai.gatewayConfig(): { baseURL: string; apiKey: string; }
574
+ ```
575
+
576
+ The exact OpenRouter API for any OpenRouter/OpenAI client: `new OpenAI(ai.gatewayConfig())`. Server-side only.
577
+
578
+ ## `totalum-sdk/email`
579
+
580
+ ### `totalumEmail`
581
+
582
+ ```ts
583
+ totalumEmail(options?: TotalumClientOptions)
584
+ ```
585
+
586
+ `totalum.email` over SDK-API `/v1/email/*` (scope `email`): Resend, HTML sent byte for byte, charged
587
+ per recipient. On dev only allow-listed recipients are accepted (`DEV_RECIPIENT_NOT_ALLOWED`).
588
+
589
+ #### `email.send`
590
+
591
+ ```ts
592
+ 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'; }>
593
+ ```
594
+
595
+ Sends one e-mail (HTML byte for byte); charged per recipient.
596
+
597
+ ```ts
598
+ await email.send({ to: 'ana@example.com', subject: 'Welcome', html: '<p>Hi Ana</p>' });
599
+ ```
600
+
601
+ #### `email.get`
602
+
603
+ ```ts
604
+ 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>
605
+ ```
606
+
607
+ `null` when the e-mail is not this project's.
608
+
609
+ ## `totalum-sdk/cron`
610
+
611
+ ### `totalumCron`
612
+
613
+ ```ts
614
+ totalumCron(options?: TotalumClientOptions)
615
+ ```
616
+
617
+ `totalum.cron` over SDK-API `/v1/cron/*` (scope `cron`): HTTP jobs against the project's own host,
618
+ fired by Totalum's Scheduler; limits per plan (`429 CRON_LIMIT_REACHED {limit, plan}`, `400 INVALID_SCHEDULE
619
+ {minIntervalSeconds}`). Executions cost nothing.
620
+
621
+ #### `cron.create`
622
+
623
+ ```ts
624
+ 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; }>
625
+ ```
626
+
627
+ A job that calls a URL of the project's own host on a cron `schedule` (or `{ everyMinutes }`).
628
+
629
+ ```ts
630
+ await cron.create({
631
+ name: 'daily-report',
632
+ schedule: '0 8 * * *',
633
+ request: { method: 'POST', url: 'https://my-app.totalum-project.com/api/cron/report' },
634
+ });
635
+ ```
636
+
637
+ #### `cron.list`
638
+
639
+ ```ts
640
+ 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; }[]>
641
+ ```
642
+
643
+ Every job of the project.
644
+
645
+ #### `cron.get`
646
+
647
+ ```ts
648
+ 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>
649
+ ```
650
+
651
+ `null` when the job is not this project's.
652
+
653
+ #### `cron.update`
654
+
655
+ ```ts
656
+ 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; }>
657
+ ```
658
+
659
+ Changes any field of a job (`schedule`, `request`, `enabled`, …).
660
+
661
+ #### `cron.delete`
662
+
663
+ ```ts
664
+ cron.delete(id: string): Promise<void>
665
+ ```
666
+
667
+ Deletes a job.
668
+
669
+ #### `cron.pause`
670
+
671
+ ```ts
672
+ 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; }>
673
+ ```
674
+
675
+ Stops a job from firing until `resume`.
676
+
677
+ #### `cron.resume`
678
+
679
+ ```ts
680
+ 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; }>
681
+ ```
682
+
683
+ Lets a paused job fire again.
684
+
685
+ #### `cron.runs`
686
+
687
+ ```ts
688
+ 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; }>
689
+ ```
690
+
691
+ A job's executions, newest first (30 days).
692
+
693
+ #### `cron.trigger`
694
+
695
+ ```ts
696
+ cron.trigger(id: string): Promise<{ runId: string; }>
697
+ ```
698
+
699
+ Fires a job now, outside its schedule.
700
+
701
+ ## `totalum-sdk/seo`
702
+
703
+ ### `totalumSeo`
704
+
705
+ ```ts
706
+ totalumSeo(options?: TotalumClientOptions)
707
+ ```
708
+
709
+ `totalum.seo` over SDK-API `/v1/seo/*` (scope `seo`): IndexNow for verified custom domains, free.
710
+
711
+ #### `seo.notifyChanged`
712
+
713
+ ```ts
714
+ seo.notifyChanged(urls: string[]): Promise<{ accepted: number; indexNow: 'error' | 'sent' | 'skipped_no_custom_domain'; sitemapsPinged: boolean; }>
715
+ ```
716
+
717
+ Tells search engines (IndexNow) that these URLs of the project's custom domains changed.
718
+
719
+ #### `seo.indexNowKey`
720
+
721
+ ```ts
722
+ seo.indexNowKey(): Promise<{ key: string; keyLocation: string; }>
723
+ ```
724
+
725
+ The key the template serves at `/<key>.txt`.
726
+
727
+ ## `totalum-sdk/browser`
728
+
729
+ ### `totalumBrowser`
730
+
731
+ ```ts
732
+ totalumBrowser(options?: TotalumClientOptions)
733
+ ```
734
+
735
+ `totalum.browser` over SDK-API `/v1/browser/*` (scope `browser`): Browserbase sessions driven entirely
736
+ over HTTPS, so every command works from a Worker. A command's refusal throws `TotalumError` with its frozen
737
+ code (`ACTION_TIMEOUT`, `ACTION_FAILED`, …); `actions()` returns every result instead.
738
+
739
+ #### `browser.session`
740
+
741
+ ```ts
742
+ 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>
743
+ ```
744
+
745
+ Opens a session with the vendor options and the Totalum-synthesised ones.
746
+
747
+ #### `browser.sessions.list`
748
+
749
+ ```ts
750
+ 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; }>
751
+ ```
752
+
753
+ The project's sessions, filtered by `status` or `metadata`.
754
+
755
+ #### `browser.sessions.get`
756
+
757
+ ```ts
758
+ browser.sessions.get(id: string): BrowserSession
759
+ ```
760
+
761
+ A handle on an existing session (no call is made).
762
+
763
+ #### `browser.programs.get`
764
+
765
+ ```ts
766
+ 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' | 'AUTO_EXECUTION_ALREADY_ACTIVE' | 'REBUILD_RUNNING' | 'SECRET_ALREADY_EXISTS' | 'SECRET_LIMIT_EXCEEDED' | 'RESERVED_SECRET_NAME' | 'DUMP_NOT_FOUND' | 'DUMP_INVALID' | 'RESTORE_TARGET_NOT_EMPTY' | 'ENGINE_NOT_SUPPORTED' | 'ENGINE_V2_DISABLED' | 'V2_TEMPORARILY_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' | 'LIVE_WRITE_NEEDS_CONFIRMATION' | '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' | 'BOOKMARK_NOT_FOUND' | 'BACKUP_NOT_FOUND' | 'BACKUP_NOT_DELETABLE' | 'BACKUP_RATE_LIMITED' | 'PRE_RESTORE_BACKUP_FAILED' | 'RESTORE_VERIFY_FAILED' | 'RUN_NOT_LATEST' | 'DEV_DATABASE_EXISTS' | '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' | 'NL_QUERY_UNANSWERABLE' | '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' | 'RELEASE_ROLLOUT_ACTIVE' | 'RELEASE_GUARD_PAUSED' | 'RELEASE_BUILD_UNAVAILABLE' | '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' | 'SECOND_FACTOR_NOT_CONFIGURED' | 'PASSWORD_REQUIRED' | 'PASSWORD_INCORRECT' | 'TOO_MANY_ATTEMPTS' | 'CONFIRMATION_MISMATCH' | 'INVALID_TOKEN' | 'MISSING_PERMISSIONS' | 'REPO_NOT_FOUND' | 'REPO_MISSING_BRANCHES' | 'UNKNOWN' | 'SANDBOX_NOT_READY' | 'SYNC_FAILED' | 'TOKEN_EXPIRED' | 'GITHUB_NOT_CONNECTED' | 'FIGMA_TOKEN_MISSING' | 'FIGMA_TOKEN_MALFORMED' | 'FIGMA_TOKEN_INVALID' | 'FIGMA_TOKEN_FORBIDDEN' | 'FIGMA_RATE_LIMITED' | 'FIGMA_UNREACHABLE' | 'INVALID_IMPORT_CODE' | 'IMPORT_SOURCE_GONE' | 'PROJECT_NOT_IMPORTABLE' | 'PROJECT_IMPORT_LIMIT_REACHED' | 'PROJECT_EXPORT_LIMIT_REACHED' | 'VERSION_NOT_FOUND' | 'INVALID_CODE_EDIT' | 'CODE_EDIT_FAILED' | 'BADGE_IN_SOURCE'; message?: string | undefined; } | undefined; }[]; vars: Record<string, unknown>; startedAt: string; credits: number; result?: unknown; endedAt?: string | undefined; }>
767
+ ```
768
+
769
+ A program's status and, once finished, its results.
770
+
771
+ #### `browser.programs.wait`
772
+
773
+ ```ts
774
+ 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' | 'AUTO_EXECUTION_ALREADY_ACTIVE' | 'REBUILD_RUNNING' | 'SECRET_ALREADY_EXISTS' | 'SECRET_LIMIT_EXCEEDED' | 'RESERVED_SECRET_NAME' | 'DUMP_NOT_FOUND' | 'DUMP_INVALID' | 'RESTORE_TARGET_NOT_EMPTY' | 'ENGINE_NOT_SUPPORTED' | 'ENGINE_V2_DISABLED' | 'V2_TEMPORARILY_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' | 'LIVE_WRITE_NEEDS_CONFIRMATION' | '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' | 'BOOKMARK_NOT_FOUND' | 'BACKUP_NOT_FOUND' | 'BACKUP_NOT_DELETABLE' | 'BACKUP_RATE_LIMITED' | 'PRE_RESTORE_BACKUP_FAILED' | 'RESTORE_VERIFY_FAILED' | 'RUN_NOT_LATEST' | 'DEV_DATABASE_EXISTS' | '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' | 'NL_QUERY_UNANSWERABLE' | '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' | 'RELEASE_ROLLOUT_ACTIVE' | 'RELEASE_GUARD_PAUSED' | 'RELEASE_BUILD_UNAVAILABLE' | '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' | 'SECOND_FACTOR_NOT_CONFIGURED' | 'PASSWORD_REQUIRED' | 'PASSWORD_INCORRECT' | 'TOO_MANY_ATTEMPTS' | 'CONFIRMATION_MISMATCH' | 'INVALID_TOKEN' | 'MISSING_PERMISSIONS' | 'REPO_NOT_FOUND' | 'REPO_MISSING_BRANCHES' | 'UNKNOWN' | 'SANDBOX_NOT_READY' | 'SYNC_FAILED' | 'TOKEN_EXPIRED' | 'GITHUB_NOT_CONNECTED' | 'FIGMA_TOKEN_MISSING' | 'FIGMA_TOKEN_MALFORMED' | 'FIGMA_TOKEN_INVALID' | 'FIGMA_TOKEN_FORBIDDEN' | 'FIGMA_RATE_LIMITED' | 'FIGMA_UNREACHABLE' | 'INVALID_IMPORT_CODE' | 'IMPORT_SOURCE_GONE' | 'PROJECT_NOT_IMPORTABLE' | 'PROJECT_IMPORT_LIMIT_REACHED' | 'PROJECT_EXPORT_LIMIT_REACHED' | 'VERSION_NOT_FOUND' | 'INVALID_CODE_EDIT' | 'CODE_EDIT_FAILED' | 'BADGE_IN_SOURCE'; message?: string | undefined; } | undefined; }[]; vars: Record<string, unknown>; startedAt: string; credits: number; result?: unknown; endedAt?: string | undefined; }>
775
+ ```
776
+
777
+ Polls until the program leaves `pending`/`running` (the `browser.program.completed` webhook is the push twin).
778
+
779
+ ## `totalum-sdk/realtime`
780
+
781
+ ### `totalumRealtime`
782
+
783
+ ```ts
784
+ totalumRealtime(options?: TotalumClientOptions)
785
+ ```
786
+
787
+ `totalum.realtime` server side over SDK-API `/v1/realtime/*` (scope `realtime`). The app's own
788
+ server mints a short-lived ticket after its own auth check and hands `{ticket, url}` to the page; the page opens the
789
+ `wss://` `url` and never holds a key. A room costs awake room-minutes × 4, never connections or messages.
790
+
791
+ #### `realtime.ticket`
792
+
793
+ ```ts
794
+ 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; }>
795
+ ```
796
+
797
+ A ticket for one room, one identity and one permission set (default subscribe only), valid to join for `ttl`
798
+ seconds (5–300, default 60).
799
+
800
+ ```ts
801
+ const { url } = await realtime.ticket({ room: `chat:${orgId}`, identity: { id: user.id }, permissions: { publish: true } });
802
+ ```
803
+
804
+ #### `realtime.publish`
805
+
806
+ ```ts
807
+ realtime.publish(room: string, input: { data: unknown; event?: string | undefined; identity?: { id: string; name?: string | undefined; } | undefined; }): Promise<{ messageId: string; at: string; connections: number; }>
808
+ ```
809
+
810
+ Publishes one message to every socket subscribed to `room`, from the app's own server (a route handler, a cron
811
+ job): no socket needed. Subscribers receive the same `message` frame a socket publish sends, with `event`
812
+ (default `message`) and `identity` (default `{ id: 'server' }`). Resolves with the message id, its timestamp
813
+ and the number of sockets it was sent to (`0` when nobody is connected — it is not queued).
814
+
815
+ ```ts
816
+ const { connections } = await realtime.publish(`orders:${shopId}`, { event: 'order.created', data: { orderId } });
817
+ ```
818
+
819
+ ## `totalum-sdk/logs`
820
+
821
+ ### `totalumLogs`
822
+
823
+ ```ts
824
+ totalumLogs(options?: TotalumClientOptions)
825
+ ```
826
+
827
+ `totalum.logs` over SDK-API `/v1/logs` (scope `logs:read`; the agent's sandbox key reads its dev
828
+ preview for free): the Worker invocations of the published app (`env: 'live'`) or the preview (`'dev'`). Free.
829
+
830
+ #### `logs.query`
831
+
832
+ ```ts
833
+ 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; }>
834
+ ```
835
+
836
+ Up to `limit` (≤ 500) log lines, newest first; `window` is always the window actually searched.
837
+
838
+ ```ts
839
+ const { items } = await logs.query({ level: 'error', env: 'live' });
840
+ ```
841
+
842
+ ## `totalum-sdk/analytics`
843
+
844
+ ### `totalumAnalytics`
845
+
846
+ ```ts
847
+ totalumAnalytics(options?: TotalumClientOptions)
848
+ ```
849
+
850
+ `totalum.analytics` over SDK-API `/v1/analytics/site` (scope `analytics:read`): the site's own traffic. Free.
851
+
852
+ #### `analytics.site`
853
+
854
+ ```ts
855
+ 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; }>
856
+ ```
857
+
858
+ Page views, visits, uniques, errors, bytes or TTFB as a series or a top-N.
859
+
860
+ ```ts
861
+ const { top } = await analytics.site({ dimension: 'path', metric: 'page_views', limit: 10 });
862
+ ```
863
+
864
+ ## `totalum-sdk/react`
865
+
866
+ ### `useRealtimeChannel`
867
+
868
+ ```ts
869
+ useRealtimeChannel(room: string, options?: RealtimeChannelOptions<M>): { publish: (data: unknown, event?: string) => boolean; status: RealtimeStatus; messages: RealtimeMessage<unknown>[]; others: RealtimePeer<M>[]; }
870
+ ```
871
+
872
+ A room in a client component: `status`, the `messages` received since it opened, `others` (with `presence`), and
873
+ `publish(data, event?)`. Render `status === 'reconnecting'` as an ordinary state, not an error.
874
+
875
+ ```ts
876
+ const { messages, others, publish, status } = useRealtimeChannel(`chat:${roomId}`, { presence: { name } });
877
+ ```
878
+
879
+ ## Types
880
+
881
+ ### `BrowserSession`
882
+
883
+ ```ts
884
+ type BrowserSession = {
885
+ id: string;
886
+ liveViewUrl: string;
887
+ expiresAt: string;
888
+ 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' | 'AUTO_EXECUTION_ALREADY_ACTIVE' | 'REBUILD_RUNNING' | 'SECRET_ALREADY_EXISTS' | 'SECRET_LIMIT_EXCEEDED' | 'RESERVED_SECRET_NAME' | 'DUMP_NOT_FOUND' | 'DUMP_INVALID' | 'RESTORE_TARGET_NOT_EMPTY' | 'ENGINE_NOT_SUPPORTED' | 'ENGINE_V2_DISABLED' | 'V2_TEMPORARILY_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' | 'LIVE_WRITE_NEEDS_CONFIRMATION' | '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' | 'BOOKMARK_NOT_FOUND' | 'BACKUP_NOT_FOUND' | 'BACKUP_NOT_DELETABLE' | 'BACKUP_RATE_LIMITED' | 'PRE_RESTORE_BACKUP_FAILED' | 'RESTORE_VERIFY_FAILED' | 'RUN_NOT_LATEST' | 'DEV_DATABASE_EXISTS' | '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' | 'NL_QUERY_UNANSWERABLE' | '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' | 'RELEASE_ROLLOUT_ACTIVE' | 'RELEASE_GUARD_PAUSED' | 'RELEASE_BUILD_UNAVAILABLE' | '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' | 'SECOND_FACTOR_NOT_CONFIGURED' | 'PASSWORD_REQUIRED' | 'PASSWORD_INCORRECT' | 'TOO_MANY_ATTEMPTS' | 'CONFIRMATION_MISMATCH' | 'INVALID_TOKEN' | 'MISSING_PERMISSIONS' | 'REPO_NOT_FOUND' | 'REPO_MISSING_BRANCHES' | 'UNKNOWN' | 'SANDBOX_NOT_READY' | 'SYNC_FAILED' | 'TOKEN_EXPIRED' | 'GITHUB_NOT_CONNECTED' | 'FIGMA_TOKEN_MISSING' | 'FIGMA_TOKEN_MALFORMED' | 'FIGMA_TOKEN_INVALID' | 'FIGMA_TOKEN_FORBIDDEN' | 'FIGMA_RATE_LIMITED' | 'FIGMA_UNREACHABLE' | 'INVALID_IMPORT_CODE' | 'IMPORT_SOURCE_GONE' | 'PROJECT_NOT_IMPORTABLE' | 'PROJECT_IMPORT_LIMIT_REACHED' | 'PROJECT_EXPORT_LIMIT_REACHED' | 'VERSION_NOT_FOUND' | 'INVALID_CODE_EDIT' | 'CODE_EDIT_FAILED' | 'BADGE_IN_SOURCE'; message?: string | undefined; } | undefined; }[]>;
889
+ program: (program: { steps: BrowserStep[]; vars?: Record<string, unknown> | undefined; timeoutSec?: number | undefined; webhookUrl?: string | undefined; }) => Promise<{ programId: string; status: 'pending'; pollUrl: string; }>;
890
+ status: () => Promise<{ id: string; status: 'running' | 'failed' | 'expired' | 'ended'; startedAt: string; minutes: number; proxyMb: number; captchas: number; credits: number; expiresAt: string; }>;
891
+ close: () => Promise<{ minutes: number; proxyMb: number; captchas: number; creditsUsed: number; recordingUrl?: string | undefined; }>;
892
+ }
893
+ ```
894
+
895
+ 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`.
896
+
897
+ ### `ChatResult`
898
+
899
+ ```ts
900
+ type ChatResult = {
901
+ id: string;
902
+ model: string;
903
+ text: string;
904
+ toolCalls: ToolCall[];
905
+ finishReason: string | null;
906
+ usage: ChatUsage;
907
+ raw: unknown;
908
+ }
909
+ ```
910
+
911
+ ### `ChatStream`
912
+
913
+ ```ts
914
+ type ChatStream = {
915
+ raw: ReadableStream<Uint8Array<ArrayBufferLike>>;
916
+ text: () => AsyncIterable<string>;
917
+ result: () => Promise<ChatResult>;
918
+ }
919
+ ```
920
+
921
+ ### `D1Database`
922
+
923
+ ```ts
924
+ type D1Database = {
925
+ prepare: (sql: string) => D1PreparedStatement;
926
+ batch: <T = unknown>(statements: D1PreparedStatement[]) => Promise<D1Result<T>[]>;
927
+ exec: (sql: string) => Promise<D1ExecResult>;
928
+ dump: () => Promise<ArrayBuffer>;
929
+ withSession: (constraintOrBookmark?: string | undefined) => D1DatabaseSession;
930
+ }
931
+ ```
932
+
933
+ ### `LogsQuery`
934
+
935
+ ```ts
936
+ type LogsQuery = {
937
+ limit?: number;
938
+ env?: 'dev' | 'live';
939
+ requestId?: string;
940
+ status?: string;
941
+ to?: string;
942
+ from?: string;
943
+ source?: 'live' | 'auto' | 'buffer';
944
+ level?: 'error' | 'log' | 'debug' | 'info' | 'warn';
945
+ q?: string;
946
+ path?: string;
947
+ }
948
+ ```
949
+
950
+ ### `RealtimeChannelOptions`
951
+
952
+ ```ts
953
+ type RealtimeChannelOptions = {
954
+ /** The app's route that mints the ticket; it receives `{ room }` and answers `{ url }` or `{ data: { url } }`. */
955
+ ticketUrl?: string;
956
+ /** Or mint the ticket yourself. */
957
+ getTicket?: ((room: string) => Promise<{ url: string; }>);
958
+ /** Announce this connection's presence with this metadata (name, colour…); `others` lists everyone else's. */
959
+ presence?: M;
960
+ /** Messages kept in memory, newest last (default 100). */
961
+ keep?: number;
962
+ /** Tests only. */
963
+ WebSocket?: { new (url: string | URL, protocols?: string | string[] | undefined): WebSocket; prototype: WebSocket; readonly CONNECTING: 0; readonly OPEN: 1; readonly CLOSING: 2; readonly CLOSED: 3; };
964
+ }
965
+ ```
966
+
967
+ ### `ScanDocumentResult`
968
+
969
+ ```ts
970
+ type ScanDocumentResult = {
971
+ data: Record<string, unknown> | Record<string, unknown>[];
972
+ metadata: { usageUnits: number; exactUsageUnits: number; pages: number; provider: string; credits: number; };
973
+ }
974
+ ```
975
+
976
+ ### `SiteAnalyticsQuery`
977
+
978
+ ```ts
979
+ type SiteAnalyticsQuery = {
980
+ /** ISO; default the last 7 days. */
981
+ from?: string;
982
+ to?: string;
983
+ /** `minute` only within the last 30 minutes. */
984
+ granularity?: 'day' | 'hour' | 'minute';
985
+ /** Up to 4. */
986
+ metric?: 'uniques' | 'bytes' | 'errors' | 'page_views' | 'hits' | 'ttfb_p50' | 'ttfb_p95' | ('uniques' | 'bytes' | 'errors' | 'page_views' | 'hits' | 'ttfb_p50' | 'ttfb_p95')[];
987
+ /** Omit for a time series (`series`); set for a top-N (`top`). */
988
+ dimension?: 'browser' | 'country' | 'status' | 'device' | 'path' | 'hostname' | 'os' | 'referrer';
989
+ /** Top-N, ≤ 100. */
990
+ limit?: number;
991
+ bots?: 'exclude' | 'include' | 'only';
992
+ /** `dev` = the preview host, `live` = the published and custom hosts; omitted = both. */
993
+ env?: 'dev' | 'live';
994
+ }
995
+ ```
996
+
997
+ ### `TotalumAiOptions`
998
+
999
+ ```ts
1000
+ type TotalumAiOptions = {
1001
+ /** The exact-OpenRouter gateway `gatewayConfig()` returns; default `TOTALUM_AI_BASE_URL`, else `https://ai.totalum.app/api/v1`. */
1002
+ aiBaseUrl?: string;
1003
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
1004
+ key?: string;
1005
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
1006
+ apiUrl?: string;
1007
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
1008
+ env?: 'dev' | 'live';
1009
+ }
1010
+ ```
1011
+
1012
+ ### `TotalumClientOptions`
1013
+
1014
+ ```ts
1015
+ type TotalumClientOptions = {
1016
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
1017
+ key?: string;
1018
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
1019
+ apiUrl?: string;
1020
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
1021
+ env?: 'dev' | 'live';
1022
+ }
1023
+ ```
1024
+
1025
+ ### `TotalumD1Options`
1026
+
1027
+ ```ts
1028
+ type TotalumD1Options = {
1029
+ /** `'migrate'` (scripts/migrate.ts only) sends `x-totalum-migrate: 1` and enables `exec()`; default `'query'`. */
1030
+ mode?: 'query' | 'migrate';
1031
+ /** Migrate mode only: sends `x-totalum-migrate-destructive: 1`. */
1032
+ destructive?: boolean;
1033
+ /** An explicit binding wins over detection (plain Workers: `env.TOTALUM_DB`; tests: a Miniflare D1). */
1034
+ binding?: D1Database;
1035
+ /** `'https'` forces the HTTPS path even inside a Worker (the conformance corpus); default `'auto'`. */
1036
+ transport?: 'auto' | 'https';
1037
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
1038
+ key?: string;
1039
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
1040
+ apiUrl?: string;
1041
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
1042
+ env?: 'dev' | 'live';
1043
+ }
1044
+ ```
1045
+
1046
+ ### `TotalumFilesOptions`
1047
+
1048
+ ```ts
1049
+ type TotalumFilesOptions = {
1050
+ /** The public files host; default `TOTALUM_FILES_URL`, else `https://files.totalum-project.com`. */
1051
+ filesUrl?: string;
1052
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
1053
+ key?: string;
1054
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
1055
+ apiUrl?: string;
1056
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
1057
+ env?: 'dev' | 'live';
1058
+ }
1059
+ ```
1060
+
1061
+ ### `TotalumOptions`
1062
+
1063
+ ```ts
1064
+ type TotalumOptions = {
1065
+ /** The exact-OpenRouter gateway `gatewayConfig()` returns; default `TOTALUM_AI_BASE_URL`, else `https://ai.totalum.app/api/v1`. */
1066
+ aiBaseUrl?: string;
1067
+ /** Project key `tlm_pk_…`; default `TOTALUM_PROJECT_KEY`. Server-side only. */
1068
+ key?: string;
1069
+ /** Default `TOTALUM_SDK_API_URL`, else `https://sdk-api.totalum.app`. */
1070
+ apiUrl?: string;
1071
+ /** Sent as `x-totalum-env` on every call (the database it targets, and dev vs live usage); default `TOTALUM_ENV`, else `live`. */
1072
+ env?: 'dev' | 'live';
1073
+ /** The public files host; default `TOTALUM_FILES_URL`, else `https://files.totalum-project.com`. */
1074
+ filesUrl?: string;
1075
+ }
1076
+ ```
1077
+
1078
+ ### `UploadOptions`
1079
+
1080
+ ```ts
1081
+ type UploadOptions = {
1082
+ name?: string;
1083
+ contentType?: string;
1084
+ /** `true` stores the file under the private prefix: no public URL, read it through `getSignedUrl`. */
1085
+ private?: boolean;
1086
+ folder?: string;
1087
+ }
1088
+ ```