Node SDK
Server-side quickstart for @layers/amba-node — install, configure, asUser() per-request scoping, and Connect/Express middleware in under 10 minutes.
@layers/amba-node is the Node.js server SDK. Same 25-namespace surface as @layers/amba-web, idiomatic for long-running Node processes — typically one client per service, per-request user scoping via asUser(uid), and a built-in Connect-style middleware factory.
When to use this SDK:
- Webhook handlers (Stripe, RevenueCat, GitHub) that need to mutate amba state from server context.
- Background workers / cron jobs that need to call the amba API on behalf of users.
- BFFs that proxy specific operations from a browser to amba with extra business logic.
1. Install
Requires Node 20+ (uses native fetch, top-level await, and import.meta.resolve).
2. Configure once at boot
AmbaClient.configure() is a one-time async call that initializes inside the Node process and returns the configured client. Hold the returned instance for the life of the process.
Set AMBA_API_KEY=amb_dev_ck_XXXX in your environment (your usual env-var management — secret store, container env, CI variable, etc.). Use a server-only key — the dev key is fine for development, but production deployments should mint a dedicated server key via the console.
3. Per-request user scoping with asUser()
The server endpoints under /v1/client/* all run under clientSessionAuth — they require a Bearer session token for an app_user. The Node SDK's asUser(uid) is how you mint that scope: given an app_user.id that already exists in your project (typically created server-side when your auth flow signs in a real end-user), asUser(uid) returns a handle whose subsequent calls all act as that user.
What if there are no app_users yet? Brand-new tenants (no end-users signed in) can mint an anonymous session via
await amba.auth.signInAnonymously()— the resultingapp_user.idthen becomes a valid argument toasUser(). For greenfield apps without their own auth flow, that's the canonical "first user" path.
Without asUser() or signInAnonymously(), the Node SDK has no session token and every /v1/client/* call returns 401 Unauthorized — session token missing or expired. The SDK is not implicitly server-trusted on the client endpoints; you choose which user it acts as on every request.
4. First track (post-auth)
Now that the SDK is scoped to a user, track an event:
If your webhook handler doesn't have a specific user in scope, mint an anonymous session first:
asUser(uid) returns a handle that:
- Wraps every read with the equivalent of
WHERE user_id = uid. - Rejects
insert/updatepayloads whoseuser_iddiffers fromuid. - On
delete, restricts to rows whereuser_id = uid.
Without asUser(), the Node SDK is server-trusted — it can read and write any row across any user. Use that intentionally for admin operations; otherwise scope every request.
5. Connect/Express middleware
For request-handlers that always need the SDK, amba.middleware() returns a Connect-style factory that attaches req.amba to every incoming request:
For a per-request user-scoped handle, chain req.amba.asUser(req.session.userId) inside each handler.
Collections
Same DSL as the web SDK:
For full operator coverage (eq, ne, gt, gte, lt, lte, in, notIn, like, ilike, isNull, isNotNull, and, or, not) see collections.
Storage (presign + commit)
The Node SDK exposes presign and commit directly so the upload itself can flow through your server — useful for buffered uploads, validation, or virus scanning:
Push fan-out
If your service is the source of truth for "send a push to user X", call register() once when the device hands you a token, and use the push campaign API (admin) to fan out from your server:
AI proxy
Same prompt slug catalog as the client SDK — slugs are managed in the console and shared across server + browser usage.
Long-running processes
The Node SDK is safe for long-lived processes:
- The underlying amba core caches HTTP connections.
- Auth token refresh is automatic.
- There's no global state — multiple
AmbaClientinstances (e.g. one per tenant key in a multi-tenant proxy) are isolated.
For high-concurrency scenarios (10k+ rps), pool one AmbaClient per worker process rather than per request.
Common pitfalls
- Calling
AmbaClient.configure()per request — don't. The cold-start init is ~50ms; call once at boot, share the instance. - Forgetting
asUser(uid)in user-context handlers — the default surface is server-trusted; withoutasUseryou can accidentally read or mutate another user's data. Lint rule: every route handler that takes user input should explicitly chooseamba.asUser(uid)oramba(admin). - WebSocket / SSE proxies — auth state isn't shared with the browser; mint a short-lived session in the browser instead of proxying through Node.
See also
- Client API reference — HTTP endpoint reference for every namespace.
- Code samples — same operations side-by-side with the other 7 SDKs.