UsageSample platform.usage-sample@1
Generated at from
openvibe-contracts v0.114.0 and
openvibe-sdk v0.35.1.
- Version
- 1.0.0
- Owner
- network
- Visibility
- public
- Status
- active
- Compatibility
- backward
- Decision
- ADR-034
- Schema
https://openvibe.network/contracts/platform/usage-sample.v1.json
One metered usage reading with retry-safe attribution (T1 Universal Fabric; ADR-034 proposed). Consumers dedupe on `idempotency_key`. A running platform.job@1 `function` job is one reading per wall-clock second (service `run`, operation `function.invoke`, unit `s`, idempotency_key `run:<job id>:<second>`), derived as platform.job-frame@1 `job_usage` describes.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
id | string | yes | ||
idempotency_key | string | yes | Stable across retries. The only dedupe key, and it encodes work identity only (examples: tools:job:<id>, ai:<run>:tokens, run:<job>:<n>), never route_epoch, node, region or trace_id. | |
service | string | yes | The Contracts manifest id of the producing service (tools, ai, run). | |
project | string |
| ||
subject | string | |||
resource | string | The producing service's billing resource: the platform.rate-card@1 `metric` for this reading's `provider` (e.g. `tokens`, `queue-operation-64kb`), and never a run, job, object or other work id. The reading's `unit` must be that metric's unit, so Billing rates it against the card found by (provider, resource): a resource that names no card, or a unit the card's metric does not fit, is left unrated (`billing.no_card` / `billing.unit_mismatch`). | ||
provider | string | |||
node | string | |||
cell | string | |||
region | string | |||
operation | string | yes | ||
quantity | number | yes |
| |
unit | string | yes | ||
at | string | yes |
| |
cost_estimate | number | Estimated USD |
| |
free_allowance_used | number | How much of this reading's `quantity` the free allowance covered (platform.rate-card@1 `free_allowance` for this provider/metric and period), in the reading's own `unit`, not in rate-card units, money or Vibes: a 1.5 GiB reading with 1 GiB free carries 1. Never more than `quantity`; 0 when nothing was free. Absent: not rated against a rate card. |
| |
vibes_charged | integer | Vibes charged for this reading, as an integer count of vibes-bits (Billing's ledger minor unit, currency `vibes-bits`; balance credit and ledger amounts use the same unit). Never whole Vibes, USD or a fraction: round once, when rating. Covers only `quantity` minus `free_allowance_used`; 0 means rated and nothing charged. Absent means not rated (yet). Records a charge already made in Billing's ledger; it is never a request to charge. |
| |
route_epoch | integer | Epoch of the signed placement plan that chose where this reading ran (platform.placement-plan@1 `epoch`). A later plan supersedes it; absent when Fabric did not place the work. |
| |
trace_id | string | Opaque trace id tying this reading to the request and route that produced it, the same `trace_id` platform.telemetry-sample@1 carries; absent when the producer had no trace. | ||
source | string | yes |
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: ai-per-metric
{
"id": "use-ai-1",
"idempotency_key": "ai:run_01JAB2C3D4E5F6G7H8J9K0MNPQ:tokens",
"service": "ai",
"subject": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"provider": "openai",
"resource": "tokens",
"operation": "chat.completion",
"quantity": 1500,
"unit": "tokens",
"at": "2026-10-02T10:00:00Z",
"cost_estimate": 0.000225,
"free_allowance_used": 0,
"source": "ai.provider-router"
}Valid: all-fifteen-fields
{
"id": "use-2",
"idempotency_key": "media:delivery:2",
"service": "media",
"project": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"subject": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"resource": "object-1",
"provider": "local",
"node": "node-1",
"cell": "cell-west",
"region": "us-west",
"operation": "deliver",
"quantity": 1.5,
"unit": "GiB",
"at": "2026-09-30T10:00:00Z",
"cost_estimate": 0.03,
"source": "media.egress",
"free_allowance_used": 1,
"vibes_charged": 4,
"route_epoch": 3,
"trace_id": "tr-42"
}Valid: example
{
"id": "use-1",
"idempotency_key": "media:delivery:1",
"service": "media",
"project": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"subject": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"resource": "object-1",
"provider": "local",
"node": "node-1",
"cell": "cell-west",
"region": "us-west",
"operation": "deliver",
"quantity": 1.5,
"unit": "GiB",
"at": "2026-09-30T10:00:00Z",
"cost_estimate": 0.03,
"source": "media.egress"
}Valid: minimal
{
"id": "use-3",
"idempotency_key": "media:delivery:3",
"service": "media",
"operation": "deliver",
"quantity": 0.25,
"unit": "GiB",
"at": "2026-09-30T10:05:00Z",
"source": "media.egress"
}Valid: run-function-last-partial-second
{
"id": "run:job_01JAB2C3D4E5F6G7H8J9K0MNPQ:2",
"idempotency_key": "run:job_01JAB2C3D4E5F6G7H8J9K0MNPQ:2",
"service": "run",
"project": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"subject": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"resource": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"node": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
"operation": "function.invoke",
"quantity": 0.35,
"unit": "s",
"at": "2026-10-02T10:00:02.250Z",
"source": "openvibe-node.worker"
}Valid: run-function-second
{
"id": "run:job_01JAB2C3D4E5F6G7H8J9K0MNPQ:0",
"idempotency_key": "run:job_01JAB2C3D4E5F6G7H8J9K0MNPQ:0",
"service": "run",
"project": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"subject": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"resource": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"node": "dev_01J8Z4M2Q0R7T9YV3K6N8P1W2X",
"operation": "function.invoke",
"quantity": 1,
"unit": "s",
"at": "2026-10-02T10:00:00.250Z",
"source": "openvibe-node.worker"
}Rejected: free-allowance-used-negative
{
"id": "use-2",
"idempotency_key": "media:delivery:2",
"service": "media",
"project": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"subject": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"resource": "object-1",
"provider": "local",
"node": "node-1",
"cell": "cell-west",
"region": "us-west",
"operation": "deliver",
"quantity": 1.5,
"unit": "GiB",
"at": "2026-09-30T10:00:00Z",
"cost_estimate": 0.03,
"source": "media.egress",
"free_allowance_used": -1,
"vibes_charged": 4,
"route_epoch": 3,
"trace_id": "tr-42"
}Rejected: missing-id
{
"idempotency_key": "media:delivery:1",
"service": "media",
"project": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"subject": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"resource": "object-1",
"provider": "local",
"node": "node-1",
"cell": "cell-west",
"region": "us-west",
"operation": "deliver",
"quantity": 1.5,
"unit": "GiB",
"at": "2026-09-30T10:00:00Z",
"cost_estimate": 0.03,
"source": "media.egress"
}Rejected: vibes-charged-fraction
{
"id": "use-2",
"idempotency_key": "media:delivery:2",
"service": "media",
"project": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"subject": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"resource": "object-1",
"provider": "local",
"node": "node-1",
"cell": "cell-west",
"region": "us-west",
"operation": "deliver",
"quantity": 1.5,
"unit": "GiB",
"at": "2026-09-30T10:00:00Z",
"cost_estimate": 0.03,
"source": "media.egress",
"free_allowance_used": 1,
"vibes_charged": 1.5,
"route_epoch": 3,
"trace_id": "tr-42"
}Rejected: vibes-charged-negative
{
"id": "use-2",
"idempotency_key": "media:delivery:2",
"service": "media",
"project": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"subject": "user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"resource": "object-1",
"provider": "local",
"node": "node-1",
"cell": "cell-west",
"region": "us-west",
"operation": "deliver",
"quantity": 1.5,
"unit": "GiB",
"at": "2026-09-30T10:00:00Z",
"cost_estimate": 0.03,
"source": "media.egress",
"free_allowance_used": 1,
"vibes_charged": -1,
"route_epoch": 3,
"trace_id": "tr-42"
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('platform.usage-sample@1', value); // { valid, errors: [{ path, message }] }