@norbix.ai/ts
v4.21.0
Published
Official TypeScript SDK for Norbix — one client for both API and Hub. Works in Node and the browser.
Readme
What is Norbix?
Norbix is a Backend-as-a-Service built for the agentic era. One platform exposes everything an app needs — auth, database, file storage, email, push, payments, code functions, logging — as both a typed SDK and an MCP server, so a developer and their agent can call the same backend the same way.
It runs three ways: as a fully managed cloud at cloud.norbix.ai (zero DevOps), self-hosted on your own machine or server, or as enterprise in your VPC. Same modules, same APIs, same SDKs — pick the runway, not the runtime.
This repo is the TypeScript SDK — one package on npm (@norbix.ai/ts) that exposes both the runtime API and the configuration Hub as separate import paths so you only ship the surface you actually use. Plus a third surface, the Norbix MCP server, that exposes the same modules to your IDE. Works in Node 18+ and modern browsers.
Two surfaces in one package — API or Hub?
Norbix has two surfaces, and each is its own import path. The npm package is one (@norbix.ai/ts), but tree-shaking is per-subpath — pick the one that matches what your code is doing. Most apps need only the API in production code; the Hub is for admin tooling, internal dashboards, and infrastructure-as-code.
| | @norbix.ai/ts/api | @norbix.ai/ts/hub |
| -------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| Surface | Runtime — what your app does at request time | Control plane — how Norbix is configured |
| Scope | Project-scoped data | Project & account configuration |
| Default base URL | https://api.norbix.ai | https://hub.norbix.ai |
| Typical caller | Your app's backend, your mobile app, your AI agent | Your admin UI, your CLI, your IaC scripts |
| Examples | Sign in users · query collections · send transactional email · charge a card · invoke a function · run an AI chat | Define schemas · configure an SMTP provider · invite a teammate · open a billing portal · set up a webhook |
# One install — pick the import path you need
npm install @norbix.ai/ts// App / runtime code
import { Norbix } from '@norbix.ai/ts';
// Both surfaces are reachable from one client:
norbix.api.database.find({ collectionName: 'orders' });
norbix.hub.database.getAllDatabaseSchemas();Both surfaces share the same authentication model, the same error model, and the same configuration shape. Want a third option that's not a package at all? See Norbix MCP — same modules, exposed to your IDE.
Getting started
The Getting Started examples below use the API surface because that's what most apps need first. The Hub follows the same shape — see Hub example below.
Install
npm install @norbix.ai/tsThree real things in 30 lines
The examples below assume an API key from the Norbix Cloud Dashboard and a project ID. The same code works against self-hosted and enterprise deployments — only the base URL changes (see Authentication & configuration).
1. Register a user
import { Norbix } from '@norbix.ai/ts';
const norbix = new Norbix({
apiKey: process.env.NORBIX_API_KEY,
projectId: 'proj_123',
});
const user = await norbix.api.membership.saveEmailUser({
email: '[email protected]',
password: 'correct-horse-battery-staple',
firstName: 'Ada',
lastName: 'Lovelace',
});
console.log(user.id);2. Insert a record
const order = await norbix.api.database.insertOne({
collectionName: 'orders',
document: {
userId: user.id,
amount: 4900,
currency: 'EUR',
status: 'pending',
items: [
{ sku: 'NBX-T-SHIRT', qty: 1, price: 2900 },
{ sku: 'NBX-MUG', qty: 1, price: 2000 },
],
createdAt: new Date().toISOString(),
},
});
console.log(order.id);That's the loop — auth and data — using two real modules behind one client. The same modules are exposed as MCP tools, so any MCP-native agent can drive the same flow. Email/push/payments and other configurable surfaces live on the Hub — see Hub example.
Want it in your language? See the Norbix SDKs family below — every SDK exposes the same module names and method shapes.
Authentication & configuration
Both surfaces share the same configuration shape. The only difference is the default base URL: the API surface points at https://api.norbix.ai, the Hub surface points at https://hub.norbix.ai.
Auth modes
The SDK supports two auth modes. Both are sent as Authorization: Bearer <token>. If both are configured, the JWT wins. With neither configured, the SDK throws NORBIX_NOT_AUTHENTICATED on the first call.
| Mode | When to use | How |
| -------------- | ---------------------------------------------- | ----------------------------------------------------------------------------- |
| API key | Server-to-server, scripts, scheduled jobs, IaC | apiKey: '...' or NORBIX_API_KEY env |
| JWT bearer | Logged-in user session | bearerToken: '...', NORBIX_BEARER_TOKEN env, or await norbix.login(...) |
// Service mode — long-lived API key
const norbix = new Norbix({ apiKey: '<api_key>', projectId: 'proj_123' });
// User mode — exchange credentials for a JWT
const norbix = new Norbix({ projectId: 'proj_123' });
await norbix.login({ userName: '[email protected]', password: 'secret' });Default base URLs
When you install the package, no base URL is required — the SDK points at Norbix Cloud by default.
| Surface | Default base URL |
| ---------------- | ----------------------- |
| norbix.api | https://api.norbix.ai |
| norbix.hub | https://hub.norbix.ai |
Overriding the base URL
Override the base URL when you self-host Norbix on your own infrastructure or run it locally. Pass it as a constructor option, or set the corresponding env var. Two real-world examples:
// Self-hosted on your company domain
const norbix = new Norbix({
apiKey: process.env.NORBIX_API_KEY,
projectId: 'proj_123',
apiBaseUrl: 'https://api.norbix.isidos.lt',
hubBaseUrl: 'https://hub.norbix.isidos.lt',
});
// Local development against a Norbix instance on localhost
const norbix = new Norbix({
apiKey: 'sk_dev_local',
projectId: 'proj_dev',
apiBaseUrl: 'http://localhost:5000',
hubBaseUrl: 'http://localhost:5001',
});Or via environment variables (no code change required):
NORBIX_API_KEY=sk_live_...
NORBIX_PROJECT_ID=proj_123
NORBIX_ACCOUNT_ID=acc_456 # optional, sent as the norbix-account-id header
NORBIX_REGION=nb-eu-germany # optional, pins requests to a Norbix region (see Regions)
NORBIX_API_URL=https://api.norbix.ai # override for self-hosted, e.g. https://api.norbix.isidos.lt
NORBIX_HUB_URL=https://hub.norbix.ai # override for self-hosted, e.g. https://hub.norbix.isidos.ltconst norbix = new Norbix(); // reads everything from env, including the overridden URLsThe SDK does not load .env files itself — use node --env-file=.env (Node 20+) or import 'dotenv/config' in your app's bootstrap. In the browser (where process doesn't exist) env loading is a silent no-op.
Regions
Norbix Cloud is multi-region. A region is identified by a region code such as nb-eu-germany, and the SDK lets you pin requests to one in three ways — constructor option, environment variable, or at runtime:
// 1. Constructor option
const norbix = new Norbix({
apiKey: process.env.NORBIX_API_KEY,
projectId: 'proj_123',
region: 'nb-eu-germany',
});
// 2. NORBIX_REGION env var — picked up when the option is not set
// NORBIX_REGION=nb-eu-germany
const norbix = new Norbix();
// 3. Switch at runtime
norbix.setRegion('nb-us-east');
norbix.getRegion(); // 'nb-us-east'
norbix.setRegion(undefined); // clear — back to no regionAnd a fourth way: every endpoint method accepts a per-call region override on its second argument, just like bearerToken and timeoutMs:
await norbix.api.database.find({ collectionName: 'orders' }, { region: 'nb-us-east' });
await norbix.hub.account.getProjects({}, { region: 'nb-us-east' });How a region affects the request. The resolved region (per-call override → client region → NORBIX_REGION) is sent as the nb-region header. There is no default region — when nothing is set, no header is sent and the backend routes to the project's primary region. Self-hosted deployments are unaffected: no region configured means requests are byte-identical to the pre-regions behavior.
Regional base URLs. When the client uses the SDK's built-in default base URLs, setting a client-level region also composes the regional URL by prefixing the region code as a subdomain — https://api.norbix.ai becomes https://nb-eu-germany.api.norbix.ai (and likewise for the Hub URL). setRegion(...) re-composes the URL, and setRegion(undefined) restores the defaults. Two rules to remember:
- A custom
baseUrl(orNORBIX_API_URL/NORBIX_HUB_URL) is never rewritten — with a region set, only thenb-regionheader is added. - A per-call
regionoverride affects the header only — it never changes the request URL.
Managing a project's regions. The Hub's regions module lists the regions available to the account and updates the set of regions a project spans (one primary + any additional):
// List available regions — each item carries { id, continent, name }
const { items } = await norbix.hub.regions.list();
// Change the project's primary region / the regions it spans
await norbix.hub.regions.updateProjectRegions({
projectId: 'proj_123',
primaryRegion: 'nb-eu-germany',
additionalRegions: ['nb-us-east'],
});hub.account.createProject accepts the same primaryRegion / additionalRegions fields, project DTOs report primaryRegion, additionalRegions, and the combined regions[], and the echo endpoint lists the regions a deployment exposes with their regional endpoints. Full reference: docs/hub/regions.md.
SSR / multi-tenant safe usage
For per-request scoping (different bearer tokens per request), pass the token as a per-call override on the second argument instead of mutating a shared singleton with setBearerToken(...):
await norbix.api.database.find(
{ collectionName: 'orders' },
{ bearerToken: requestUserToken, timeoutMs: 5_000 },
);Every generated endpoint method accepts the same { bearerToken?, timeoutMs?, env?, region? } options as its second argument.
Project vs account scope.
projectIdis required by the API surface.accountIdis optional: when set, the client sends it as thenorbix-account-idheader. Sign-up (hub.account.createAccount), accepting an invitation (hub.account.createTeamMemberFromInvitation), listing regions (hub.account.getAccountRegions/hub.regions.list) and verifying the account (hub.account.verifyAccount, which takesaccountIdin its request) need no token and noaccountId— they are sent with noAuthorizationheader.
Modules
The SDK is a thin client over the Norbix gateway. Every module below resolves to a typed namespace on the client and an MCP tool group, so the same surface is reachable from code or from an agent. Per-module reference pages live in /docs and on docs.norbix.ai.
norbix.api — runtime, project-scoped
Default base URL: https://api.norbix.ai. 8 modules · 66 endpoints.
| Module | Purpose | Reference |
| ---------------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| 🔐 auth | Sign-in flows. Most apps prefer norbix.login(...). | docs/api/auth.md |
| 👤 membership | User CRUD, registration, login, passkeys, email verification, magic links, roles, preferences | docs/api/membership.md |
| 🗄️ database | Collections, find/insert/update/delete, aggregate, taxonomies | docs/api/database.md |
| 📁 files | Signed upload URLs, download, file info, file by id, listing, integration test | docs/api/files.md |
| 🔑 apikeys | List + regenerate per-environment API keys | docs/api/apikeys.md |
| 🪪 accessToken | Refresh-token exchange | docs/api/access_token.md |
| 🩺 echo | Gateway smoke check | docs/api/echo.md |
Email/push/SMS notifications, payments, and code execution are configured on the Hub surface and surfaced at runtime through integration triggers — they are not separate API modules. File storage now has its own
filesAPI module: it issues signed upload URLs so clients upload binary content directly to storage, never streaming bytes through the Norbix API.
The Database calls follow rules the gateway checks (bulk writes with an empty filter need allRecords: true, expandReferences for { id, display } references, nested documents and arrayFilters, the typed schema field DTOs, the error codes of each refusal) — see docs/database-rules.md.
norbix.hub — control plane, configuration
Default base URL: https://hub.norbix.ai. 18 modules · 315 endpoints.
| Module | Purpose | Reference |
| ------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------- |
| 🏢 account | Account profile, status, projects, regions, team, billing, verification | docs/hub/account.md |
| 🌍 regions | List available Norbix regions, update the regions a project spans | docs/hub/regions.md |
| 🗄️ database | Schemas, integrations, saved aggregates, taxonomies, triggers | docs/hub/database.md |
| 📁 files | File-storage integrations, triggers, module settings | docs/hub/files.md |
| 📧 notifications | Email, push & SMS templates, integrations, campaigns, contacts, devices | docs/hub/notifications.md |
| 📨 email | Email module switches | docs/hub/email.md |
| 💳 payments | Payment integrations, triggers, tests, module settings | docs/hub/payments.md |
| 🤖 ai | LLM and MCP integration configuration and tests | docs/hub/ai.md |
| 📊 logs | Logging integrations and module settings | docs/hub/logs.md |
| 👥 membership | Roles, policies, users, preferences, integrations, triggers | docs/hub/membership.md |
| ⏰ scheduler | Scheduler module, tasks and their run history | docs/hub/scheduler.md |
| 🪝 webhooks | Webhook integrations, destinations, tests, module settings | docs/hub/webhooks.md |
| 📥 webhooks (receiver) | Verify & handle inbound Norbix webhook POSTs at your endpoint | docs/webhooks-receiver.md |
| ⚡ code | Code integrations (AWS Lambda, Azure, Google), functions, invoke, runs | docs/hub/code.md |
| ⚡ code (function side) | Parse the envelope your cloud function receives, call Norbix back | docs/code-functions.md |
| 🔐 auth | Hub-side sign-in flows | docs/hub/auth.md |
| 🔑 apikeys | List + regenerate Hub API keys | docs/hub/apikeys.md |
| 🪪 accessToken | Refresh-token exchange | docs/hub/access_token.md |
| 🩺 echo | Gateway smoke check | docs/hub/echo.md |
| 🛠️ internal | Internal helpers | docs/hub/internal.md |
| 📦 resources | Resolve resource references | docs/hub/resources.md |
| 🚦 triggers | Triggers that need attention (for example a missing provider) | docs/hub/triggers.md |
End-user AI chat (norbix.api.ai) and project AI settings (norbix.hub.ai, norbix.hub.account)
A signed-in project user (bearerToken from norbix.login) can talk to the
project's AI assistant. The turn call answers at once with a turnId; the
answer streams over SSE on the user's own channel ai-chat:{projectId}:{authId}.
const { isAvailable } = await norbix.api.ai.getEndUserChatAvailability();
const { id: sessionId } = await norbix.api.ai.createEndUserChatSession({ title: 'Help' });
const stream = norbix.aiChat({ authId }); // API host, this user's channel
stream.on('ai.chat.turn.token', (e) => process.stdout.write(String(e.payload?.text ?? '')));
stream.on('ai.chat.turn.completed', () => stream.close());
await stream.connect(); // rejects with code "AiChatChannelRefused" if the channel is not yours — no retry
await norbix.api.ai.startEndUserChatTurn({ sessionId, message: 'What can you do?' });Sessions, entries, feedback, attachments and memory: listEndUserChatSessions,
getEndUserChatEntries, setEndUserChatEntryFeedback, uploadEndUserChatAttachment,
listEndUserChatMemory, forgetEndUserChatMemory — see docs/api/ai.md.
Project owners configure the assistant and the providers on the Hub:
await norbix.hub.account.updateProjectAiSettings({ projectId, ...settings });
await norbix.hub.account.createProjectAiAssistant({
projectId,
name: 'Support bot',
instructions: '…',
});
const usage = await norbix.hub.account.getProjectAiUsage({ projectId }); // wallet usage
await norbix.hub.ai.saveEmbeddingIntegration({
provider: 'OpenAi',
model: 'text-embedding-3-small',
apiKey,
});
await norbix.hub.ai.setLlmIntegrationAsDefault({ id: llmIntegrationId });
await norbix.hub.account.setAdminPortalEnabled({ projectId, enabled: true });Full lists: docs/hub/ai.md, docs/hub/account.md.
Hub example
The Hub surface follows the same shape as the API surface — same constructor, same auth, same client. Use it from admin tooling, internal dashboards, or IaC scripts.
import { Norbix } from '@norbix.ai/ts';
const norbix = new Norbix({
apiKey: process.env.NORBIX_API_KEY,
accountId: 'acc_456',
});
// Define a database schema for a new collection
await norbix.hub.database.saveDatabaseSchema({
collectionName: 'orders',
fields: [
{ name: 'userId', type: 'string', required: true, indexed: true },
{ name: 'amount', type: 'integer', required: true },
{ name: 'currency', type: 'string', required: true },
{ name: 'status', type: 'string', required: true, enum: ['pending', 'paid', 'refunded'] },
{ name: 'createdAt', type: 'datetime', required: true },
],
});
// Invite a teammate
await norbix.hub.account.sendInviteToTeamMember({
email: '[email protected]',
role: 'developer',
});Campaigns and triggers (norbix.hub.notifications, norbix.hub.triggers)
A campaign is sent through one provider integration, and the gateway requires
its id. Pick it with getEmailIntegrations / getPushIntegrations /
getSmsIntegrations. For Email and Push it goes inside campaign; for SMS it
is a top-level integrationId (not the same field as databaseIntegrationId).
await norbix.hub.notifications.createEmailCampaign({
campaign: {
source: 'Email',
templateId: emailTemplateId,
integrationId: emailIntegrationId, // required
recipients: ['[email protected]'],
},
});
await norbix.hub.notifications.createPushCampaign({
campaign: { source: 'AllUsers', templateId: pushTemplateId, integrationId: pushIntegrationId },
});
await norbix.hub.notifications.createSmsCampaign({
templateId: smsTemplateId,
integrationId: smsIntegrationId, // required: the SMS provider
deliveryType: 'PhoneNumbers',
phoneNumbers: { phoneNumbers: ['+37060000000'] },
});An Email / Push / SMS trigger action needs integrationId too, and can set
language (one template translation for every recipient) and initiatorId.
Two helpers show what to fix before it fails:
// Triggers of one type that need attention, with the reason
const { items } = await norbix.hub.triggers.getTriggersNeedingAttention({ triggerType: 'Schema' });
// Templates that would miss a translation if the project languages changed
const { templates } = await norbix.hub.account.checkProjectLanguages({
projectId,
defaultLanguage: 'en',
languages: ['en', 'lt'],
});Inbound webhooks
When Norbix POSTs signed events to your endpoint, use @norbix.ai/ts/webhooks — not
hub.webhooks (that module configures destinations).
import {
NORBIX_WEBHOOK_EVENT_NAMES,
NorbixWebhookEvents,
NorbixWebhookReceiver,
} from '@norbix.ai/ts/webhooks';
const receiver = new NorbixWebhookReceiver(); // NORBIX_WEBHOOK_SIGNING_SECRET from env
receiver.on(NorbixWebhookEvents.Membership.UserRegistered, (user, event) => {
console.log('registered', user.email ?? user.userName);
});
receiver.onAll(NORBIX_WEBHOOK_EVENT_NAMES, (e) => console.log(e));
await receiver.handle({ rawBody: req.rawBody, headers: req.headers });De-duplicate on event.eventId: it is the same for every delivery of one
change (plain + schema Webhook trigger). event.deliveryId (envelope id)
only repeats on a retry.
Cloud functions
When a trigger or a scheduled task runs your function on AWS Lambda, Azure Functions or
Google Cloud Functions, the function receives one JSON envelope — the event, its data, a
short-lived token for the run-as user and your config. parseFunctionEvent turns it into a
typed CodeFunctionEvent (or throws on an unknown specVersion), the views
asDatabaseRecordChange<T>() / asUserChange() / asFileChange() / asPayment() /
asScheduledTask() / payload<T>() type the data slot, and createClient() gives you a
Norbix client that acts as the run-as user against the Norbix that called you
(clientOptions() returns the constructor options instead). The Hub side — list the functions
an integration may call, their aliases, invoke one by hand, fetch a sample envelope, read the
last runs — is norbix.hub.code.getCodeFunctions / getCodeFunctionQualifiers /
invokeCodeFunction / getCodeFunctionEventSample / getCodeFunctionRuns.
import { parseFunctionEvent } from '@norbix.ai/ts';
export const handler = async (raw: unknown) => {
const event = parseFunctionEvent(raw);
if (event.event !== 'database.record.updated') return { ok: true };
const { old, new: next } = event.asDatabaseRecordChange<{ _id: string; status: string }>();
if (old?.status !== next?.status) {
await event.createClient().api.database.insertOne({
collectionName: 'order_events',
document: JSON.stringify({
orderId: next?._id,
status: next?.status,
eventId: event.eventId,
}),
});
}
return { ok: true };
};Norbix MCP — same modules, agent-native
Norbix ships an MCP (Model Context Protocol) server that exposes every API and Hub module as agent-callable tools. Same surface as this SDK, just over a different transport — when you connect the Norbix MCP to your IDE, the agent in your editor can read your project, run scripts, and call Norbix the same way your app does.
What it gives you:
- Total SDK & API knowledge. The Norbix MCP knows every module, every method, every request/response type — across all Norbix SDKs (TypeScript, .NET, Python, Dart, Kotlin, Swift) and the underlying gateway. Ask "how do I send a templated email from the .NET SDK?" in your IDE chat and the agent answers from the same source the docs are generated from.
- Code-aware actions. Connect it to your repo and the agent can update project constants, regenerate types after a Hub schema change, scaffold a new module integration, run a Norbix CLI command, or open a PR — without leaving the chat. Run a script or talk to it; same surface, two interaction modes.
- Drop-in IDE setup. One config block in your IDE's MCP settings and you're done. The MCP server runs locally and proxies to your Cloud / self-hosted / enterprise Norbix instance using the same
NORBIX_API_URL/NORBIX_HUB_URLenv vars as the SDK.
Setup in your IDE:
| IDE | Setup guide |
| ---------------------- | -------------------------------------------------------------------------------- |
| Claude Code | docs.norbix.ai/mcp/claude-code |
| Cursor | docs.norbix.ai/mcp/cursor |
| Windsurf | docs.norbix.ai/mcp/windsurf |
| Codex | docs.norbix.ai/mcp/codex |
| Claude Desktop | docs.norbix.ai/mcp/claude-desktop |
| VS Code (Continue) | docs.norbix.ai/mcp/vscode |
| Zed | docs.norbix.ai/mcp/zed |
→ Full MCP documentation · Why MCP? · Self-hosted MCP
Norbix SDKs
Same modules, same method shapes, every language. Each row links to the repo for that language. Package shape varies per language ecosystem norm — TypeScript, Python, Dart, and Kotlin ship a single package; .NET and Swift ship two surfaces (NuGet packages / SwiftPM library products) inside one repo.
| Language | Package | Repo | Status |
| ----------------- | ----------------------------------------- | ------------------------------------------------------------------- | -------------- |
| TypeScript / Node | @norbix.ai/ts | norbix-code/sdk-ts | ✅ Stable |
| .NET | Norbix.Api + Norbix.Hub | norbix-code/sdk-net | ✅ Stable |
| Python | norbix | norbix-code/sdk-python | 🚧 In progress |
| Dart / Flutter | norbix | norbix-code/sdk-dart | 🚧 In progress |
| Kotlin | ai.norbix:norbix-kotlin | norbix-code/sdk-kotlin | 🚧 In progress |
| Swift | Norbix (libs: NorbixApi, NorbixHub) | norbix-code/sdk-swift | 🚧 In progress |
| Go | github.com/norbix-code/sdk-go/v2 | norbix-code/sdk-go | 🚧 In progress |
Install Norbix
Three ways to run the backend this SDK talks to. Pick by who owns the infrastructure and how strict the compliance bar is.
A. Try it on Norbix Cloud — fastest
Zero DevOps. Spin up a managed project on cloud.norbix.ai, grab an API key, point the SDK at it. The default base URLs (https://api.norbix.ai and https://hub.norbix.ai) already point at Cloud — no override needed. 7-day free trial, no credit card.
# 1. Sign up at https://cloud.norbix.ai
# 2. Create a project, copy the API key + project ID
export NORBIX_API_KEY=sk_live_...
export NORBIX_PROJECT_ID=proj_...
# 3. Run any of the examples above. You're done.→ Sign up · Cloud docs
B. Self-host on your machine or your server
Run Norbix on Docker, Kamal, Terraform, AWS CDK, Kubernetes, DigitalOcean, a VPS, or bare metal. Issue a license from the Cloud Dashboard, then deploy with one command. Override the SDK's base URL to point at your deployment.
1. Get a self-hosted license. Sign in at cloud.norbix.ai, open the Self-Hosted tab, generate a license key.
2. Deploy. Build your install in the Cloud Dashboard's installer UI or clone the install repo:
# Quickest — Docker Compose
git clone https://github.com/norbix-code/install
cd install/docker-compose
NORBIX_LICENSE_KEY=lic_... docker compose up -d
# Norbix is up at http://localhost:5000 (API) and http://localhost:5001 (Hub) by defaultOther deployment paths (each in a sibling folder of the install repo):
| Method | Folder | Best for |
| ------------------- | ----------------- | ------------------------------- |
| 🐳 Docker | docker-compose/ | Local dev, single VM |
| 🚢 Kamal | kamal/ | One-server deploys, Rails-style |
| 🏗️ Terraform | terraform/ | Multi-cloud IaC |
| ☁️ AWS CDK | aws-cdk/ | AWS-native |
| ⎈ Kubernetes | kubernetes/ | k3s / k8s at scale |
| 🌊 DigitalOcean | digitalocean/ | Droplets + DO Kubernetes |
| 🖥️ VPS / bare metal | vps/ | Any provider, total control |
| 🏢 On-premises | on-prem/ | Air-gapped or private DC |
3. Point the SDK at it. Two patterns — pick whichever fits.
# Local development on your machine
export NORBIX_API_URL=http://localhost:5000
export NORBIX_HUB_URL=http://localhost:5001# Self-hosted on your company's domain
export NORBIX_API_URL=https://api.norbix.isidos.lt
export NORBIX_HUB_URL=https://hub.norbix.isidos.lt→ Install repo · Self-host docs
C. Enterprise — your cloud, your compliance
Run Norbix in your VPC or dedicated infrastructure. SOC2-ready, GDPR/HIPAA-compatible, full audit trails, custom SLA, dedicated support, deployment review with the Norbix team. Same APIs as Cloud and Self-Hosted — just behind your perimeter. Override the SDK's base URL to your private endpoint.
→ Contact sales · Enterprise docs
Error handling
import { NorbixError } from '@norbix.ai/ts';
try {
await norbix.api.database.find({ collectionName: 'orders' });
} catch (err) {
if (err instanceof NorbixError) {
// httpStatus / errorCode / errors are the names every Norbix SDK uses.
// status / code / fieldErrors are the same values, kept for older code.
console.log(err.httpStatus, err.errorCode, err.message);
for (const e of err.errors) console.log(e.errorCode, e.fieldName, e.message);
console.log(err.body); // the answer exactly as it arrived
}
throw err;
}message and errorCode are the gateway's own. The gateway puts them inside
responseStatus.errors[], so a NorbixError reads that list first, takes the
first entry for message / errorCode, and keeps every entry in errors.
Only when the body has no responseStatus are the top-level message and
errorCode read. Request failed (HTTP <status>) is the last fallback, used
when the body says nothing (for example a 500 page that is not JSON).
| Code | Meaning |
| ------------------------------- | ----------------------------------------------------------------- |
| NORBIX_NOT_AUTHENTICATED | No apiKey, bearerToken, or env var, and login() not called. |
| NORBIX_ACCOUNT_SCOPE_REQUIRED | Account-scoped call made without accountId (no method today). |
| NORBIX_MISSING_PATH_PARAM | A {token} in the route was not provided on the request. |
| NORBIX_NETWORK_ERROR | Fetch failed (network, CORS, timeout). |
Breaking change in 2.0.0 — a refused call now throws
The gateway answers a business refusal (an unknown id, a rule that says no)
with HTTP 200 and responseStatus.isSuccess = false. Until 2.0.0 the SDK
handed that answer back as a normal value, so code carried on as if the call
had worked. From 2.0.0 such an answer throws a NorbixError with
httpStatus = 200 and the gateway's message and error code.
If your code checked res.responseStatus.isSuccess itself, move that check
into a try / catch:
// before
const res = await norbix.api.files.getFileInfo({ filesIntegrationId, path });
if (!res.responseStatus.isSuccess) handleFailure(res.responseStatus.errors);
// after
try {
const res = await norbix.api.files.getFileInfo({ filesIntegrationId, path });
} catch (err) {
if (err instanceof NorbixError) handleFailure(err.errors);
}Endpoints that answer with raw bytes rather than a document — download, the
public file link, the upload and download content links — are not JSON and are
unchanged.
Community & support
- Documentation. Best for: building, integrating, and reference.
- GitHub Discussions. Best for: technical Q&A, feature requests, sharing what you built.
- GitHub Issues. Best for: bugs and reproducible errors in this SDK.
- Discord. Best for: real-time chat with the team and the community.
- Email support. Best for: account, billing, and infrastructure issues that aren't public.
Resources
Website · Cloud Dashboard · Docs · API · Hub · MCP · Blog · Discord · X · YouTube · LinkedIn
Development
npm install
npm run lint
npm run typecheck
npm test
npm run buildConventional commits are required. Use npm run commit for a guided flow. Pushes to main are released to npm by semantic-release with provenance enabled. next and beta branches publish prereleases.
The SDK module classes (src/api/*, src/hub/*), their tests, and per-module docs are generated from the gateway DTOs by an internal maintenance workflow. Generated artifacts are committed to git and consumed by CI as-is — CI never regenerates. The generation scripts themselves are dev-only and gitignored (see .gitignore).
Security
Found something? Don't open a public issue. See SECURITY.md and email [email protected]. We respond within one business day.
Contributing
Issues, PRs, and design partners welcome. Start with CONTRIBUTING.md for branching, local dev, and how to add a module. Bigger ideas land in Discussions before they land in code.
License
MIT © Norbix
