openvibers/openvibe.billing Commits

Declare billing.usage.record in repo docs and note usage keying (#5)

OP OpenVibers committed 3 Oct 2026 · 37ae3292f5 · 3 files, +25 −2

local checks ✓ 3/3 · CI ✓ 3/3 · review SHIP by DeepSeek harness (QUALITY=high) · 1 fix round

https://github.com/OpenVibers/OpenVibe.Billing/pull/5

Changes

ddiff --git a/docs/capabilities-proposal/billing.usage.record.json b/docs/capabilities-proposal/billing.usage.record.json
nnew file mode 100644
iindex 0000000..ac8dcc6
---- /dev/null
++++ b/docs/capabilities-proposal/billing.usage.record.json
@@@ -0,0 +1,21 @@
++{
++ "id": "billing.usage.record",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Record a platform.usage-sample@1 reading without moving money. The reading's idempotency_key deduplicates retries. Listing all readings requires billing.ledger.admin.",
++ "permissions": [
++ "billing:usage"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "ledger-write",
++ "events": [],
++ "implementedBy": [
++ "POST /api/v1/usage"
++ ],
++ "inputSchema": "platform.usage-sample@1",
++ "outputSchema": "billing.usage-record-result@1"
++}
ddiff --git a/docs/service-manifest-proposal.json b/docs/service-manifest-proposal.json
iindex 4655950..5c3db69 100644
---- a/docs/service-manifest-proposal.json
++++ b/docs/service-manifest-proposal.json
@@@ -21,7 +21,8 @@
"billing.cashout.manage",
"billing.subscription.manage",
"billing.entitlement.check",
-- "billing.ledger.admin"
++ "billing.ledger.admin",
++ "billing.usage.record"
],
"eventsProduced": [
"billing.transaction.settled",
ddiff --git a/server/api/v1.js b/server/api/v1.js
iindex ddcc1d1..c3fcde0 100644
---- a/server/api/v1.js
++++ b/server/api/v1.js
@@@ -2,7 +2,8 @@
/**
* /api/v1 — the operations API. Service tokens only (audience openvibe.billing); Live is the
-- * first client. Every mutating call needs an Idempotency-Key and is refused with 503
++ * first client. Every mutating call needs an Idempotency-Key — except POST /api/v1/usage,
++ * which is keyed by the reading's own idempotency_key — and is refused with 503
* billing.frozen while the economy is frozen (reads keep working).
*
* Amounts are integers: bits for Vibes (vibes-bits), cents for money (usd-cents). People are