Docs
BlogHomeStart building

Totalum SDK


Legacy projects

If your project was created before 8 October 2026 or doesn't have the v2 engine flag, it runs the v1 Totalum engine, which is now legacy and doesn't have some of the features. See the legacy docs.

totalum-sdk is the package every Totalum v2 app uses for Totalum's built-in features: the project's database (totalum-sdk/d1, used through Drizzle), file storage, e-mail, AI, payments, real-time rooms, scheduled jobs, vector search, web scraping, a cloud browser, the user's connected accounts and more. Every call goes over HTTPS to the Totalum API with the project key, so it works the same in the preview, the published app (Cloudflare Workers), the coding agent's sandbox and a laptop. Never add a third-party SDK or provider key for something listed here.

The whole reference as one Markdown file, for a coding agent: /totalum-sdk.md.

#Contents

ModuleImportWhat it is for
The totalum objecttotalum-sdkThe default totalum object and createTotalum() give you every namespace on one object: totalum.files, totalum.ai, totalum.email and the rest.
Database drivertotalum-sdk/d1The project's SQL database (Cloudflare D1, SQLite), used through Drizzle: drizzle(totalumD1()).
Files & Storagetotalum-sdk/filesStore and serve your app's files (uploads, images, generated PDFs).
Paymentstotalum-sdk/paymentsTake payments and subscriptions with Stripe on the project owner's own Stripe account (Stripe Connect), without handling card data: create a hosted Checkout, send the buyer to its url, and read the result back.
Webhookstotalum-sdk/webhooksReceive Totalum's signed events (payments, e-mail delivery, browser programs, connected-account events, credits exhausted) and check that they really come from Totalum.
Web Scraping & Searchtotalum-sdk/webRead the web from your app: one page as Markdown or HTML (scrape), a web search (search), every URL of a site (map), a whole site in the background (crawl) and screenshots.
PDFtotalum-sdk/pdfTurn HTML or a web page into a PDF stored in the project's files: invoices, tickets, reports.
Document Scan / OCRtotalum-sdk/scanRead documents and images: extract the fields you describe (an invoice's number, date and total) as JSON with document(), or get the plain text of every page with ocr().
Vector Searchtotalum-sdk/vectorsSemantic search over your own content: store texts or images as vectors with metadata (upsert), then find the closest ones to a question, a text or an image (query).
Connected Accountstotalum-sdk/connectionsLet your app's users connect their own accounts of about 1,500 apps — Google Calendar, Gmail, Google Drive, Outlook, Slack, HubSpot, Notion, GitHub, Stripe, Airtable and more — and act on them from your server: create a calendar event, send an e-mail from their Gmail, read their files, or receive their events.
Speechtotalum-sdk/speechSpeech to text (transcribe) and text to speech (synthesize): transcribe a recording or a voice note, read a text aloud, store the audio as a project file.
AItotalum-sdk/aiAI from your server without any provider account: chat completions (streamed or not), structured JSON, a label out of a list, embeddings, image generation and editing, video generation and image description.
Emailtotalum-sdk/emailSend transactional e-mail (sign-up confirmations, receipts, notifications) from the project's own sender, and check whether it was delivered.
Cron Jobstotalum-sdk/cronRun a route of your own app on a schedule: every night at 8:00, every 15 minutes, the first day of the month.
SEO & IndexNowtotalum-sdk/seoTell search engines that pages of your custom domain changed (IndexNow), so new and edited pages are indexed in minutes instead of days.
Browser Automationtotalum-sdk/browserA real Chrome in the cloud, driven over HTTPS from your server, so it works inside the published app: open pages, click, type, log in, fill forms, download files, take screenshots and PDFs, extract data.
Realtimetotalum-sdk/realtimeLive updates between the people using your app: chat, notifications, presence ("who is online"), collaborative editing, live dashboards and games.
Logstotalum-sdk/logsRead your app's own server logs: the requests the published app (env: 'live') or the preview ('dev') handled, with their console lines, status codes and errors.
Site Analyticstotalum-sdk/analyticsYour site's own traffic: page views, visits, unique visitors, errors, bytes and response times, as a time series or a top list (top pages, referrers, countries, devices, browsers).
React Realtime Hookstotalum-sdk/reactThe browser side of realtime rooms for React client components: useRealtimeChannel(room) connects to a room, keeps the messages received, shows who else is present, and reconnects by itself (every deploy drops sockets).

#Quick start

  1. Install the package (it is already installed in every Totalum project):

    sh
    npm install --save-exact totalum-sdk
  2. Give the server its project key. Totalum sets TOTALUM_PROJECT_KEY (tlm_pk_…) on the preview, the published app and the sandbox; on your own machine put it in .env.local. It is a secret: use it only in server code (route handlers, server actions, cron routes, scripts), never in a NEXT_PUBLIC_ variable or a client component.

  3. Call a namespace on the default totalum instance:

    ts
    // src/app/api/welcome/route.ts
    import { totalum } from 'totalum-sdk';
    
    export async function POST(request: Request) {
      const { email } = (await request.json()) as { email: string };
      const sent = await totalum.email.send({
        to: email,
        subject: 'Welcome to Acme',
        html: '<p>Thanks for signing up.</p>',
      });
      return Response.json({ id: sent.id, credits: sent.usage.credits });
    }

    sent is:

    json
    {
      "success": true,
      "message": "Email sent successfully",
      "messageId": "01a12c0c-9e5f-74ea-a128-a72d3fdd47ae",
      "id": "em_01M4P0S77M6XCM69SYZWP1XME9",
      "status": "queued",
      "usage": { "credits": 0.0515 }
    }
  4. Read the database with Drizzle on totalumD1():

    ts
    import { drizzle } from 'drizzle-orm/d1';
    import { totalumD1 } from 'totalum-sdk/d1';
    import { users } from '@/db/schema';
    
    const db = drizzle(totalumD1());
    const rows = await db.select().from(users).limit(10);

Paid calls return what they cost in usage.credits (Totalum credits). Failures throw TotalumError: see Errors.

#Install and configure

sh
npm install --save-exact totalum-sdk

Server-side only (route handlers, server actions, cron handlers, npx tsx scripts/<name>.ts). Every namespace reads the same environment at call time, never at import; an option of the same name wins:

VariableOptionMeaning
TOTALUM_PROJECT_KEYkeyThe project key tlm_pk_…. Never NEXT_PUBLIC_. Missing → SDK_NOT_CONFIGURED.
TOTALUM_SDK_API_URLapiUrlDefault https://sdk-api.totalum.app.
TOTALUM_ENVenvdev or live (default), sent as x-totalum-env: the database totalum-sdk/d1 targets over HTTPS, and dev vs live usage.
TOTALUM_FILES_URLfilesUrlThe public files host of files.url().
TOTALUM_AI_BASE_URLaiBaseUrlThe OpenAI-compatible AI gateway ai.gatewayConfig() returns.
TOTALUM_APP_KEYkeySet by Totalum in the sandbox only: the deployed app's own key, used before TOTALUM_PROJECT_KEY by every namespace but the database, so the agent's checks have the app's permissions.
TOTALUM_WEBHOOK_SECRETargumentThe secret webhooks.verify checks Totalum-Signature with. Totalum sets it on the preview, the published site and the sandbox, and a rotation reaches them at once: never set it yourself.
ts
import { totalum } from 'totalum-sdk';            // or one namespace: import { totalumFiles } from 'totalum-sdk/files';
const file = await totalum.files.upload(blob, { name: 'avatar.png' });

#Errors

Every failure throws TotalumError (isTotalumError(e)) with errorCode (frozen), status, details and requestId; TotalumD1Error (message shaped like a native D1 error) and TotalumWebhookError extend it. A capped or disabled feature (FEATURE_LIMIT_REACHED 429, FEATURE_DISABLED 403) refuses only its own namespace; at a zero balance paid calls answer INSUFFICIENT_CREDITS 402. A project makes at most 100 built-in calls per second (AI, e-mail, file uploads, web, scan, PDF, speech, vectors, browser, realtime, payments): above it the Totalum API answers RATE_LIMITED 429 with Retry-After, which the SDK retries twice (with jitter) before throwing — handle it, and never fan out hundreds of calls at once (batch, queue or await them in small groups).

ts
import { isTotalumError, totalum } from 'totalum-sdk';

try {
  await totalum.files.get('p/my-app/01M4P0PZXJ0DPQM7R20QVZ0EKC.txt');
} catch (e) {
  if (isTotalumError(e) && e.errorCode === 'FILE_NOT_FOUND') return null;
  throw e; // logs as: TotalumError [CODE]: message
}

These are the errors every call can throw; each method lists its own below it.

CodeHTTPMeaning
SDK_NOT_CONFIGURED—No project key: set TOTALUM_PROJECT_KEY (server-side) or pass { key }. Thrown before any request is sent.
NETWORK_ERROR0The Totalum API could not be reached (DNS, TLS, connection reset). cause holds the original error.
RESPONSE_PARSE_ERRORanyThe answer was not the JSON the SDK expects (a proxy or gateway page in between).
UNAUTHORIZED401The key is unknown or revoked.
LEGACY_KEY_NOT_SUPPORTED401An account key (tlm_sk_…) or a legacy key was used: v2 projects need a project key tlm_pk_….
SANDBOX_KEY_EXPIRED401The coding agent's temporary sandbox key expired (only inside Totalum's sandbox).
FORBIDDEN_SCOPE403The key lacks the scope this namespace needs (for example email, ai, files:write).
VALIDATION_ERROR400The input does not match what the method accepts; details names the fields.
PAYLOAD_TOO_LARGE413The request body is over 26 MB.
RATE_LIMITED429More than the project's built-in calls per second (100). The SDK already waited and retried twice; details.retryAfterMs says how long to wait.
RATE_LIMIT_EXCEEDED429A per-visitor or per-feature limit that lasts up to a minute; details says which and when to retry.
INSUFFICIENT_CREDITS402The account has no credits left for a paid call. Nothing was charged.
FEATURE_LIMIT_REACHED429The plan's limit for this feature is used up for the period; only this namespace is refused.
FEATURE_DISABLED403The project owner turned this feature off; only this namespace is refused.
AI_MEDIA_PAUSED_THIS_HOUR429The project used a lot of credits this hour, so image, video and speech AI pause until the hour ends (details.resetsAt). Text AI keeps working.
PROJECT_PAUSED_RUNAWAY429The project was paused because its usage passed the safety threshold.
PROJECT_PAUSED_BALANCE402The project is paused because the account balance is negative.
PROJECT_SUSPENDED402The project is suspended because of a negative credit balance.
PROJECT_PAUSED_BY_USER402The owner paused the project; it works again once resumed.
PROJECT_HIBERNATED410The project is hibernated; the owner reactivates it in Totalum (free, about a minute).
PROJECT_DELETED410The project was deleted.
PROVIDER_UNAVAILABLE503The service behind this feature is unavailable right now. Retry later.
ENGINE_UNAVAILABLE500An unexpected error on Totalum's side; details.errorId identifies it for support.

Database failures read D1_ERROR: … on every connection, whichever engine holds the project's database: Network connection lost. (a transient failure), D1 DB is overloaded. … (too many statements at once: send fewer, or group writes in db.batch), D1 DB exceeded its CPU time limit and was reset. (one statement ran too long: add an index or split it), Memory limit exceeded before EOF. (a result too big for the Worker: select fewer rows or columns, paginate), statement too long: SQLITE_TOOBIG. The driver repeats a statement up to twice (after ≈ 0.1 s and ≈ 0.4 s) only when that is safe: a read (SELECT, or a batch of them) after a transient failure, and a write only when the failure says the statement never reached the database. A write that may have been applied, an overloaded database, a limit and a SQL error are thrown at once — make a write you retry yourself idempotent (INSERT … ON CONFLICT DO NOTHING, a unique key).

Node-only methods throw NODE_ONLY inside a Worker (the preview and the published app both run on Cloudflare Workers) and name the HTTPS replacement: ai.video.wait().

All 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.

All server codes: SERVICE_UNAUTHORIZED, SERVICE_REPLAY, ACTOR_MISMATCH, PAYLOAD_TOO_LARGE, VALIDATION_ERROR, PROJECT_NOT_FOUND, PROJECT_NOT_READY, OPERATION_IN_PROGRESS, AGENT_RUNNING, PROJECT_MOVED, OBJECT_MIGRATING, INDEX_SHARD_UNAVAILABLE, RATE_LIMIT_EXCEEDED, RATE_LIMITED, PROJECT_PAUSED_RUNAWAY, AI_MEDIA_PAUSED_THIS_HOUR, 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, VECTORS_LIMIT_REACHED, CONNECTION_REQUIRED, CONNECTION_ACTION_FAILED, TOOLKIT_NOT_AVAILABLE, TOOLKIT_NEEDS_OWN_APP, AGENT_ALREADY_RUNNING, IMPORT_IN_PROGRESS, MIGRATION_TOO_LARGE, MIGRATION_START_FAILED, TOO_MANY_RUN_REQUESTS, PROMPT_SECURITY_VIOLATION, NO_PROCESS_RUNNING, RUN_NOT_FOUND, KEY_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, DESTRUCTIVE_MIGRATION_UNDONE_BY_RESTORE, DEV_DATABASE_NOT_FOUND, DATABASE_ROLE_NOT_FOUND, BOOKMARK_NOT_FOUND, BACKUP_NOT_FOUND, BACKUP_NOT_DELETABLE, BACKUP_RATE_LIMITED, BACKUP_TOO_LARGE_FOR_IMPORT, PRE_RESTORE_BACKUP_FAILED, RESTORE_VERIFY_FAILED, RESTORE_BEFORE_LIVE_MIGRATION, 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, RECORD_KEY_REQUIRED, AMBIGUOUS_RECORD_ID, 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, RELEASE_BELOW_MIN_SAFE_VERSION, 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, TURSO_STORAGE_INSUFFICIENT, 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_RATE_LIMITED, MOBILE_BUILD_QUEUE_TIMEOUT, MOBILE_BUILD_NOT_CANCELLABLE, MOBILE_BUILD_NOT_FOUND, MOBILE_BUILD_NOT_READY, MOBILE_REQUIRES_PUBLISHED_PROJECT, DOWNLOAD_EXPIRED, PROCESS_IN_PROGRESS, SANDBOX_NOT_RUNNING, MOBILE_LAYER_MISSING, MOBILE_BUILD_FAILED, MOBILE_ARTIFACT_INVALID, SIGNING_FINGERPRINT_MISMATCH, AM_RESTARTED, MOBILE_BUILD_NOT_SIGNED, STORE_NOT_CONFIGURED, STORE_CREDENTIALS_INVALID, STORE_APP_NOT_FOUND, STORE_UPLOAD_RUNNING, STORE_UPLOAD_LIMIT_REACHED, STORE_UPLOAD_NOT_FOUND, STORE_UPLOAD_FAILED, PLAY_FIRST_UPLOAD_MANUAL, STORE_PROCESSING_TIMEOUT, 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, CONCURRENCY_QUEUE_TIMEOUT, CONCURRENCY_QUEUE_FULL, PROVIDER_TIMEOUT, 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, LIVE_CRON_READ_ONLY, 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, PAYMENTS_PUBLISH_FIRST, PAYMENTS_ACCOUNT_DISCONNECTED, 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, DOMAIN_PRICE_OVER_CAP, 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, PROJECT_HAS_CUSTOM_DOMAIN, 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.

#Versions and deprecations

Semantic versioning from 1.0.0: a minor release only adds, so an app written against 1.a runs unchanged on every later 1.b. A replaced name keeps working for at least one major version: it is marked Deprecated below and logs one console.warn naming its replacement the first time it runs — switch to the replacement when you touch that code. The package's CHANGELOG.md lists every change.

#totalum-sdk

The default totalum object and createTotalum() give you every namespace on one object: totalum.files, totalum.ai, totalum.email and the rest. Import it in server code and call the namespace you need; nothing is read or sent until the first call. Every subpath (totalum-sdk/files, totalum-sdk/ai, …) also exports its own factory (totalumFiles(), totalumAi(), …) for a smaller bundle, and the root re-exports all of them.

ts
import { totalum } from 'totalum-sdk';
const page = await totalum.files.list({ limit: 20 });
ExportWhat it does
createTotalumCreates a totalum object with your own options — another project key, the dev environment, a test API URL.
totalumThe default instance, configured from the environment (TOTALUM_PROJECT_KEY, TOTALUM_SDK_API_URL, TOTALUM_ENV): import it and call any namespace.
TotalumThe type of totalum and of createTotalum()'s result: one property per namespace.
TotalumOptionsThe options of createTotalum(): every namespace's options in one object (each falls back to its env var).

#createTotalum

ts
createTotalum(options?: TotalumOptions): Totalum

Creates a totalum object with your own options — another project key, the dev environment, a test API URL. Every integration namespace is on it, each built on first access with the same options — no I/O and no env read until a method is called. The database is totalumD1() from totalum-sdk/d1, not a namespace.

Parameters

NameTypeRequiredDescription
optionsTotalumOptionsnoEvery namespace's options: key, apiUrl, env, filesUrl, aiBaseUrl; each falls back to its environment variable.
options.aiBaseUrlstringnoThe OpenAI-compatible AI gateway gatewayConfig() returns; default TOTALUM_AI_BASE_URL, else https://ai.totalum.app/api/v1.
options.keystringnoProject key tlm_pk_…; default TOTALUM_PROJECT_KEY. Server-side only.
options.apiUrlstringnoThe Totalum API's URL: default TOTALUM_SDK_API_URL, else https://sdk-api.totalum.app.
options.env'dev' | 'live'noSent as x-totalum-env on every call (the database it targets, and dev vs live usage); default TOTALUM_ENV, else live.
options.filesUrlstringnoThe public files host files.url() uses; default TOTALUM_FILES_URL, else https://files.totalum-project.com.

Returns Totalum — An object with every namespace (files, ai, email, …), like totalum.

Example

ts
import { createTotalum } from 'totalum-sdk';

const devTotalum = createTotalum({ env: 'dev' });
await devTotalum.email.send({ to: 'ana@example.com', subject: 'Test', html: '<p>Test</p>' });

#totalum

ts
const totalum: Totalum

The default instance, configured from the environment (TOTALUM_PROJECT_KEY, TOTALUM_SDK_API_URL, TOTALUM_ENV): import it and call any namespace. Use it in server code only.

Example

ts
import { totalum } from 'totalum-sdk';

const page = await totalum.files.list({ limit: 10 });

#Totalum type

The type of totalum and of createTotalum()'s result: one property per namespace.

FieldTypeAlways presentDescription
aiTotalumAiyesAI from your server without any provider account: chat completions (streamed or not), structured JSON, a label out of a list, embeddings, image generation and editing, video generation and image description. See AI.
analyticsTotalumAnalyticsyesYour site's own traffic: page views, visits, unique visitors, errors, bytes and response times, as a time series or a top list (top pages, referrers, countries, devices, browsers). See Site Analytics.
browserTotalumBrowseryesA real Chrome in the cloud, driven over HTTPS from your server, so it works inside the published app: open pages, click, type, log in, fill forms, download files, take screenshots and PDFs, extract data. See Browser Automation.
connectionsTotalumConnectionsyesLet your app's users connect their own accounts of about 1,500 apps — Google Calendar, Gmail, Google Drive, Outlook, Slack, HubSpot, Notion, GitHub, Stripe, Airtable and more — and act on them from your server: create a calendar event, send an e-mail from their Gmail, read their files, or receive their events. See Connected Accounts.
cronTotalumCronyesRun a route of your own app on a schedule: every night at 8:00, every 15 minutes, the first day of the month. See Cron Jobs.
emailTotalumEmailyesSend transactional e-mail (sign-up confirmations, receipts, notifications) from the project's own sender, and check whether it was delivered. See Email.
filesTotalumFilesyesStore and serve your app's files (uploads, images, generated PDFs). See Files & Storage.
logsTotalumLogsyesRead your app's own server logs: the requests the published app (env: 'live') or the preview ('dev') handled, with their console lines, status codes and errors. See Logs.
paymentsTotalumPaymentsyesTake payments and subscriptions with Stripe on the project owner's own Stripe account (Stripe Connect), without handling card data: create a hosted Checkout, send the buyer to its url, and read the result back. See Payments.
pdfTotalumPdfyesTurn HTML or a web page into a PDF stored in the project's files: invoices, tickets, reports. See PDF.
realtimeTotalumRealtimeyesLive updates between the people using your app: chat, notifications, presence ("who is online"), collaborative editing, live dashboards and games. See Realtime.
scanTotalumScanyesRead documents and images: extract the fields you describe (an invoice's number, date and total) as JSON with document(), or get the plain text of every page with ocr(). See Document Scan / OCR.
seoTotalumSeoyesTell search engines that pages of your custom domain changed (IndexNow), so new and edited pages are indexed in minutes instead of days. See SEO & IndexNow.
speechTotalumSpeechyesSpeech to text (transcribe) and text to speech (synthesize): transcribe a recording or a voice note, read a text aloud, store the audio as a project file. See Speech.
vectorsTotalumVectorsyesSemantic search over your own content: store texts or images as vectors with metadata (upsert), then find the closest ones to a question, a text or an image (query). See Vector Search.
webTotalumWebyesRead the web from your app: one page as Markdown or HTML (scrape), a web search (search), every URL of a site (map), a whole site in the background (crawl) and screenshots. See Web Scraping & Search.
webhooksTotalumWebhooksyesReceive Totalum's signed events (payments, e-mail delivery, browser programs, connected-account events, credits exhausted) and check that they really come from Totalum. See Webhooks.

#TotalumOptions

The options of createTotalum(): every namespace's options in one object (each falls back to its env var).

NameTypeRequiredDescription
aiBaseUrlstringnoThe OpenAI-compatible AI gateway gatewayConfig() returns; default TOTALUM_AI_BASE_URL, else https://ai.totalum.app/api/v1.
keystringnoProject key tlm_pk_…; default TOTALUM_PROJECT_KEY. Server-side only.
apiUrlstringnoThe Totalum API's URL: default TOTALUM_SDK_API_URL, else https://sdk-api.totalum.app.
env'dev' | 'live'noSent as x-totalum-env on every call (the database it targets, and dev vs live usage); default TOTALUM_ENV, else live.
filesUrlstringnoThe public files host files.url() uses; default TOTALUM_FILES_URL, else https://files.totalum-project.com.