BillingCreditSettledPayload billing.credit.settled@1

Generated at from openvibe-contracts v0.419.0 and openvibe-sdk v0.161.0.

Version
1.0.0
Owner
billing
Visibility
first-party
Status
active
Compatibility
backward
Schema
https://openvibe.network/contracts/events/payloads/billing.credit.settled.v1.json

billing.credit.settled v1 (OpenVibe.Billing server/ops/credits.js settleHold(); written with the settlement row in the settle transaction): a Credits hold was settled once. It is AGGREGATE-ONLY on purpose: it carries no subject, no project_id and no account id, so a consumer can count services, routes and money but cannot reconstruct a person's statement; per-person statements are read from Billing's own ledger. OpenVibe.Report consumes it for aggregate analytics. Money is integer nano-USD as decimal strings (D1: never a float). Envelope: subject { type: credit-settlement, id: stl_… }, visibility internal, priority important, actor service:billing.

Fields

FieldTypeRequiredDescriptionConstraints
settlement_idstringyesULID settlement id, the same one the settle result and Billing's statement use.
  • pattern ^stl_[0-9A-HJKMNP-TV-Z]{26}$
hold_idstringyesThe settled hold.
  • pattern ^hld_[0-9A-HJKMNP-TV-Z]{26}$
servicestringyesThe hold's service (D9): which metered service spent the credit, e.g. ai. Read from the hold; the settle request does not carry it.
  • pattern ^[a-z][a-z0-9-]{0,39}$
settled_atstringyesWhen the settlement committed (the settlement row's created_at).
  • format date-time
deployment_idstring | nullyesThe answering attempt's deployment id, '<provider>:<model>' as sent in the settle request's attempts[].deployment_id; null when no attempt answered (a cache hit or a BYOK call with no managed attempt).
  • maxLength 256
provider_accessenumyesThe answering attempt's commercial route (D3); null when no attempt answered or its route did not state one.
  • one of "OWN_DEPLOYMENT", "AUTHORIZED_WHOLESALE", "CUSTOMER_BYOK", "RESTRICTED", "UNVERIFIED", null
rate_versionstringyesThe retail rate-card version the usage was priced against (the settle request's retail.version).
usageobjectyesThe measured token counts, the same shape as billing.credit-hold-settle-request@1's usage.
  • no other fields
usage.input_tokensintegeryes
  • minimum 0
usage.cached_read_tokensintegeryes
  • minimum 0
usage.cache_write_tokensintegeryes
  • minimum 0
usage.output_tokensintegeryes
  • minimum 0
charge_nano_usdstringyesThe charge the settlement recorded, integer nano-USD (D1). Usage beyond the hold and free balance is separately shortfall_nano_usd.
  • pattern ^[0-9]{1,19}$
supply_cost_nano_usdstringyesWhat the route cost OpenVibe at supply, integer nano-USD (D1); 0 for BYOK.
  • pattern ^[0-9]{1,19}$
shortfall_nano_usdstringyesUsage beyond the hold and the free balance: owed, not collected (nano-USD, D1).
  • pattern ^[0-9]{1,19}$
released_nano_usdstringyesHold amount returned to the account, integer nano-USD (D1).
  • pattern ^[0-9]{1,19}$
byokbooleanyesTrue when the caller supplied their own provider key; the retail charge is 0.
sandboxbooleanyesTrue when the hold was funded from usd_credit_sandbox (BILLING_CREDITS_SANDBOX), never paid credit.

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: byok-sandbox
{
  "settlement_id": "stl_01JAB2C3D4E5F6G7H8J9K0MNP1",
  "hold_id": "hld_01JAB2C3D4E5F6G7H8J9K0MNP2",
  "service": "ai",
  "settled_at": "2026-11-04T12:00:07.000Z",
  "deployment_id": null,
  "provider_access": null,
  "rate_version": "rr-2026-11-03-001",
  "usage": {
    "input_tokens": 0,
    "cached_read_tokens": 0,
    "cache_write_tokens": 0,
    "output_tokens": 0
  },
  "charge_nano_usd": "0",
  "supply_cost_nano_usd": "0",
  "shortfall_nano_usd": "0",
  "released_nano_usd": "500000",
  "byok": true,
  "sandbox": true
}
Valid: managed-ai
{
  "settlement_id": "stl_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "hold_id": "hld_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "service": "ai",
  "settled_at": "2026-11-04T12:00:05.000Z",
  "deployment_id": "deepinfra:Qwen/Qwen3-Coder-30B-A3B-Instruct",
  "provider_access": "AUTHORIZED_WHOLESALE",
  "rate_version": "rr-2026-11-03-001",
  "usage": {
    "input_tokens": 1000,
    "cached_read_tokens": 0,
    "cache_write_tokens": 0,
    "output_tokens": 500
  },
  "charge_nano_usd": "11",
  "supply_cost_nano_usd": "9",
  "shortfall_nano_usd": "0",
  "released_nano_usd": "9999989",
  "byok": false,
  "sandbox": false
}
Rejected: money-number
{
  "settlement_id": "stl_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "hold_id": "hld_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "service": "ai",
  "settled_at": "2026-11-04T12:00:05.000Z",
  "deployment_id": "deepinfra:Qwen/Qwen3-Coder-30B-A3B-Instruct",
  "provider_access": "AUTHORIZED_WHOLESALE",
  "rate_version": "rr-2026-11-03-001",
  "usage": {
    "input_tokens": 1000,
    "cached_read_tokens": 0,
    "cache_write_tokens": 0,
    "output_tokens": 500
  },
  "charge_nano_usd": 11,
  "supply_cost_nano_usd": "9",
  "shortfall_nano_usd": "0",
  "released_nano_usd": "9999989",
  "byok": false,
  "sandbox": false
}
Rejected: subject-included
{
  "settlement_id": "stl_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "hold_id": "hld_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "service": "ai",
  "settled_at": "2026-11-04T12:00:05.000Z",
  "deployment_id": "deepinfra:Qwen/Qwen3-Coder-30B-A3B-Instruct",
  "provider_access": "AUTHORIZED_WHOLESALE",
  "rate_version": "rr-2026-11-03-001",
  "usage": {
    "input_tokens": 1000,
    "cached_read_tokens": 0,
    "cache_write_tokens": 0,
    "output_tokens": 500
  },
  "charge_nano_usd": "11",
  "supply_cost_nano_usd": "9",
  "shortfall_nano_usd": "0",
  "released_nano_usd": "9999989",
  "byok": false,
  "sandbox": false,
  "subject": {
    "type": "user",
    "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
  }
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('billing.credit.settled@1', value);   // { valid, errors: [{ path, message }] }