Skip to main content

Identifiers and lifecycles

This page defines the identifiers you must keep stable and the minimal lifecycle rules you should follow in production.

The six identifiers you will see everywhere

realm_id

  • What it is: the project boundary.
  • Who chooses it: you (per application).
  • Rule: every request must include X-Realm-Id.

Service key (service_key_id, service_key_secret)

  • What it is: server-to-server credentials used to authenticate calls to /mgt/v1.
  • Who uses it: your backend services and trusted workers only.
  • Rule: never ship the secret to browsers, mobile apps, or other untrusted clients.

principal_id

  • What it is: your billing principal identifier (usually a customer, org, team, or tenant id).
  • Who chooses it: you.
  • Rules:
    • It must be stable over time.
    • It must represent the entity that owns billing in your product.
    • Do not use a per-request random id.

billing_account_id

  • What it is: Vluna's billing account identifier and the payor/account data anchor.
  • Who assigns it: Vluna.
  • Rules:
    • The mapping between principal_id and billing_account_id is 1:1.
    • The mapping is immutable after first creation.
    • Do not trust client-supplied billing_account_id from untrusted environments.

user_id

  • What it is: your runtime user identifier inside the billing principal.
  • Who chooses it: you.
  • Rules:
    • It must be stable for the end user whose usage is being measured.
    • Runtime gate, wallet, events, grants, limits, and self reports require it together with principal_id.
    • Do not collapse user_id into principal_id unless your product is truly one paying account per user.

billing_user_id

  • What it is: Vluna's internal identifier for (billing_account_id, user_id).
  • Who assigns it: Vluna.
  • Rules:
    • It is the runtime ownership key for usage, grants, wallet balance, limits, events, and self-service reports.
    • It may appear in admin/ops APIs and token issue responses.
    • It is not the public runtime SDK input; use user_id at the SDK/API boundary.

Idempotency-Key

  • What it is: a client-provided key used to safely retry write requests.
  • Rules:
    • All write requests require it.
    • Reuse the same key only when retrying the same logical operation.
    • If you reuse a key with a different request body, the server returns a conflict.

Minimal lifecycle: from principal to bearer token

The simplest safe pattern is:

  1. Your backend receives a request for a customer and end user.
  2. Your backend identifies principal_id for the paying customer and user_id for the runtime user.
  3. Your backend calls POST /mgt/v1/token/issue with both identifiers.
  4. Vluna returns:
    • billing_account_id (stable for that principal)
    • billing_user_id (stable for that user under the account)
    • access_token (short-lived bearer token)
  5. Your backend stores the returned identifiers if it needs support or analytics joins.
  6. Your frontend uses the bearer token for /api/v1 calls, when needed.

Minimal lifecycle: authorize then commit

The runtime gate loop is:

  1. Authorize: POST /mgt/v1/gate/authorize returns a lease_token.
  2. Do the protected work in your system.
  3. Commit: POST /mgt/v1/gate/commits reports usage and returns an authoritative priced result.
  4. If work fails, cancel the lease using POST /mgt/v1/gate/cancel (best-effort).

Safe defaults for Day 0 integration

Use these defaults until you are ready to tighten enforcement:

  • Always send an Idempotency-Key and reuse it on retries.
  • Start with one stable feature_code and one stable unit for quantity_minor.
  • Treat hints as machine-readable signals: log them, emit metrics, and decide how to degrade behavior when they appear.

Common failure modes (and how to avoid them)

  • Wrong principal_id choice:
    • Too broad (one id for all customers) merges billing and limits for unrelated customers.
    • Too narrow (random id per request) fragments billing and makes operations and support impossible.
  • Wrong user_id choice:
    • Too broad (one id for all users in a team) merges usage, grants, limits, and self-service reports for different users.
    • Too narrow (random id per request) creates a new runtime user for every call.
  • Secret handling mistakes:
    • Shipping a Service Key secret to the browser makes account takeover likely.
  • Retry mistakes:
    • Retrying writes without reusing the same Idempotency-Key can double charge or double record usage.

Next steps