openvibers/openvibe.contracts Commits

Contracts 0.201.0: subscription tiers priced by Billing (billing.tier.manage, tier-request/result, optional tier on intents, credit subscriptions and entitlements) (#181)

OP OpenVibers committed 27 days ago · 00ec5ecd0a · 59 files, +762 −83

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 9fb72968..6469632b 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -4,6 +4,15 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
the notes were in the tag and commit messages (`git tag -n1`).
++## 0.201.0 — 2026-10-17
++
++- Subscription tiers priced by OpenVibe.Billing (the owner's VIP ask: creator memberships with tiers). New capability
++ `billing.tier.manage` (`GET /api/v1/tiers/:streamer`, `PUT /api/v1/tiers/:streamer/:tier`) with `billing.tier-request@1`
++ and `billing.tier-result@1`: the product where a creator sells tiers (OpenVibe.VIP) sets each tier's monthly price
++ within Billing's bounds; Billing keeps and charges it (ADR-012). Optional `tier` on `billing.intent-request@1`
++ (subscriptions), `billing.subscription-request@1` and `billing.entitlement@1`. Tier 1 without a price keeps the site's
++ default subscription price, so nothing changes for anyone who does not set tiers.
++
## 0.200.0 — 2026-10-17
- OpenVibe.Tips and OpenVibe.VIP are live sites (`exposure.state: live`, `publicSite: service`) now that OpenVibe.Billing is
ddiff --git a/contracts/billing/entitlement.v1.json b/contracts/billing/entitlement.v1.json
iindex 7d39feb0..fb5ecbc2 100644
---- a/contracts/billing/entitlement.v1.json
++++ b/contracts/billing/entitlement.v1.json
@@@ -11,6 +11,7 @@
"kind": { "type": "string" },
"active": { "type": "boolean" },
"expires_at": { "type": ["string", "null"] },
++ "tier": { "type": ["integer", "null"], "description": "The subscription's tier (1 unless the creator sells tiers); null without a subscription." },
"subscription": {
"type": ["object", "null"],
"properties": {
ddiff --git a/contracts/billing/intent-request.v1.json b/contracts/billing/intent-request.v1.json
iindex 02e57c3c..aa4352d9 100644
---- a/contracts/billing/intent-request.v1.json
++++ b/contracts/billing/intent-request.v1.json
@@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/billing/intent-request.v1.json",
"title": "BillingIntentRequest",
-- "description": "billing.intent-request@1: the body of POST /api/v1/intents on OpenVibe.Billing (billing.intent.create): a checkout with an enabled provider for a Vibes purchase ({ kind: purchase, bits } at least the minimum purchase) or a channel subscription ({ kind: subscription, streamer }; route direct pays the streamer's own account, and a direct PowerChat subscription names receiving_account). Billing prices it; the answer is { intent, checkout_url } (201). GET /api/v1/intents/:id and POST /api/v1/intents/:id/capture take no body. Every mutating call needs an Idempotency-Key header (a replay with the same key and body returns the first answer) and is refused with 503 billing.frozen while the economy is frozen. Refusals are problem+json (billing.invalid_input, billing.invalid_amount, billing.insufficient_funds, …).",
++ "description": "billing.intent-request@1: the body of POST /api/v1/intents on OpenVibe.Billing (billing.intent.create): a checkout with an enabled provider for a Vibes purchase ({ kind: purchase, bits } at least the minimum purchase) or a channel subscription ({ kind: subscription, streamer, tier? } at the tier's price; route direct pays the streamer's own account, and a direct PowerChat subscription names receiving_account). Billing prices it; the answer is { intent, checkout_url } (201). GET /api/v1/intents/:id and POST /api/v1/intents/:id/capture take no body. Every mutating call needs an Idempotency-Key header (a replay with the same key and body returns the first answer) and is refused with 503 billing.frozen while the economy is frozen. Refusals are problem+json (billing.invalid_input, billing.invalid_amount, billing.insufficient_funds, …).",
"anyOf": [
{
"type": "object",
@@@ -75,6 +75,15 @@
},
"cancel_url": {
"type": "string"
++ },
++ "tier": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]?$",
++ "description": "Subscription: the creator's tier (1 by default), priced by Billing (billing.tier.manage)."
}
}
},
ddiff --git a/contracts/billing/subscription-request.v1.json b/contracts/billing/subscription-request.v1.json
iindex 9be97a4e..fe33edeb 100644
---- a/contracts/billing/subscription-request.v1.json
++++ b/contracts/billing/subscription-request.v1.json
@@@ -94,6 +94,15 @@
"type": "boolean"
}
}
++ },
++ "tier": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]?$",
++ "description": "The creator's tier (1 by default): a credit-paid period costs the tier's price (billing.tier.manage); a renewal keeps the price the subscription was bought at."
}
}
},
ddiff --git a/contracts/billing/tier-request.v1.json b/contracts/billing/tier-request.v1.json
nnew file mode 100644
iindex 00000000..5b75d298
---- /dev/null
++++ b/contracts/billing/tier-request.v1.json
@@@ -0,0 +1,28 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/billing/tier-request.v1.json",
++ "title": "BillingTierRequest",
++ "description": "billing.tier-request@1: the body of PUT /api/v1/tiers/:streamer/:tier on OpenVibe.Billing (billing.tier.manage): the monthly price of one of a creator's subscription tiers (1 to max_tiers), which the creator chooses on the product that sells it (OpenVibe.VIP) and Billing keeps and charges (ADR-012: Billing prices, products never do). price_cents must be within Billing's bounds (min_price_cents to max_price_cents, from GET /api/v1/tiers/:streamer or /api/v1/rates). status archived stops new subscriptions to the tier; running ones renew at the price they were bought at. A tier without a row: tier 1 is sold at the site's default subscription price, any other tier is refused (billing.tier_unknown). GET /api/v1/tiers/:streamer takes no body. The PUT needs an Idempotency-Key header and is refused with 503 billing.frozen while the economy is frozen.",
++ "type": "object",
++ "required": [
++ "price_cents"
++ ],
++ "properties": {
++ "price_cents": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]*$",
++ "description": "USD cents per period (a month)."
++ },
++ "status": {
++ "enum": [
++ "active",
++ "archived"
++ ],
++ "description": "active (the default) sells the tier; archived sells it no more."
++ }
++ }
++}
ddiff --git a/contracts/billing/tier-result.v1.json b/contracts/billing/tier-result.v1.json
nnew file mode 100644
iindex 00000000..002dfe59
---- /dev/null
++++ b/contracts/billing/tier-result.v1.json
@@@ -0,0 +1,82 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/billing/tier-result.v1.json",
++ "title": "BillingTierResult",
++ "description": "billing.tier-result@1: answers of billing.tier.manage on OpenVibe.Billing. GET /api/v1/tiers/:streamer → { streamer, tiers, default_price_cents, min_price_cents, max_price_cents, max_tiers } (tiers: every tier with a price, archived included; tier 1 without a row is sold at default_price_cents); PUT /api/v1/tiers/:streamer/:tier → { tier }.",
++ "anyOf": [
++ {
++ "type": "object",
++ "required": [
++ "streamer",
++ "tiers",
++ "default_price_cents",
++ "min_price_cents",
++ "max_price_cents",
++ "max_tiers"
++ ],
++ "properties": {
++ "streamer": {
++ "$ref": "../identity/subject-ref.v1.json"
++ },
++ "tiers": {
++ "type": "array",
++ "items": {
++ "$ref": "#/$defs/tier"
++ }
++ },
++ "default_price_cents": {
++ "type": "integer"
++ },
++ "min_price_cents": {
++ "type": "integer"
++ },
++ "max_price_cents": {
++ "type": "integer"
++ },
++ "max_tiers": {
++ "type": "integer"
++ }
++ }
++ },
++ {
++ "type": "object",
++ "required": [
++ "tier"
++ ],
++ "properties": {
++ "tier": {
++ "$ref": "#/$defs/tier"
++ }
++ }
++ }
++ ],
++ "$defs": {
++ "tier": {
++ "type": "object",
++ "required": [
++ "tier",
++ "price_cents",
++ "status"
++ ],
++ "properties": {
++ "tier": {
++ "type": "integer",
++ "minimum": 1
++ },
++ "price_cents": {
++ "type": "integer",
++ "minimum": 1
++ },
++ "status": {
++ "enum": [
++ "active",
++ "archived"
++ ]
++ },
++ "updated_at": {
++ "type": "string"
++ }
++ }
++ }
++ }
++}
ddiff --git a/contracts/catalog.json b/contracts/catalog.json
iindex 4d8569e8..0db71757 100644
---- a/contracts/catalog.json
++++ b/contracts/catalog.json
@@@ -2249,6 +2249,24 @@
"compatibility": "backward",
"status": "active"
},
++ {
++ "id": "billing.tier-request",
++ "version": "1.0.0",
++ "owner": "billing",
++ "schema": "billing/tier-request.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "billing.tier-result",
++ "version": "1.0.0",
++ "owner": "billing",
++ "schema": "billing/tier-result.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
{
"id": "billing.subscription",
"version": "1.0.0",
ddiff --git a/fixtures/billing.subscription-request/valid/tier.json b/fixtures/billing.subscription-request/valid/tier.json
nnew file mode 100644
iindex 00000000..01c21aa1
---- /dev/null
++++ b/fixtures/billing.subscription-request/valid/tier.json
@@@ -0,0 +1 @@
++{ "subscriber": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ", "streamer": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR", "source": "credit", "tier": 2 }
ddiff --git a/fixtures/billing.tier-request/invalid/no-price.json b/fixtures/billing.tier-request/invalid/no-price.json
nnew file mode 100644
iindex 00000000..4068426c
---- /dev/null
++++ b/fixtures/billing.tier-request/invalid/no-price.json
@@@ -0,0 +1 @@
++{ "status": "active" }
ddiff --git a/fixtures/billing.tier-request/invalid/unknown-status.json b/fixtures/billing.tier-request/invalid/unknown-status.json
nnew file mode 100644
iindex 00000000..eb84cade
---- /dev/null
++++ b/fixtures/billing.tier-request/invalid/unknown-status.json
@@@ -0,0 +1 @@
++{ "price_cents": 999, "status": "paused" }
ddiff --git a/fixtures/billing.tier-request/valid/archived.json b/fixtures/billing.tier-request/valid/archived.json
nnew file mode 100644
iindex 00000000..deca98b9
---- /dev/null
++++ b/fixtures/billing.tier-request/valid/archived.json
@@@ -0,0 +1 @@
++{ "price_cents": "1500", "status": "archived" }
ddiff --git a/fixtures/billing.tier-request/valid/price.json b/fixtures/billing.tier-request/valid/price.json
nnew file mode 100644
iindex 00000000..6c7656c9
---- /dev/null
++++ b/fixtures/billing.tier-request/valid/price.json
@@@ -0,0 +1 @@
++{ "price_cents": 999 }
ddiff --git a/fixtures/billing.tier-result/invalid/tier-zero.json b/fixtures/billing.tier-result/invalid/tier-zero.json
nnew file mode 100644
iindex 00000000..cb16477c
---- /dev/null
++++ b/fixtures/billing.tier-result/invalid/tier-zero.json
@@@ -0,0 +1 @@
++{ "tier": { "tier": 0, "price_cents": 1500, "status": "active" } }
ddiff --git a/fixtures/billing.tier-result/valid/list.json b/fixtures/billing.tier-result/valid/list.json
nnew file mode 100644
iindex 00000000..65b83a81
---- /dev/null
++++ b/fixtures/billing.tier-result/valid/list.json
@@@ -0,0 +1 @@
++{ "streamer": { "type": "user", "id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR" }, "tiers": [{ "tier": 1, "price_cents": 499, "status": "active", "updated_at": "2026-10-17T06:00:00.000Z" }, { "tier": 2, "price_cents": 1500, "status": "active" }], "default_price_cents": 499, "min_price_cents": 100, "max_price_cents": 50000, "max_tiers": 10 }
ddiff --git a/fixtures/billing.tier-result/valid/put.json b/fixtures/billing.tier-result/valid/put.json
nnew file mode 100644
iindex 00000000..6f58b852
---- /dev/null
++++ b/fixtures/billing.tier-result/valid/put.json
@@@ -0,0 +1 @@
++{ "tier": { "tier": 2, "price_cents": 1500, "status": "active" } }
ddiff --git a/generated/json-schema/bundle.json b/generated/json-schema/bundle.json
iindex ab118272..349bd5ce 100644
---- a/generated/json-schema/bundle.json
++++ b/generated/json-schema/bundle.json
@@@ -23865,6 +23865,13 @@
"null"
]
},
++ "tier": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "description": "The subscription's tier (1 unless the creator sells tiers); null without a subscription."
++ },
"subscription": {
"type": [
"object",
@@@ -23905,7 +23912,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/billing/intent-request.v1.json",
"title": "BillingIntentRequest",
-- "description": "billing.intent-request@1: the body of POST /api/v1/intents on OpenVibe.Billing (billing.intent.create): a checkout with an enabled provider for a Vibes purchase ({ kind: purchase, bits } at least the minimum purchase) or a channel subscription ({ kind: subscription, streamer }; route direct pays the streamer's own account, and a direct PowerChat subscription names receiving_account). Billing prices it; the answer is { intent, checkout_url } (201). GET /api/v1/intents/:id and POST /api/v1/intents/:id/capture take no body. Every mutating call needs an Idempotency-Key header (a replay with the same key and body returns the first answer) and is refused with 503 billing.frozen while the economy is frozen. Refusals are problem+json (billing.invalid_input, billing.invalid_amount, billing.insufficient_funds, …).",
++ "description": "billing.intent-request@1: the body of POST /api/v1/intents on OpenVibe.Billing (billing.intent.create): a checkout with an enabled provider for a Vibes purchase ({ kind: purchase, bits } at least the minimum purchase) or a channel subscription ({ kind: subscription, streamer, tier? } at the tier's price; route direct pays the streamer's own account, and a direct PowerChat subscription names receiving_account). Billing prices it; the answer is { intent, checkout_url } (201). GET /api/v1/intents/:id and POST /api/v1/intents/:id/capture take no body. Every mutating call needs an Idempotency-Key header (a replay with the same key and body returns the first answer) and is refused with 503 billing.frozen while the economy is frozen. Refusals are problem+json (billing.invalid_input, billing.invalid_amount, billing.insufficient_funds, …).",
"anyOf": [
{
"type": "object",
@@@ -23978,6 +23985,15 @@
},
"cancel_url": {
"type": "string"
++ },
++ "tier": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]?$",
++ "description": "Subscription: the creator's tier (1 by default), priced by Billing (billing.tier.manage)."
}
}
},
@@@ -24218,6 +24234,15 @@
"type": "boolean"
}
}
++ },
++ "tier": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]?$",
++ "description": "The creator's tier (1 by default): a credit-paid period costs the tier's price (billing.tier.manage); a renewal keeps the price the subscription was bought at."
}
}
},
@@@ -24275,6 +24300,126 @@
]
}
},
++ "billing.tier-request": {
++ "version": "1.0.0",
++ "owner": "billing",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/billing/tier-request.v1.json",
++ "title": "BillingTierRequest",
++ "description": "billing.tier-request@1: the body of PUT /api/v1/tiers/:streamer/:tier on OpenVibe.Billing (billing.tier.manage): the monthly price of one of a creator's subscription tiers (1 to max_tiers), which the creator chooses on the product that sells it (OpenVibe.VIP) and Billing keeps and charges (ADR-012: Billing prices, products never do). price_cents must be within Billing's bounds (min_price_cents to max_price_cents, from GET /api/v1/tiers/:streamer or /api/v1/rates). status archived stops new subscriptions to the tier; running ones renew at the price they were bought at. A tier without a row: tier 1 is sold at the site's default subscription price, any other tier is refused (billing.tier_unknown). GET /api/v1/tiers/:streamer takes no body. The PUT needs an Idempotency-Key header and is refused with 503 billing.frozen while the economy is frozen.",
++ "type": "object",
++ "required": [
++ "price_cents"
++ ],
++ "properties": {
++ "price_cents": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]*$",
++ "description": "USD cents per period (a month)."
++ },
++ "status": {
++ "enum": [
++ "active",
++ "archived"
++ ],
++ "description": "active (the default) sells the tier; archived sells it no more."
++ }
++ }
++ }
++ },
++ "billing.tier-result": {
++ "version": "1.0.0",
++ "owner": "billing",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/billing/tier-result.v1.json",
++ "title": "BillingTierResult",
++ "description": "billing.tier-result@1: answers of billing.tier.manage on OpenVibe.Billing. GET /api/v1/tiers/:streamer → { streamer, tiers, default_price_cents, min_price_cents, max_price_cents, max_tiers } (tiers: every tier with a price, archived included; tier 1 without a row is sold at default_price_cents); PUT /api/v1/tiers/:streamer/:tier → { tier }.",
++ "anyOf": [
++ {
++ "type": "object",
++ "required": [
++ "streamer",
++ "tiers",
++ "default_price_cents",
++ "min_price_cents",
++ "max_price_cents",
++ "max_tiers"
++ ],
++ "properties": {
++ "streamer": {
++ "$ref": "../identity/subject-ref.v1.json"
++ },
++ "tiers": {
++ "type": "array",
++ "items": {
++ "$ref": "#/$defs/tier"
++ }
++ },
++ "default_price_cents": {
++ "type": "integer"
++ },
++ "min_price_cents": {
++ "type": "integer"
++ },
++ "max_price_cents": {
++ "type": "integer"
++ },
++ "max_tiers": {
++ "type": "integer"
++ }
++ }
++ },
++ {
++ "type": "object",
++ "required": [
++ "tier"
++ ],
++ "properties": {
++ "tier": {
++ "$ref": "#/$defs/tier"
++ }
++ }
++ }
++ ],
++ "$defs": {
++ "tier": {
++ "type": "object",
++ "required": [
++ "tier",
++ "price_cents",
++ "status"
++ ],
++ "properties": {
++ "tier": {
++ "type": "integer",
++ "minimum": 1
++ },
++ "price_cents": {
++ "type": "integer",
++ "minimum": 1
++ },
++ "status": {
++ "enum": [
++ "active",
++ "archived"
++ ]
++ },
++ "updated_at": {
++ "type": "string"
++ }
++ }
++ }
++ }
++ }
++ },
"billing.subscription": {
"version": "1.0.0",
"owner": "billing",
ddiff --git a/generated/openapi/actor.json b/generated/openapi/actor.json
iindex b5d0cfb0..7ea5c55d 100644
---- a/generated/openapi/actor.json
++++ b/generated/openapi/actor.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Actor API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/ai.json b/generated/openapi/ai.json
iindex 914f325a..4d8348e1 100644
---- a/generated/openapi/ai.json
++++ b/generated/openapi/ai.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.AI API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/billing.json b/generated/openapi/billing.json
iindex e363470f..ed50105b 100644
---- a/generated/openapi/billing.json
++++ b/generated/openapi/billing.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Billing API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
@@@ -1399,6 +1399,167 @@
}
}
},
++ "/api/v1/tiers/{streamer}": {
++ "get": {
++ "operationId": "get_api_v1_tiers_streamer",
++ "summary": "Read and set the monthly prices of a creator's subscription tiers, for the product where the creator sells them (OpenVibe.VIP), within Billing's bounds.",
++ "description": "**billing.tier.manage** (internal): Read and set the monthly prices of a creator's subscription tiers, for the product where the creator sells them (OpenVibe.VIP), within Billing's bounds. Billing keeps the price and charges it: new subscriptions to a tier pay its price, running ones renew at the price they were bought at.",
++ "tags": [
++ "billing.tier"
++ ],
++ "x-openvibe-capabilities": [
++ "billing.tier.manage"
++ ],
++ "x-openvibe-visibility": [
++ "internal"
++ ],
++ "x-openvibe-quota-class": "ledger-write",
++ "security": [
++ {
++ "openvibeToken": [
++ "billing.tier.manage"
++ ]
++ }
++ ],
++ "x-openvibe-input": {
++ "$ref": "#/components/schemas/billing.tier-request.v1"
++ },
++ "parameters": [
++ {
++ "name": "streamer",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ },
++ {
++ "name": "price_cents",
++ "in": "query",
++ "required": true,
++ "schema": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]*$",
++ "description": "USD cents per period (a month)."
++ },
++ "description": "USD cents per period (a month)."
++ },
++ {
++ "name": "status",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "enum": [
++ "active",
++ "archived"
++ ],
++ "description": "active (the default) sells the tier; archived sells it no more."
++ },
++ "description": "active (the default) sells the tier; archived sells it no more."
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/billing.tier-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ "/api/v1/tiers/{streamer}/{tier}": {
++ "put": {
++ "operationId": "put_api_v1_tiers_streamer_tier",
++ "summary": "Read and set the monthly prices of a creator's subscription tiers, for the product where the creator sells them (OpenVibe.VIP), within Billing's bounds.",
++ "description": "**billing.tier.manage** (internal): Read and set the monthly prices of a creator's subscription tiers, for the product where the creator sells them (OpenVibe.VIP), within Billing's bounds. Billing keeps the price and charges it: new subscriptions to a tier pay its price, running ones renew at the price they were bought at.",
++ "tags": [
++ "billing.tier"
++ ],
++ "x-openvibe-capabilities": [
++ "billing.tier.manage"
++ ],
++ "x-openvibe-visibility": [
++ "internal"
++ ],
++ "x-openvibe-quota-class": "ledger-write",
++ "security": [
++ {
++ "openvibeToken": [
++ "billing.tier.manage"
++ ]
++ }
++ ],
++ "requestBody": {
++ "required": false,
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/billing.tier-request.v1"
++ }
++ }
++ }
++ },
++ "parameters": [
++ {
++ "name": "streamer",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ },
++ {
++ "name": "tier",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/billing.tier-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
"/api/v1/transactions": {
"get": {
"operationId": "get_api_v1_transactions",
@@@ -2631,6 +2792,13 @@
"null"
]
},
++ "tier": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "description": "The subscription's tier (1 unless the creator sells tiers); null without a subscription."
++ },
"subscription": {
"type": [
"object",
@@@ -2664,7 +2832,7 @@
},
"billing.intent-request.v1": {
"title": "BillingIntentRequest",
-- "description": "billing.intent-request@1: the body of POST /api/v1/intents on OpenVibe.Billing (billing.intent.create): a checkout with an enabled provider for a Vibes purchase ({ kind: purchase, bits } at least the minimum purchase) or a channel subscription ({ kind: subscription, streamer }; route direct pays the streamer's own account, and a direct PowerChat subscription names receiving_account). Billing prices it; the answer is { intent, checkout_url } (201). GET /api/v1/intents/:id and POST /api/v1/intents/:id/capture take no body. Every mutating call needs an Idempotency-Key header (a replay with the same key and body returns the first answer) and is refused with 503 billing.frozen while the economy is frozen. Refusals are problem+json (billing.invalid_input, billing.invalid_amount, billing.insufficient_funds, …).",
++ "description": "billing.intent-request@1: the body of POST /api/v1/intents on OpenVibe.Billing (billing.intent.create): a checkout with an enabled provider for a Vibes purchase ({ kind: purchase, bits } at least the minimum purchase) or a channel subscription ({ kind: subscription, streamer, tier? } at the tier's price; route direct pays the streamer's own account, and a direct PowerChat subscription names receiving_account). Billing prices it; the answer is { intent, checkout_url } (201). GET /api/v1/intents/:id and POST /api/v1/intents/:id/capture take no body. Every mutating call needs an Idempotency-Key header (a replay with the same key and body returns the first answer) and is refused with 503 billing.frozen while the economy is frozen. Refusals are problem+json (billing.invalid_input, billing.invalid_amount, billing.insufficient_funds, …).",
"anyOf": [
{
"type": "object",
@@@ -2737,6 +2905,15 @@
},
"cancel_url": {
"type": "string"
++ },
++ "tier": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]?$",
++ "description": "Subscription: the creator's tier (1 by default), priced by Billing (billing.tier.manage)."
}
}
},
@@@ -2956,6 +3133,15 @@
"type": "boolean"
}
}
++ },
++ "tier": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]?$",
++ "description": "The creator's tier (1 by default): a credit-paid period costs the tier's price (billing.tier.manage); a renewal keeps the price the subscription was bought at."
}
}
},
@@@ -3080,6 +3266,112 @@
}
}
},
++ "billing.tier-request.v1": {
++ "title": "BillingTierRequest",
++ "description": "billing.tier-request@1: the body of PUT /api/v1/tiers/:streamer/:tier on OpenVibe.Billing (billing.tier.manage): the monthly price of one of a creator's subscription tiers (1 to max_tiers), which the creator chooses on the product that sells it (OpenVibe.VIP) and Billing keeps and charges (ADR-012: Billing prices, products never do). price_cents must be within Billing's bounds (min_price_cents to max_price_cents, from GET /api/v1/tiers/:streamer or /api/v1/rates). status archived stops new subscriptions to the tier; running ones renew at the price they were bought at. A tier without a row: tier 1 is sold at the site's default subscription price, any other tier is refused (billing.tier_unknown). GET /api/v1/tiers/:streamer takes no body. The PUT needs an Idempotency-Key header and is refused with 503 billing.frozen while the economy is frozen.",
++ "type": "object",
++ "required": [
++ "price_cents"
++ ],
++ "properties": {
++ "price_cents": {
++ "type": [
++ "integer",
++ "string"
++ ],
++ "minimum": 1,
++ "pattern": "^[1-9][0-9]*$",
++ "description": "USD cents per period (a month)."
++ },
++ "status": {
++ "enum": [
++ "active",
++ "archived"
++ ],
++ "description": "active (the default) sells the tier; archived sells it no more."
++ }
++ }
++ },
++ "billing.tier-result.v1": {
++ "title": "BillingTierResult",
++ "description": "billing.tier-result@1: answers of billing.tier.manage on OpenVibe.Billing. GET /api/v1/tiers/:streamer → { streamer, tiers, default_price_cents, min_price_cents, max_price_cents, max_tiers } (tiers: every tier with a price, archived included; tier 1 without a row is sold at default_price_cents); PUT /api/v1/tiers/:streamer/:tier → { tier }.",
++ "anyOf": [
++ {
++ "type": "object",
++ "required": [
++ "streamer",
++ "tiers",
++ "default_price_cents",
++ "min_price_cents",
++ "max_price_cents",
++ "max_tiers"
++ ],
++ "properties": {
++ "streamer": {
++ "$ref": "#/components/schemas/identity.subject-ref.v1"
++ },
++ "tiers": {
++ "type": "array",
++ "items": {
++ "$ref": "#/components/schemas/billing.tier-result.v1/$defs/tier"
++ }
++ },
++ "default_price_cents": {
++ "type": "integer"
++ },
++ "min_price_cents": {
++ "type": "integer"
++ },
++ "max_price_cents": {
++ "type": "integer"
++ },
++ "max_tiers": {
++ "type": "integer"
++ }
++ }
++ },
++ {
++ "type": "object",
++ "required": [
++ "tier"
++ ],
++ "properties": {
++ "tier": {
++ "$ref": "#/components/schemas/billing.tier-result.v1/$defs/tier"
++ }
++ }
++ }
++ ],
++ "$defs": {
++ "tier": {
++ "type": "object",
++ "required": [
++ "tier",
++ "price_cents",
++ "status"
++ ],
++ "properties": {
++ "tier": {
++ "type": "integer",
++ "minimum": 1
++ },
++ "price_cents": {
++ "type": "integer",
++ "minimum": 1
++ },
++ "status": {
++ "enum": [
++ "active",
++ "archived"
++ ]
++ },
++ "updated_at": {
++ "type": "string"
++ }
++ }
++ }
++ }
++ },
"billing.transaction.v1": {
"title": "BillingTransaction",
"description": "billing.transaction@1: one journal transaction as OpenVibe.Billing's /api/v1 presents it (server/ledger.js present). Amounts are integers: bits for vibes-bits, cents for usd-cents; each transaction's entries balance per currency. Subjects are bare Network subject ids.",
ddiff --git a/generated/openapi/blog.json b/generated/openapi/blog.json
iindex 068dd884..eed325ea 100644
---- a/generated/openapi/blog.json
++++ b/generated/openapi/blog.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Blog API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/bot.json b/generated/openapi/bot.json
iindex 5168921d..07415e0a 100644
---- a/generated/openapi/bot.json
++++ b/generated/openapi/bot.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Bot API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/chat.json b/generated/openapi/chat.json
iindex 5de67ff1..f7596363 100644
---- a/generated/openapi/chat.json
++++ b/generated/openapi/chat.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Chat API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/codes.json b/generated/openapi/codes.json
iindex 5750405e..6ab449a2 100644
---- a/generated/openapi/codes.json
++++ b/generated/openapi/codes.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Codes API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/community.json b/generated/openapi/community.json
iindex d3e4fd86..59fde2c4 100644
---- a/generated/openapi/community.json
++++ b/generated/openapi/community.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Community API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/coupons.json b/generated/openapi/coupons.json
iindex c934925d..d69b5ed7 100644
---- a/generated/openapi/coupons.json
++++ b/generated/openapi/coupons.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Coupons API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/deals.json b/generated/openapi/deals.json
iindex f34e2efc..48721680 100644
---- a/generated/openapi/deals.json
++++ b/generated/openapi/deals.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Deals API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/events.json b/generated/openapi/events.json
iindex 17532a2e..8ea22070 100644
---- a/generated/openapi/events.json
++++ b/generated/openapi/events.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Events API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/food.json b/generated/openapi/food.json
iindex eb7cfd11..3ed54704 100644
---- a/generated/openapi/food.json
++++ b/generated/openapi/food.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Food API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/games.json b/generated/openapi/games.json
iindex a13cdf56..7625ca77 100644
---- a/generated/openapi/games.json
++++ b/generated/openapi/games.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Games API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/host.json b/generated/openapi/host.json
iindex c3b0ae41..e21374a2 100644
---- a/generated/openapi/host.json
++++ b/generated/openapi/host.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Host API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/index.json b/generated/openapi/index.json
iindex efcf4d78..bcf1768d 100644
---- a/generated/openapi/index.json
++++ b/generated/openapi/index.json
@@@ -19,8 +19,8 @@
"service": "billing",
"name": "OpenVibe.Billing",
"origin": "https://billing.openvibe.network",
-- "operations": 30,
-- "capabilities": 9
++ "operations": 32,
++ "capabilities": 10
},
{
"service": "blog",
ddiff --git a/generated/openapi/inventory.json b/generated/openapi/inventory.json
iindex 71aebece..8ec56e6c 100644
---- a/generated/openapi/inventory.json
++++ b/generated/openapi/inventory.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Inventory API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/live.json b/generated/openapi/live.json
iindex 0e0488e3..1b21c468 100644
---- a/generated/openapi/live.json
++++ b/generated/openapi/live.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Live API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media-hub.json b/generated/openapi/media-hub.json
iindex 78298a75..cfd8d360 100644
---- a/generated/openapi/media-hub.json
++++ b/generated/openapi/media-hub.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.MediaHub API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media.json b/generated/openapi/media.json
iindex 10b59c5d..fff416d7 100644
---- a/generated/openapi/media.json
++++ b/generated/openapi/media.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Media API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/network.json b/generated/openapi/network.json
iindex 9b88d341..b544846b 100644
---- a/generated/openapi/network.json
++++ b/generated/openapi/network.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Network API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/news.json b/generated/openapi/news.json
iindex 25e8be0a..8f542cc8 100644
---- a/generated/openapi/news.json
++++ b/generated/openapi/news.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.News API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/openre.json b/generated/openapi/openre.json
iindex 7bae7f84..ba8c14c9 100644
---- a/generated/openapi/openre.json
++++ b/generated/openapi/openre.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenRestream API",
-- "version": "0.200.0",
-- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/play.json b/generated/openapi/play.json
iindex e9cc5ecb..e1619972 100644
---- a/generated/openapi/play.json
++++ b/generated/openapi/play.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Play API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/quest.json b/generated/openapi/quest.json
iindex f3763a5b..89e5afd1 100644
---- a/generated/openapi/quest.json
++++ b/generated/openapi/quest.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Quest API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/reviews.json b/generated/openapi/reviews.json
iindex 24b77d32..e753e897 100644
---- a/generated/openapi/reviews.json
++++ b/generated/openapi/reviews.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Reviews API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/run.json b/generated/openapi/run.json
iindex 724b5016..bb8860a0 100644
---- a/generated/openapi/run.json
++++ b/generated/openapi/run.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Run API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/search.json b/generated/openapi/search.json
iindex 3d6cd8d8..ca26340f 100644
---- a/generated/openapi/search.json
++++ b/generated/openapi/search.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Search API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/services.json b/generated/openapi/services.json
iindex cb098e02..7aeb988e 100644
---- a/generated/openapi/services.json
++++ b/generated/openapi/services.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Services API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/sources.json b/generated/openapi/sources.json
iindex 5f3c9f3b..ec4a1d8e 100644
---- a/generated/openapi/sources.json
++++ b/generated/openapi/sources.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Sources API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/space.json b/generated/openapi/space.json
iindex a77c4370..08c8b8ec 100644
---- a/generated/openapi/space.json
++++ b/generated/openapi/space.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Space API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tips.json b/generated/openapi/tips.json
iindex be24e10b..7b13be9a 100644
---- a/generated/openapi/tips.json
++++ b/generated/openapi/tips.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tips API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tools.json b/generated/openapi/tools.json
iindex 955d7e52..89f89338 100644
---- a/generated/openapi/tools.json
++++ b/generated/openapi/tools.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tools API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/trade.json b/generated/openapi/trade.json
iindex 68e72beb..ef2d2add 100644
---- a/generated/openapi/trade.json
++++ b/generated/openapi/trade.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Trade API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/vip.json b/generated/openapi/vip.json
iindex 507e63bf..8af0fc4e 100644
---- a/generated/openapi/vip.json
++++ b/generated/openapi/vip.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.VIP API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/watch.json b/generated/openapi/watch.json
iindex ffa4b5a7..5da56346 100644
---- a/generated/openapi/watch.json
++++ b/generated/openapi/watch.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Watch API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/wiki.json b/generated/openapi/wiki.json
iindex 702d59ab..88f1b894 100644
---- a/generated/openapi/wiki.json
++++ b/generated/openapi/wiki.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Wiki API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/work.json b/generated/openapi/work.json
iindex 5cfc23ca..7b418292 100644
---- a/generated/openapi/work.json
++++ b/generated/openapi/work.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Work API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/zone.json b/generated/openapi/zone.json
iindex 3dc24148..fd97dd6c 100644
---- a/generated/openapi/zone.json
++++ b/generated/openapi/zone.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Zone API",
-- "version": "0.200.0",
-- "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.200.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.201.0",
++ "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.201.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/typescript/index.d.ts b/generated/typescript/index.d.ts
iindex 4632c565..2230e0fe 100644
---- a/generated/typescript/index.d.ts
++++ b/generated/typescript/index.d.ts
@@@ -149342,6 +149342,10 @@ export interface BillingEntitlement {
kind: string;
active: boolean;
expires_at: string | null;
++ /**
++ * The subscription's tier (1 unless the creator sells tiers); null without a subscription.
++ */
++ tier?: number | null;
subscription: {
id?: string;
status?: string;
@@@ -149353,7 +149357,7 @@ export interface BillingEntitlement {
/** [email protected] (owner: billing) */
/**
-- * billing.intent-request@1: the body of POST /api/v1/intents on OpenVibe.Billing (billing.intent.create): a checkout with an enabled provider for a Vibes purchase ({ kind: purchase, bits } at least the minimum purchase) or a channel subscription ({ kind: subscription, streamer }; route direct pays the streamer's own account, and a direct PowerChat subscription names receiving_account). Billing prices it; the answer is { intent, checkout_url } (201). GET /api/v1/intents/:id and POST /api/v1/intents/:id/capture take no body. Every mutating call needs an Idempotency-Key header (a replay with the same key and body returns the first answer) and is refused with 503 billing.frozen while the economy is frozen. Refusals are problem+json (billing.invalid_input, billing.invalid_amount, billing.insufficient_funds, …).
++ * billing.intent-request@1: the body of POST /api/v1/intents on OpenVibe.Billing (billing.intent.create): a checkout with an enabled provider for a Vibes purchase ({ kind: purchase, bits } at least the minimum purchase) or a channel subscription ({ kind: subscription, streamer, tier? } at the tier's price; route direct pays the streamer's own account, and a direct PowerChat subscription names receiving_account). Billing prices it; the answer is { intent, checkout_url } (201). GET /api/v1/intents/:id and POST /api/v1/intents/:id/capture take no body. Every mutating call needs an Idempotency-Key header (a replay with the same key and body returns the first answer) and is refused with 503 billing.frozen while the economy is frozen. Refusals are problem+json (billing.invalid_input, billing.invalid_amount, billing.insufficient_funds, …).
*/
export type BillingIntentRequest =
| {
@@@ -149385,6 +149389,10 @@ export type BillingIntentRequest =
auto_renew?: boolean | number;
success_url?: string;
cancel_url?: string;
++ /**
++ * Subscription: the creator's tier (1 by default), priced by Billing (billing.tier.manage).
++ */
++ tier?: number | string;
}
| NoBody;
@@@ -149463,6 +149471,10 @@ export type BillingSubscriptionRequest =
subscription_ref?: string;
test?: boolean;
};
++ /**
++ * The creator's tier (1 by default): a credit-paid period costs the tier's price (billing.tier.manage); a renewal keeps the price the subscription was bought at.
++ */
++ tier?: number | string;
}
| NoBody;
@@@ -149489,6 +149501,48 @@ export type BillingSubscriptionResult =
subscriptions: BillingSubscription[];
};
++/** [email protected] (owner: billing) */
++/**
++ * billing.tier-request@1: the body of PUT /api/v1/tiers/:streamer/:tier on OpenVibe.Billing (billing.tier.manage): the monthly price of one of a creator's subscription tiers (1 to max_tiers), which the creator chooses on the product that sells it (OpenVibe.VIP) and Billing keeps and charges (ADR-012: Billing prices, products never do). price_cents must be within Billing's bounds (min_price_cents to max_price_cents, from GET /api/v1/tiers/:streamer or /api/v1/rates). status archived stops new subscriptions to the tier; running ones renew at the price they were bought at. A tier without a row: tier 1 is sold at the site's default subscription price, any other tier is refused (billing.tier_unknown). GET /api/v1/tiers/:streamer takes no body. The PUT needs an Idempotency-Key header and is refused with 503 billing.frozen while the economy is frozen.
++ */
++export interface BillingTierRequest {
++ /**
++ * USD cents per period (a month).
++ */
++ price_cents: number | string;
++ /**
++ * active (the default) sells the tier; archived sells it no more.
++ */
++ status?: "active" | "archived";
++}
++
++/** [email protected] (owner: billing) */
++/**
++ * billing.tier-result@1: answers of billing.tier.manage on OpenVibe.Billing. GET /api/v1/tiers/:streamer → { streamer, tiers, default_price_cents, min_price_cents, max_price_cents, max_tiers } (tiers: every tier with a price, archived included; tier 1 without a row is sold at default_price_cents); PUT /api/v1/tiers/:streamer/:tier → { tier }.
++ */
++export type BillingTierResult =
++ | {
++ streamer: SubjectRef;
++ tiers: {
++ tier: number;
++ price_cents: number;
++ status: "active" | "archived";
++ updated_at?: string;
++ }[];
++ default_price_cents: number;
++ min_price_cents: number;
++ max_price_cents: number;
++ max_tiers: number;
++ }
++ | {
++ tier: {
++ tier: number;
++ price_cents: number;
++ status: "active" | "archived";
++ updated_at?: string;
++ };
++ };
++
/** [email protected] (owner: billing) */
/**
* billing.subscription@1: one channel subscription as OpenVibe.Billing presents it (server/ops/subscriptions.js present).
ddiff --git a/manifests/capabilities/billing.tier.manage.json b/manifests/capabilities/billing.tier.manage.json
nnew file mode 100644
iindex 00000000..42f4e658
---- /dev/null
++++ b/manifests/capabilities/billing.tier.manage.json
@@@ -0,0 +1,23 @@
++{
++ "id": "billing.tier.manage",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "sensitive": true,
++ "description": "Read and set the monthly prices of a creator's subscription tiers, for the product where the creator sells them (OpenVibe.VIP), within Billing's bounds. Billing keeps the price and charges it: new subscriptions to a tier pay its price, running ones renew at the price they were bought at.",
++ "permissions": [
++ "billing:subscriptions"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "ledger-write",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/tiers/:streamer",
++ "PUT /api/v1/tiers/:streamer/:tier"
++ ],
++ "inputSchema": "billing.tier-request@1",
++ "outputSchema": "billing.tier-result@1"
++}
ddiff --git a/manifests/services/billing.json b/manifests/services/billing.json
iindex e54048c8..de77d184 100644
---- a/manifests/services/billing.json
++++ b/manifests/services/billing.json
@@@ -26,6 +26,7 @@
"billing.cashout.request",
"billing.cashout.manage",
"billing.subscription.manage",
++ "billing.tier.manage",
"billing.entitlement.check",
"billing.ledger.admin",
"billing.usage.record"
ddiff --git a/package-lock.json b/package-lock.json
iindex 0140de51..43a280ba 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -1,12 +1,12 @@
{
"name": "openvibe-contracts",
-- "version": "0.195.1",
++ "version": "0.201.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openvibe-contracts",
-- "version": "0.195.1",
++ "version": "0.201.0",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
ddiff --git a/package.json b/package.json
iindex 2c55c42c..0601054d 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.200.0",
++ "version": "0.201.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"types": "generated/typescript/index.d.ts",