Valqio Docs
Guides

Generated clients

Use app-native SDK helpers generated from controls and their product-facing integrations.

Generated clients turn Valqio configuration into app-native TypeScript helpers. They keep product code close to your domain language while preserving Valqio's runtime decision model.

Generated client files come from Console or Valqio's SDK tooling for your project.

For a full integration path, see the end-to-end generated client guide.

For non-consuming feature and parameter checks, see feature and parameter access.

When to use generated clients

Use a generated client when your project has control-owned app integrations, meters, flags, limits, plans, or configs that should be referenced by stable app aliases.

Generated clients help you avoid:

  • hard-coded meter keys scattered through app code
  • mismatched subject shapes
  • missing request IDs
  • unresolved binding drift
  • hand-written reserve, commit, and release glue for common actions

Typical shape

import {
  createInvoicingValqioClientFromEnv,
  inspectInvoicingValqioReadiness,
} from './valqio.generated'

async function createReadyInvoicingClient() {
  const bindings = inspectInvoicingValqioReadiness()
  if (!bindings.ready) {
    throw new Error(`Valqio bindings unresolved: ${bindings.unresolved.join(', ')}`)
  }

  const invoicing = createInvoicingValqioClientFromEnv({
    runtimeOverrides: { mode: 'remote-only' },
  })
  const runtime = await invoicing.ready()
  if (!runtime.snapshotReady) {
    throw new Error('Valqio published runtime snapshot is unavailable')
  }

  return invoicing
}

const invoicingPromise = createReadyInvoicingClient()

export async function sendInvoiceForWorkspace(workspaceId: string, requestId: string) {
  const invoicing = await invoicingPromise
  const customer = invoicing.customer({ id: workspaceId }, { requestId })
  const invoice = await customer.actions.invoices.send.run(
    {
      idempotencyKey: `sendInvoice:${requestId}`,
      context: { endpoint: '/invoices/send' },
    },
    async () => sendInvoice(),
  )
  return { status: 200, body: { invoice, requestId } }
}

Readiness

Run both checks at startup or health-check time:

  • inspectInvoicingValqioReadiness() synchronously verifies that generated aliases resolve to concrete bindings.
  • await invoicing.ready() checks whether the runtime client can obtain a published snapshot. Require snapshotReady before serving product work that depends on that environment. After the first load, this check may use the client's cached snapshot; it is not a general data-plane health probe.

Failing fast is better than silently running product work without enforcement.

Cross-process reservations

When a request process and worker are separated by a queue, use the generated advanced methods and store the action transaction ID with the job:

export async function enqueueVideo(workspaceId: string, jobId: string) {
  const invoicing = await invoicingPromise
  const customer = invoicing.customer({ id: workspaceId }, { requestId: jobId })
  const transaction = await customer.actions.videos.render.begin({
    quantity: 1,
    idempotencyKey: `renderVideo:${jobId}`,
    expiresIn: 'PT15M',
  })

  await jobs.enqueue({
    jobId,
    workspaceId,
    actionTransactionId: transaction.transactionId,
  })
}

export async function runVideoJob(job: VideoJob) {
  const invoicing = await invoicingPromise
  const customer = invoicing.customer(
    { id: job.workspaceId },
    { requestId: job.jobId },
  )
  const claimed = await customer.actions.videos.render.claim({
    transactionId: job.actionTransactionId,
  })

  let video
  try {
    video = await renderVideo()
  } catch (error) {
    await customer.actions.videos.render.release({
      transactionId: claimed.transactionId,
      failure: {
        code: error instanceof Error ? error.name : 'WORK_FAILED',
        message: error instanceof Error ? error.message : String(error),
      },
    })
    throw error
  }

  await customer.actions.videos.render.commit({
    transactionId: claimed.transactionId,
  })
  return video
}

Commit only after the app has completed the work it intends to charge for. Release failed work. Keep commit outside the product-work catch: an uncertain commit must be retried or reconciled and must never trigger release of successful work. The application supplies one stable key at begin(); Valqio owns phase-level idempotency.

On this page