Quickstart
Check access, enforce usage, and inspect the evidence those operations create.
This guide uses generation-runs to show the Valqio integration loop. The same request shape works for API calls, exports, reports, seats, storage, model tokens, or other costly product work.
1. Get SDK access
@valqio/sdk-node is currently a private-preview package and is not published on the public npm registry. Request package access from Valqio, then configure the registry details supplied with your account.
After access is configured, install the SDK:
npm install @valqio/sdk-node2. Configure runtime environment values
Use hosted values from the Valqio Console for your project and environment.
VALQIO_API_KEY=<server runtime key>
VALQIO_DATA_PLANE_URL=<hosted runtime API URL>
VALQIO_PROJECT_ID=<project id>
VALQIO_ENVIRONMENT=<environment key>Do not print API keys or paste them into logs, screenshots, or support tickets.
3. Create a 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',
})4. Call Valqio before the billable action
This is the access-then-consume path: check feature access without consuming usage, then enforce usage before the costly work starts.
export async function generateReport(requestId: string, workspaceId: string) {
const idempotencyKey = `generate-report:${requestId}`
const subject = {
type: 'customer' as const,
key: workspaceId,
}
const access = await runtime.evaluate({
requestId,
subject,
checks: [{ key: 'report-export', type: 'flag' }],
})
const reportExport = access.results.find((result) => result.key === 'report-export')
if (reportExport?.decision !== 'allow') {
return {
status: 403,
body: {
reason: 'upgrade_required',
reasonCode: reportExport?.reasonCode,
requestId,
},
}
}
const decision = await runtime.enforce({
requestId,
meterKey: 'generation-runs',
quantity: 1,
subject,
idempotencyKey,
})
if (!decision.allowed) {
return {
status: 402,
body: {
reasonCode: decision.reasonCode,
requestId,
idempotencyKey,
},
}
}
const result = await runExpensiveGeneration()
return {
status: 200,
body: {
result,
requestId,
idempotencyKey,
},
}
}For generated helper examples, see feature and parameter access.
5. Inspect the evidence
After the request, open Console and inspect the decision record. The evidence should explain:
- which subject asked to run work
- which meter or action was evaluated
- whether the decision was allowed or denied
- what remaining balance, quota, or limit context was used
- which idempotency key protected retries
- which request ID ties the Console record back to your app logs
That evidence is the handoff from runtime enforcement to support, finance, customer success, analytics, and billing sync.