Valqio Docs
Guides

Node SDK

Use @valqio/sdk-node to make runtime decisions from server routes, workers, and backend services.

The Node SDK exposes low-level runtime clients and higher-level application clients. Use a generated app client when Console provides one for your project. Use the runtime client directly when you need the stable primitive surface or a small first proof.

Install

npm install @valqio/sdk-node

Runtime client

import { createRuntimeClient } from '@valqio/sdk-node'

const runtime = createRuntimeClient({
  apiKey: process.env.VALQIO_API_KEY!,
  baseUrl: process.env.VALQIO_DATA_PLANE_URL!,
  projectId: process.env.VALQIO_PROJECT_ID!,
  environment: process.env.VALQIO_ENVIRONMENT!,
  mode: 'remote-only',
})

Use this client in backend code that already knows the subject and the action being attempted.

export async function generateForWorkspace(workspaceId: string, requestId: string) {
  const decision = await runtime.enforce({
    requestId,
    meterKey: 'generation-runs',
    quantity: 1,
    subject: { type: 'customer', key: workspaceId },
    idempotencyKey: `generation-runs:${requestId}`,
  })

  if (!decision.allowed) {
    return {
      status: 402,
      body: { reasonCode: decision.reasonCode, requestId },
    }
  }

  const result = await runGeneration()
  return { status: 200, body: { result, requestId } }
}

Subject-bound workflow

When your app uses generated bindings, bind the customer once and call generated helpers through the request.

import { createMyAppValqioClientFromEnv } from './valqio.generated'

const myApp = createMyAppValqioClientFromEnv({
  runtimeOverrides: { mode: 'remote-only' },
})

export async function generateWithBindings(workspaceId: string, requestId: string) {
  const customer = myApp.customer({ id: workspaceId }, { requestId })
  const decision = await customer.meters.generationRuns.enforce({
    quantity: 1,
    requestId,
    idempotencyKey: `generation-runs:${requestId}`,
  })

  if (!decision.allowed) {
    return {
      status: 402,
      body: { reasonCode: decision.reasonCode, requestId },
    }
  }

  const result = await runGeneration()
  return { status: 200, body: { result, requestId } }
}

Runtime checklist

  • Call Valqio before the product action starts.
  • Send a stable subject key.
  • Send quantity in the same unit your meter or action expects.
  • Send an idempotency key for every request that may be retried.
  • Log the request ID, idempotency key, reason code, and any reservation ID in a safe place for support investigation.

What stays server-side

Keep consuming runtime calls on your backend, worker, or serverless function. Do not expose server runtime API keys in browser code.

Browser and client-side experiences can show plan state, remaining usage, or upgrade paths through your own backend. The server remains responsible for enforce, reserve, commit, and release.

On this page