Node SDK

API reference for @temps-sdk/node-sdk (0.0.7). The package gives server-side Node.js and Bun code two things: TempsClient, a typed client for the Temps REST API with 25 namespaces, and ErrorTracking, a Sentry-compatible client that reports exceptions to your project's DSN. It also includes a feature-flag reader.

Other SDKs (React analytics, Vue, Svelte, KV and Blob storage) are listed in SDKs; browser error tracking uses the official Sentry SDKs, as described in Error Tracking.


Installation

npm install @temps-sdk/node-sdk

Requirements: Node.js 18+ or Bun. TypeScript 5+ (peer dependency).


API client

The API client provides typed access to every Temps API endpoint. List endpoints are paginated; see Pagination.

import { TempsClient } from '@temps-sdk/node-sdk';

const temps = new TempsClient({
  baseUrl: 'https://your-temps-instance.com/api',
  apiKey: 'your-api-key',
});

// List projects
const { data: projects } = await temps.projects.list();

// Trigger a deployment of the main branch
await temps.projects.triggerPipeline({
  path: { id: 1 },
  body: { branch: 'main' },
});

// Rollback
await temps.deployments.rollback({
  path: { project_id: 1, deployment_id: 5 },
});

Constructor options

  • Name
    baseUrl
    Type
    string
    Description

    Your Temps instance's API root, including the /api prefix (e.g. https://your-temps-instance.com/api). The client's paths, such as /projects/{id}, are appended to it. Apps deployed on Temps get this value injected as TEMPS_API_URL. Required.

  • Name
    apiKey
    Type
    string
    Description

    API key, sent as a Bearer token. Optional in the type, but every authenticated endpoint needs it.

Raw client access

For advanced use cases or endpoints not covered by namespaces:

const client = temps.rawClient;

Client namespaces

The client organizes all platform operations into 25 typed namespaces:

NamespaceDescription
temps.apiKeysAPI key CRUD, activate/deactivate
temps.analyticsVisitors, sessions, events, enrichment, stats
temps.auditLogsAudit log retrieval
temps.authenticationLogin, logout, MFA, password reset
temps.backupsBackup schedules, S3 sources, run/restore
temps.cronsCron jobs and execution history
temps.deploymentsGet, cancel, pause, resume, rollback, teardown, jobs and job logs (start a deploy with temps.projects.triggerPipeline)
temps.dnsDNS providers, managed domains, zone listing
temps.domainsSSL/TLS domains, ACME provisioning
temps.emailEmail providers, domains, send, stats
temps.externalServicesPostgreSQL, Redis, S3 lifecycle, env vars
temps.filesFile retrieval by ID
temps.funnelsFunnel CRUD, metrics, previews
temps.gitGitHub/GitLab providers, repo connections, sync
temps.loadBalancerRoute management
temps.monitoringMonitors, incidents, uptime, status buckets
temps.notificationsPreferences, providers (email, Slack, webhook)
temps.performanceWeb Vitals metrics
temps.platformInstance info, IPs, geolocation, presets
temps.projectsFull project lifecycle: environments, domains, env vars, containers, analytics, errors, session replay, webhooks
temps.proxyLogsProxy log queries
temps.repositoriesSynced repos, branches, tags, presets
temps.sessionReplaySession init, events, deletion
temps.settingsPlatform settings
temps.usersUser CRUD, MFA, roles

All request/response types are auto-generated from the OpenAPI spec:

import type {
  ProjectResponse,
  DeploymentResponse,
  CreateProjectRequest,
} from '@temps-sdk/node-sdk';

Error tracking

A Sentry-compatible error tracking client for server-side code. Initialize it once at application startup. Grouping, source maps and the dashboard side are covered in Error Tracking.

import { ErrorTracking } from '@temps-sdk/node-sdk';

ErrorTracking.init({
  dsn: 'https://public-key@your-instance.temps.dev/1',
  environment: 'production',
  release: '1.0.0',
});

The DSN follows the Sentry format: https://<public-key>@<host>/<project-id>. Find it in your project's Error Tracking > DSN & Setup tab.


ErrorTracking.init options

  • Name
    dsn
    Type
    string
    Description

    The Data Source Name. Required.

  • Name
    environment
    Type
    string
    Description

    Environment name (e.g. production, staging).

  • Name
    release
    Type
    string
    Description

    Your application version.

  • Name
    serverName
    Type
    string
    Description

    Server identifier for distinguishing instances.

  • Name
    sampleRate
    Type
    number
    Description

    Error sampling rate (0.0 to 1.0).

  • Name
    tracesSampleRate
    Type
    number
    Description

    Performance trace sampling rate (0.0 to 1.0).

  • Name
    ignoreErrors
    Type
    (string | RegExp)[]
    Description

    Errors matching these patterns are silently dropped.

  • Name
    beforeSend
    Type
    (event) => event | null
    Description

    Modify or drop events before sending. Return null to drop.

  • Name
    maxBreadcrumbs
    Type
    number
    Description

    Maximum breadcrumbs to retain.

  • Name
    attachStacktrace
    Type
    boolean
    Description

    Attach stack traces to message events.

  • Name
    debug
    Type
    boolean
    Description

    Log events to console instead of sending. Useful for development.

  • Name
    integrations
    Type
    Integration[]
    Description

    Custom integrations (each must implement setupOnce()).


Capturing errors

// Capture an exception
try {
  riskyOperation();
} catch (error) {
  const eventId = ErrorTracking.captureException(error);
}

// Capture with extra context
ErrorTracking.captureException(error, {
  tags: { subsystem: 'payments' },
  extra: { orderId: '12345', amount: 99.99 },
  level: 'fatal',
});

// Capture a message
ErrorTracking.captureMessage('Disk usage above 90%', 'warning');

// Capture a raw event
ErrorTracking.captureEvent({
  message: 'Custom event',
  level: 'info',
  tags: { source: 'cron' },
});

Global handlers

The SDK automatically captures unhandled errors:

HandlerLevelBehavior
process.on('uncaughtException')fatalCaptured, then process.exit(1)
process.on('unhandledRejection')errorCaptured, process continues

Both are tagged with handled: false.


Context and scope

Enrich error reports with user information, tags, and structured data.

// Set the current user (attached to all subsequent events)
ErrorTracking.setUser({
  id: '123',
  email: 'alice@example.com',
  username: 'alice',
  ip_address: '{{auto}}',
});

// Set global tags
ErrorTracking.setTag('region', 'eu-west-1');
ErrorTracking.setTags({ service: 'api', version: '2.0' });

// Set extra data
ErrorTracking.setExtra('requestId', 'abc-123');
ErrorTracking.setExtras({ query: 'SELECT ...', duration: 150 });

// Set structured context
ErrorTracking.setContext('order', {
  id: 'order-456',
  total: 99.99,
  items: 3,
});

// Clear user on logout
ErrorTracking.setUser(null);

Scoped context

// Permanent scope modification
ErrorTracking.configureScope((scope) => {
  scope.setTag('transaction', 'checkout');
  scope.setUser({ id: '123' });
});

// Temporary scope (discarded after callback)
ErrorTracking.withScope((scope) => {
  scope.setTag('component', 'payment-form');
  ErrorTracking.captureMessage('Payment processed');
});

Leave a trail of events leading up to an error.

ErrorTracking.addBreadcrumb({
  category: 'auth',
  message: 'User logged in',
  level: 'info',
  data: { method: 'oauth' },
});

ErrorTracking.addBreadcrumb({
  category: 'http',
  message: 'GET /api/users',
  level: 'info',
  type: 'http',
  data: { status: 200, duration: 45 },
});

// Clear all breadcrumbs
ErrorTracking.clearBreadcrumbs();
  • Name
    category
    Type
    string
    Description

    Grouping category (e.g. auth, http, db).

  • Name
    message
    Type
    string
    Description

    Human-readable description.

  • Name
    type
    Type
    string
    Description

    One of: default, http, navigation, console.

  • Name
    level
    Type
    string
    Description

    One of: debug, info, warning, error, critical.

  • Name
    data
    Type
    Record<string, any>
    Description

    Arbitrary structured data.


Performance monitoring

Track transactions and spans to measure latency.

const transaction = ErrorTracking.startTransaction({
  name: 'POST /api/checkout',
  op: 'http.server',
});

const dbSpan = transaction.startChild({
  op: 'db.query',
  description: 'SELECT * FROM orders WHERE id = ?',
});
// ... query ...
dbSpan.finish();

transaction.setMeasurement('order_total', 99.99, 'usd');
transaction.setStatus('ok');
transaction.finish();

Spans capture startTimestamp, endTimestamp, op, description, status, tags, and data. Spans can be nested.


User feedback

Collect feedback after an error:

const eventId = ErrorTracking.captureException(error);

ErrorTracking.captureUserFeedback({
  event_id: eventId,
  name: 'Alice',
  email: 'alice@example.com',
  comments: 'The checkout button did nothing.',
});

Lifecycle

// Flush pending events (waits up to 2s by default)
await ErrorTracking.flush(2000);

// Close the client (disables further capturing + flushes)
await ErrorTracking.close(2000);

Enriching visitors

Attach backend context — user identity, subscription tier, custom tags — to a visitor record after they authenticate. This links the anonymous pre-login session to the known user in Analytics.

Getting the visitor ID

On apps served by Temps, the proxy stores the visitor ID in the _temps_visitor_id cookie. It is HttpOnly, so browser JavaScript can't read it and the React SDK doesn't expose it. Read it on the server instead: after login, have the frontend call one of your own API routes, and the cookie arrives with that request:

// After the user signs in
useEffect(() => {
  if (user) fetch('/api/enrich-visitor', { method: 'POST' });
}, [user]);

enrichVisitor accepts the cookie value (a sealed enc_… GUID), a plain visitor GUID ("550e8400-...") or a numeric visitor ID.

Enriching from the backend

import { TempsClient } from '@temps-sdk/node-sdk';

const client = new TempsClient({
  baseUrl: process.env.TEMPS_API_URL,
  apiKey: process.env.TEMPS_API_KEY,
});

await client.analytics.enrichVisitor({
  path: { visitor_id: visitorId },
  query: { project_id: Number(process.env.TEMPS_PROJECT_ID) },
  body: {
    custom_data: {
      userId: user.id,
      email: user.email,
      subscriptionTier: user.subscription?.tier ?? 'free',
      signupDate: user.createdAt.toISOString(),
    },
  },
});
// Returns: { success: true, visitor_id: string, message: string }

Next.js API route example

// app/api/enrich-visitor/route.ts
import { cookies } from 'next/headers';
import { TempsClient } from '@temps-sdk/node-sdk';

// On Temps, TEMPS_API_URL and TEMPS_API_TOKEN (a deployment token) are injected.
// A deployment token may only enrich visitors of its own project, using the
// sealed cookie value, which is exactly what this route sends.
const client = new TempsClient({
  baseUrl: process.env.TEMPS_API_URL!,
  apiKey: process.env.TEMPS_API_TOKEN!,
});

export async function POST() {
  const visitorId = (await cookies()).get('_temps_visitor_id')?.value;
  const user = await getCurrentUser(); // your own auth/session lookup
  if (!visitorId || !user) return Response.json({ success: false }, { status: 400 });

  await client.analytics.enrichVisitor({
    path: { visitor_id: visitorId },
    query: { project_id: Number(process.env.TEMPS_PROJECT_ID) },
    body: {
      custom_data: {
        userId: user.id,
        email: user.email,
        subscriptionTier: user.subscription?.tier ?? 'free',
      },
    },
  });

  return Response.json({ success: true });
}

Querying enriched visitors

// By GUID
const { data: byGuid } = await client.analytics.getVisitorByGuid({
  path: { visitor_id: '550e8400-e29b-41d4-a716-446655440000' },
  query: { project_id: 1 },
});

// By numeric ID
const { data: byId } = await client.analytics.getVisitorById({
  path: { id: 123 },
  query: { project_id: 1 },
});

console.log(byId?.custom_data);
// { userId: '123', email: 'user@example.com', subscriptionTier: 'pro' }

Feature flags

Read feature flags created in the Temps console from any service you deploy on Temps. TEMPS_API_URL and TEMPS_API_TOKEN are injected into every deployment and the token pins the project (and usually the environment), so flags.init() needs no configuration on Temps itself.

import { flags } from '@temps-sdk/node-sdk';

await flags.init();

if (flags.get('checkout.v2', { key: user.id }, false)) {
  // ...
}

get() is synchronous and does zero network I/O per call: the whole environment's flag set is loaded into memory once and kept fresh by a background poll, so a per-check HTTP round trip never sits in a request handler's hot path. The third argument is the fallback — returned whenever the flag is unknown, the snapshot hasn't loaded yet, or the control plane is unreachable. flags.ready and flags.lastError are exposed so an unreachable flag service is a visible condition, not a silent one.

Locally, without TEMPS_API_URL/TEMPS_API_TOKEN set, every read returns its fallback — this is expected, not a degraded state.


Flag refresh interval

The background poll that keeps the in-memory flag snapshot fresh runs every 30 seconds by default. A flag flipped in the console reaches an already-running process on its next poll — up to 30s later, not instantly. This is deliberate: it keeps reads free of network I/O, at the cost of that window.

Override it either way:

import { FlagsClient } from '@temps-sdk/node-sdk';

const flags = new FlagsClient({ refreshIntervalMs: 5_000 });
await flags.init();

TEMPS_FLAGS_REFRESH_INTERVAL_MS is the one to reach for on a Temps deployment — set it as an environment variable on the project/environment and the default flags singleton picks it up with no redeploy of application code. A non-numeric or negative value is ignored (falls back to 30s) and logged via console.warn, rather than silently accepted.

Unchanged flags cost a 304 Not Modified, not a payload, so tightening this interval is cheap even at a low value. Setting it to 0 disables the background poll entirely — reads keep serving whatever snapshot was loaded at init().

Last updated

Was this page helpful?