openvibers/openvibe.contracts Commits
One Network level: curve, named reasons and contracts (#407)
Changes
@@@ -1,3 +1,7 @@++## 0.391.0 — 2026-11-09++++- One Network experience curve, named reasons, level reads and capped service awards.++# Changelog## 0.390.0 — 2026-11-10@@@ -5,7 +5,7 @@**Docs:** https://openvibe.services · **For AI:** https://openvibe.services/llms.txt**Install and test:** `npm ci && npm test` (Node 20 or newer)--**Status:** alpha (first released in Wave 1; the release is package.json's `version`, tagged). At v0.389.0: 1210 schemas in `contracts/catalog.json`, 65 service manifests, 511 capability manifests, 13 namespace manifests and the staff capability map. Service repositories run `openvibe-contracts-check` and the pin-drift check in CI, and deployed services verify service and app tokens with `serviceAuth` in production. Consumers pin release tags (each repository's `STATUS.json` names its pin). `node scripts/docs-currency.js <root>` checks every checkout's README and `STATUS.json` against its code: the pins and versions they name, a library's consumer list, the deployed flag against the manifest, README links, and the paths and migrations they name. `node scripts/estate.js` generates `docs/ESTATE.md` and `manifests/repositories/` from the estate checkouts, and `--check` fails on drift (plan T1 step 3).++**Status:** alpha (first released in Wave 1; the release is package.json's `version`, tagged). At v0.391.0: 1214 schemas in `contracts/catalog.json`, 65 service manifests, 512 capability manifests, 13 namespace manifests and the staff capability map. Service repositories run `openvibe-contracts-check` and the pin-drift check in CI, and deployed services verify service and app tokens with `serviceAuth` in production. Consumers pin release tags (each repository's `STATUS.json` names its pin). `node scripts/docs-currency.js <root>` checks every checkout's README and `STATUS.json` against its code: the pins and versions they name, a library's consumer list, the deployed flag against the manifest, README links, and the paths and migrations they name. `node scripts/estate.js` generates `docs/ESTATE.md` and `manifests/repositories/` from the estate checkouts, and `--check` fails on drift (plan T1 step 3).**Plan:** OpenVibe Development Roadmap, Wave 1 (implementation plan rev 3, §3.1 and §18.11).**License:** AGPL-3.0 (same as every OpenVibe service).@@@ -11159,6 +11159,42 @@"visibility": "public","compatibility": "backward","status": "active"++ },++ {++ "id": "network.level",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/level.v1.json",++ "visibility": "public",++ "compatibility": "backward",++ "status": "active"++ },++ {++ "id": "network.level-award",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/level-award.v1.json",++ "visibility": "internal",++ "compatibility": "backward",++ "status": "active"++ },++ {++ "id": "network.level-batch",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/level-batch.v1.json",++ "visibility": "public",++ "compatibility": "backward",++ "status": "active"++ },++ {++ "id": "network.level-board",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/level-board.v1.json",++ "visibility": "public",++ "compatibility": "backward",++ "status": "active"}]}nnew file mode 100644@@@ -0,0 +1,38 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/level-award.v1.json",++ "title": "NetworkLevelAward",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "subject",++ "reason",++ "amount",++ "idempotency_key"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "reason": {++ "enum": [++ "quest.completed",++ "coins.earned",++ "video.published",++ "stream.watched"++ ]++ },++ "amount": {++ "type": "integer",++ "minimum": 1,++ "maximum": 10000++ },++ "idempotency_key": {++ "type": "string",++ "minLength": 1,++ "maxLength": 160++ }++ },++ "description": "NetworkLevelAward: one earned platform level owned by Network; experience is never bought or spent."++}nnew file mode 100644@@@ -0,0 +1,21 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/level-batch.v1.json",++ "title": "NetworkLevelBatch",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "levels"++ ],++ "properties": {++ "levels": {++ "type": "object",++ "maxProperties": 100,++ "additionalProperties": {++ "type": "integer",++ "minimum": 1++ }++ }++ },++ "description": "NetworkLevelBatch: one earned platform level owned by Network; experience is never bought or spent."++}nnew file mode 100644@@@ -0,0 +1,276 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/level-board.v1.json",++ "title": "NetworkLevelBoard",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "all_time",++ "week"++ ],++ "properties": {++ "all_time": {++ "type": "object",++ "required": [++ "top",++ "me",++ "around"++ ],++ "properties": {++ "top": {++ "type": "array",++ "maxItems": 50,++ "items": {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ },++ "me": {++ "anyOf": [++ {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ },++ {++ "type": "null"++ }++ ]++ },++ "around": {++ "type": "array",++ "maxItems": 11,++ "items": {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ }++ },++ "additionalProperties": false++ },++ "week": {++ "type": "object",++ "required": [++ "top",++ "me",++ "around"++ ],++ "properties": {++ "top": {++ "type": "array",++ "maxItems": 50,++ "items": {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ },++ "me": {++ "anyOf": [++ {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ },++ {++ "type": "null"++ }++ ]++ },++ "around": {++ "type": "array",++ "maxItems": 11,++ "items": {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ }++ },++ "additionalProperties": false++ }++ },++ "description": "NetworkLevelBoard: one earned platform level owned by Network; experience is never bought or spent."++}nnew file mode 100644@@@ -0,0 +1,78 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/level.v1.json",++ "title": "NetworkLevel",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "level",++ "xp",++ "into",++ "span",++ "next_at",++ "rank",++ "recent"++ ],++ "properties": {++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "into": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "span": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "next_at": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 1++ },++ "recent": {++ "type": "array",++ "maxItems": 5,++ "items": {++ "type": "object",++ "required": [++ "name",++ "at",++ "amount"++ ],++ "properties": {++ "name": {++ "type": "string"++ },++ "at": {++ "type": "string",++ "format": "date-time"++ },++ "amount": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ }++ },++ "description": "NetworkLevel: one earned platform level owned by Network; experience is never bought or spent."++}nnew file mode 100644@@@ -0,0 +1 @@++{}nnew file mode 100644@@@ -0,0 +1,6 @@++{++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNP1",++ "reason": "quest.completed",++ "amount": 25,++ "idempotency_key": "completion:1"++}nnew file mode 100644@@@ -0,0 +1 @@++{}nnew file mode 100644@@@ -0,0 +1,3 @@++{++ "levels": {}++}nnew file mode 100644@@@ -0,0 +1 @@++{}nnew file mode 100644@@@ -0,0 +1,12 @@++{++ "all_time": {++ "top": [],++ "me": null,++ "around": []++ },++ "week": {++ "top": [],++ "me": null,++ "around": []++ }++}nnew file mode 100644@@@ -0,0 +1 @@++{}nnew file mode 100644@@@ -0,0 +1,9 @@++{++ "level": 1,++ "xp": 0,++ "into": 0,++ "span": 100,++ "next_at": 100,++ "rank": null,++ "recent": []++}@@@ -122992,6 +122992,439 @@}}}++ },++ "network.level": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/level.v1.json",++ "title": "NetworkLevel",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "level",++ "xp",++ "into",++ "span",++ "next_at",++ "rank",++ "recent"++ ],++ "properties": {++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "into": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "span": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "next_at": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 1++ },++ "recent": {++ "type": "array",++ "maxItems": 5,++ "items": {++ "type": "object",++ "required": [++ "name",++ "at",++ "amount"++ ],++ "properties": {++ "name": {++ "type": "string"++ },++ "at": {++ "type": "string",++ "format": "date-time"++ },++ "amount": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ }++ },++ "description": "NetworkLevel: one earned platform level owned by Network; experience is never bought or spent."++ }++ },++ "network.level-award": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/level-award.v1.json",++ "title": "NetworkLevelAward",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "subject",++ "reason",++ "amount",++ "idempotency_key"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "reason": {++ "enum": [++ "quest.completed",++ "coins.earned",++ "video.published",++ "stream.watched"++ ]++ },++ "amount": {++ "type": "integer",++ "minimum": 1,++ "maximum": 10000++ },++ "idempotency_key": {++ "type": "string",++ "minLength": 1,++ "maxLength": 160++ }++ },++ "description": "NetworkLevelAward: one earned platform level owned by Network; experience is never bought or spent."++ }++ },++ "network.level-batch": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/level-batch.v1.json",++ "title": "NetworkLevelBatch",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "levels"++ ],++ "properties": {++ "levels": {++ "type": "object",++ "maxProperties": 100,++ "additionalProperties": {++ "type": "integer",++ "minimum": 1++ }++ }++ },++ "description": "NetworkLevelBatch: one earned platform level owned by Network; experience is never bought or spent."++ }++ },++ "network.level-board": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/level-board.v1.json",++ "title": "NetworkLevelBoard",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "all_time",++ "week"++ ],++ "properties": {++ "all_time": {++ "type": "object",++ "required": [++ "top",++ "me",++ "around"++ ],++ "properties": {++ "top": {++ "type": "array",++ "maxItems": 50,++ "items": {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ },++ "me": {++ "anyOf": [++ {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ },++ {++ "type": "null"++ }++ ]++ },++ "around": {++ "type": "array",++ "maxItems": 11,++ "items": {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ }++ },++ "additionalProperties": false++ },++ "week": {++ "type": "object",++ "required": [++ "top",++ "me",++ "around"++ ],++ "properties": {++ "top": {++ "type": "array",++ "maxItems": 50,++ "items": {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ },++ "me": {++ "anyOf": [++ {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ },++ {++ "type": "null"++ }++ ]++ },++ "around": {++ "type": "array",++ "maxItems": 11,++ "items": {++ "type": "object",++ "required": [++ "subject",++ "username",++ "level",++ "xp",++ "rank"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "username": {++ "type": "string"++ },++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ }++ },++ "additionalProperties": false++ }++ },++ "description": "NetworkLevelBoard: one earned platform level owned by Network; experience is never bought or spent."++ }}}}@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Actor API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.AI API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Bench API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Billing API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Blog API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Bot API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Chat API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Codes API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Community API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe Connect API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Coupons API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Deals API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Design API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Domains API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Events API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Exchange API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Exchange as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Exchange as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Food API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Games API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Git API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Git as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Git as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Host API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -180,8 +180,8 @@"service": "network","name": "OpenVibe.Network","origin": "https://openvibe.network",-- "operations": 68,-- "capabilities": 39++ "operations": 69,++ "capabilities": 40},{"service": "news",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Inventory API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Live API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Mail API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Mail as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Mail as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.MediaHub API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Media API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Network API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -2971,6 +2971,62 @@}}},++ "/internal/levels/award": {++ "post": {++ "operationId": "post_internal_levels_award",++ "summary": "Award earned, non-spendable experience.",++ "description": "**network.levels.award** (internal): Award earned, non-spendable experience. Service identity comes from the credential; duplicates are refused with 409. Daily service and person caps apply.",++ "tags": [++ "network.levels"++ ],++ "x-openvibe-capabilities": [++ "network.levels.award"++ ],++ "x-openvibe-visibility": [++ "internal"++ ],++ "x-openvibe-quota-class": "ledger-write",++ "security": [++ {++ "openvibeToken": [++ "network.levels.award"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.level-award.v1"++ }++ }++ }++ },++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.level.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },"/internal/link-pairings": {"post": {"operationId": "post_internal_link_pairings",@@@ -6730,6 +6786,118 @@}}},++ "network.level-award.v1": {++ "title": "NetworkLevelAward",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "subject",++ "reason",++ "amount",++ "idempotency_key"++ ],++ "properties": {++ "subject": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "reason": {++ "enum": [++ "quest.completed",++ "coins.earned",++ "video.published",++ "stream.watched"++ ]++ },++ "amount": {++ "type": "integer",++ "minimum": 1,++ "maximum": 10000++ },++ "idempotency_key": {++ "type": "string",++ "minLength": 1,++ "maxLength": 160++ }++ },++ "description": "NetworkLevelAward: one earned platform level owned by Network; experience is never bought or spent."++ },++ "network.level.v1": {++ "title": "NetworkLevel",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "level",++ "xp",++ "into",++ "span",++ "next_at",++ "rank",++ "recent"++ ],++ "properties": {++ "level": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "xp": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "into": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "span": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "next_at": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ },++ "rank": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 1++ },++ "recent": {++ "type": "array",++ "maxItems": 5,++ "items": {++ "type": "object",++ "required": [++ "name",++ "at",++ "amount"++ ],++ "properties": {++ "name": {++ "type": "string"++ },++ "at": {++ "type": "string",++ "format": "date-time"++ },++ "amount": {++ "type": "integer",++ "minimum": 0,++ "maximum": 1000000000000++ }++ },++ "additionalProperties": false++ }++ }++ },++ "description": "NetworkLevel: one earned platform level owned by Network; experience is never bought or spent."++ },"network.link-list-result.v1": {"title": "NetworkLinkListResult","description": "network.link-list-result@1: GET /api/v1/links on OpenVibe.Network (public, cacheable): every node of the platform, filterable by ?role= and ?region=. The input of openvibe-sdk/geo's nearest().",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.News API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenRestream API",-- "version": "0.390.0",-- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Play API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Quest API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Report API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Reviews API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Run API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Search API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Services API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Sources API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Space API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tips API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Today API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tools API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Trade API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.VIP API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Vision API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Watch API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Wiki API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Work API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Zone API",-- "version": "0.390.0",-- "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",++ "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.391.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"@@@ -328190,3 +328190,1150 @@ export interface AiAdvice {words?: number;created_at: string;}++++/** [email protected] (owner: network) */++/**++ * NetworkLevel: one earned platform level owned by Network; experience is never bought or spent.++ */++export interface NetworkLevel {++ level: number;++ xp: number;++ into: number;++ span: number;++ next_at: number;++ rank: number | null;++ /**++ * @maxItems 5++ */++ recent:++ | []++ | [++ {++ name: string;++ at: string;++ amount: number;++ }++ ]++ | [++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ }++ ]++ | [++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ }++ ]++ | [++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ }++ ]++ | [++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ },++ {++ name: string;++ at: string;++ amount: number;++ }++ ];++}++++/** [email protected] (owner: network) */++/**++ * NetworkLevelAward: one earned platform level owned by Network; experience is never bought or spent.++ */++export interface NetworkLevelAward {++ subject: string;++ reason: "quest.completed" | "coins.earned" | "video.published" | "stream.watched";++ amount: number;++ idempotency_key: string;++}++++/** [email protected] (owner: network) */++/**++ * NetworkLevelBatch: one earned platform level owned by Network; experience is never bought or spent.++ */++export interface NetworkLevelBatch {++ levels: {++ [k: string]: number | undefined;++ };++}++++/** [email protected] (owner: network) */++/**++ * NetworkLevelBoard: one earned platform level owned by Network; experience is never bought or spent.++ */++export interface NetworkLevelBoard {++ all_time: {++ /**++ * @maxItems 50++ */++ top: {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }[];++ me: {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ } | null;++ /**++ * @maxItems 11++ */++ around:++ | []++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ];++ };++ week: {++ /**++ * @maxItems 50++ */++ top: {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }[];++ me: {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ } | null;++ /**++ * @maxItems 11++ */++ around:++ | []++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ]++ | [++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ },++ {++ subject: string;++ username: string;++ level: number;++ xp: number;++ rank: number;++ }++ ];++ };++}@@@ -13,6 +13,7 @@const registry = require('./lib/registry');module.exports = {++ levels: require('./lib/levels'),catalog: registry.catalog,resolve: registry.resolve,validate: registry.validate,nnew file mode 100644@@@ -0,0 +1,16 @@++'use strict';++/** One platform level. Experience is an earned, non-spendable whole number. */++function levelOf(xp) {++ if (!Number.isSafeInteger(xp) || xp < 0 || xp > 1000000000000) throw new RangeError('xp must be an integer from 0 to 1000000000000');++ const level = Math.floor((1 + Math.sqrt(1 + xp / 12.5)) / 2);++ const start = 50 * level * (level - 1);++ return { level, into: xp - start, span: 100 * level, next_at: 50 * level * (level + 1) };++}++const reasons = Object.freeze({++ 'quest.completed': Object.freeze({ name: 'Finished a quest' }),++ 'coins.earned': Object.freeze({ name: 'Earned OpenCoins' }),++ 'video.published': Object.freeze({ name: 'Published a video' }),++ 'stream.watched': Object.freeze({ name: 'Watched a stream' }),++});++function reasonName(code) { return reasons[code]?.name || 'Earned experience'; }++module.exports = { levelOf, reasons, reasonName };nnew file mode 100644@@@ -0,0 +1,19 @@++{++ "id": "network.levels.award",++ "version": "1.0",++ "owner": "network",++ "status": "active",++ "visibility": "internal",++ "description": "Award earned, non-spendable experience. Service identity comes from the credential; duplicates are refused with 409. Daily service and person caps apply.",++ "permissions": [++ "levels:write"++ ],++ "resourceConstraints": [],++ "quotaClass": "ledger-write",++ "events": [],++ "implementedBy": [++ "POST /internal/levels/award"++ ],++ "inputSchema": "network.level-award@1",++ "outputSchema": "network.level@1"++}@@@ -89,7 +89,8 @@"network.consent.manage","network.machines.read","network.machines.manage",-- "network.presence.read"++ "network.presence.read",++ "network.levels.award"],"eventsProduced": ["network.account.deleted",@@@ -1,12 +1,12 @@{"name": "openvibe-contracts",-- "version": "0.384.0",++ "version": "0.391.0","lockfileVersion": 3,"requires": true,"packages": {"": {"name": "openvibe-contracts",-- "version": "0.384.0",++ "version": "0.391.0","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -1,6 +1,6 @@{"name": "openvibe-contracts",-- "version": "0.390.0",++ "version": "0.391.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",nnew file mode 100644@@@ -0,0 +1,15 @@++'use strict';++const assert = require('assert');++const { levels, validate } = require('..');++for (let l = 1; l <= 10000; l++) {++ const at = 50*l*(l-1);++ assert.equal(levels.levelOf(at).level, l);++ if (at) assert.equal(levels.levelOf(at-1).level, l-1);++ assert.equal(levels.levelOf(at).into, 0);++ assert.equal(levels.levelOf(at).span, 100*l);++}++for (const x of [-1, 1.5, NaN, Infinity, '100']) assert.throws(() => levels.levelOf(x));++assert.equal(levels.reasonName('quest.completed'), 'Finished a quest');++assert.equal(levels.reasonName('private:raw-code'), 'Earned experience');++assert(validate('network.level@1', {...levels.levelOf(300), xp:300, rank:null, recent:[]}).valid);++console.log('levels: curve boundaries and named reasons passed');@@@ -1,3 +1,4 @@++require('./levels.test');'use strict';const assert = require('assert');const fs = require('fs');
@@ -1,3 +1,7 @@
@@ -1,3 +1,7 @@
+## 0.391.0 — 2026-11-09
+
+- One Network experience curve, named reasons, level reads and capped service awards.
+
# Changelog
# Changelog
## 0.390.0 — 2026-11-10
## 0.390.0 — 2026-11-10
@@ -5,7 +5,7 @@
@@ -5,7 +5,7 @@
**Docs:** https://openvibe.services · **For AI:** https://openvibe.services/llms.txt
**Docs:** https://openvibe.services · **For AI:** https://openvibe.services/llms.txt
**Install and test:** `npm ci && npm test` (Node 20 or newer)
**Install and test:** `npm ci && npm test` (Node 20 or newer)
-**Status:** alpha (first released in Wave 1; the release is package.json's `version`, tagged). At v0.389.0: 1210 schemas in `contracts/catalog.json`, 65 service manifests, 511 capability manifests, 13 namespace manifests and the staff capability map. Service repositories run `openvibe-contracts-check` and the pin-drift check in CI, and deployed services verify service and app tokens with `serviceAuth` in production. Consumers pin release tags (each repository's `STATUS.json` names its pin). `node scripts/docs-currency.js <root>` checks every checkout's README and `STATUS.json` against its code: the pins and versions they name, a library's consumer list, the deployed flag against the manifest, README links, and the paths and migrations they name. `node scripts/estate.js` generates `docs/ESTATE.md` and `manifests/repositories/` from the estate checkouts, and `--check` fails on drift (plan T1 step 3).
+**Status:** alpha (first released in Wave 1; the release is package.json's `version`, tagged). At v0.391.0: 1214 schemas in `contracts/catalog.json`, 65 service manifests, 512 capability manifests, 13 namespace manifests and the staff capability map. Service repositories run `openvibe-contracts-check` and the pin-drift check in CI, and deployed services verify service and app tokens with `serviceAuth` in production. Consumers pin release tags (each repository's `STATUS.json` names its pin). `node scripts/docs-currency.js <root>` checks every checkout's README and `STATUS.json` against its code: the pins and versions they name, a library's consumer list, the deployed flag against the manifest, README links, and the paths and migrations they name. `node scripts/estate.js` generates `docs/ESTATE.md` and `manifests/repositories/` from the estate checkouts, and `--check` fails on drift (plan T1 step 3).
**Plan:** OpenVibe Development Roadmap, Wave 1 (implementation plan rev 3, §3.1 and §18.11).
**Plan:** OpenVibe Development Roadmap, Wave 1 (implementation plan rev 3, §3.1 and §18.11).
**License:** AGPL-3.0 (same as every OpenVibe service).
**License:** AGPL-3.0 (same as every OpenVibe service).
@@ -11159,6 +11159,42 @@
@@ -11159,6 +11159,42 @@
"visibility": "public",
"visibility": "public",
"compatibility": "backward",
"compatibility": "backward",
"status": "active"
"status": "active"
+ },
+ {
+ "id": "network.level",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/level.v1.json",
+ "visibility": "public",
+ "compatibility": "backward",
+ "status": "active"
+ },
+ {
+ "id": "network.level-award",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/level-award.v1.json",
+ "visibility": "internal",
+ "compatibility": "backward",
+ "status": "active"
+ },
+ {
+ "id": "network.level-batch",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/level-batch.v1.json",
+ "visibility": "public",
+ "compatibility": "backward",
+ "status": "active"
+ },
+ {
+ "id": "network.level-board",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/level-board.v1.json",
+ "visibility": "public",
+ "compatibility": "backward",
+ "status": "active"
}
}
]
]
}
}
new file mode 100644
new file mode 100644
@@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/level-award.v1.json",
+ "title": "NetworkLevelAward",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "subject",
+ "reason",
+ "amount",
+ "idempotency_key"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "reason": {
+ "enum": [
+ "quest.completed",
+ "coins.earned",
+ "video.published",
+ "stream.watched"
+ ]
+ },
+ "amount": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 10000
+ },
+ "idempotency_key": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 160
+ }
+ },
+ "description": "NetworkLevelAward: one earned platform level owned by Network; experience is never bought or spent."
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/level-batch.v1.json",
+ "title": "NetworkLevelBatch",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "levels"
+ ],
+ "properties": {
+ "levels": {
+ "type": "object",
+ "maxProperties": 100,
+ "additionalProperties": {
+ "type": "integer",
+ "minimum": 1
+ }
+ }
+ },
+ "description": "NetworkLevelBatch: one earned platform level owned by Network; experience is never bought or spent."
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,276 @@
@@ -0,0 +1,276 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/level-board.v1.json",
+ "title": "NetworkLevelBoard",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "all_time",
+ "week"
+ ],
+ "properties": {
+ "all_time": {
+ "type": "object",
+ "required": [
+ "top",
+ "me",
+ "around"
+ ],
+ "properties": {
+ "top": {
+ "type": "array",
+ "maxItems": 50,
+ "items": {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "me": {
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "around": {
+ "type": "array",
+ "maxItems": 11,
+ "items": {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "week": {
+ "type": "object",
+ "required": [
+ "top",
+ "me",
+ "around"
+ ],
+ "properties": {
+ "top": {
+ "type": "array",
+ "maxItems": 50,
+ "items": {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "me": {
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "around": {
+ "type": "array",
+ "maxItems": 11,
+ "items": {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "description": "NetworkLevelBoard: one earned platform level owned by Network; experience is never bought or spent."
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,78 @@
@@ -0,0 +1,78 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/level.v1.json",
+ "title": "NetworkLevel",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "level",
+ "xp",
+ "into",
+ "span",
+ "next_at",
+ "rank",
+ "recent"
+ ],
+ "properties": {
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "into": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "span": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "next_at": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1
+ },
+ "recent": {
+ "type": "array",
+ "maxItems": 5,
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "at",
+ "amount"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "amount": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "description": "NetworkLevel: one earned platform level owned by Network; experience is never bought or spent."
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{}
new file mode 100644
new file mode 100644
@@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
+{
+ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNP1",
+ "reason": "quest.completed",
+ "amount": 25,
+ "idempotency_key": "completion:1"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{}
new file mode 100644
new file mode 100644
@@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
+{
+ "levels": {}
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{}
new file mode 100644
new file mode 100644
@@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
+{
+ "all_time": {
+ "top": [],
+ "me": null,
+ "around": []
+ },
+ "week": {
+ "top": [],
+ "me": null,
+ "around": []
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{}
new file mode 100644
new file mode 100644
@@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
+{
+ "level": 1,
+ "xp": 0,
+ "into": 0,
+ "span": 100,
+ "next_at": 100,
+ "rank": null,
+ "recent": []
+}
@@ -122992,6 +122992,439 @@
@@ -122992,6 +122992,439 @@
}
}
}
}
}
}
+ },
+ "network.level": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/level.v1.json",
+ "title": "NetworkLevel",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "level",
+ "xp",
+ "into",
+ "span",
+ "next_at",
+ "rank",
+ "recent"
+ ],
+ "properties": {
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "into": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "span": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "next_at": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1
+ },
+ "recent": {
+ "type": "array",
+ "maxItems": 5,
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "at",
+ "amount"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "amount": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "description": "NetworkLevel: one earned platform level owned by Network; experience is never bought or spent."
+ }
+ },
+ "network.level-award": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/level-award.v1.json",
+ "title": "NetworkLevelAward",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "subject",
+ "reason",
+ "amount",
+ "idempotency_key"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "reason": {
+ "enum": [
+ "quest.completed",
+ "coins.earned",
+ "video.published",
+ "stream.watched"
+ ]
+ },
+ "amount": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 10000
+ },
+ "idempotency_key": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 160
+ }
+ },
+ "description": "NetworkLevelAward: one earned platform level owned by Network; experience is never bought or spent."
+ }
+ },
+ "network.level-batch": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/level-batch.v1.json",
+ "title": "NetworkLevelBatch",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "levels"
+ ],
+ "properties": {
+ "levels": {
+ "type": "object",
+ "maxProperties": 100,
+ "additionalProperties": {
+ "type": "integer",
+ "minimum": 1
+ }
+ }
+ },
+ "description": "NetworkLevelBatch: one earned platform level owned by Network; experience is never bought or spent."
+ }
+ },
+ "network.level-board": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/level-board.v1.json",
+ "title": "NetworkLevelBoard",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "all_time",
+ "week"
+ ],
+ "properties": {
+ "all_time": {
+ "type": "object",
+ "required": [
+ "top",
+ "me",
+ "around"
+ ],
+ "properties": {
+ "top": {
+ "type": "array",
+ "maxItems": 50,
+ "items": {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "me": {
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "around": {
+ "type": "array",
+ "maxItems": 11,
+ "items": {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "week": {
+ "type": "object",
+ "required": [
+ "top",
+ "me",
+ "around"
+ ],
+ "properties": {
+ "top": {
+ "type": "array",
+ "maxItems": 50,
+ "items": {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "me": {
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "around": {
+ "type": "array",
+ "maxItems": 11,
+ "items": {
+ "type": "object",
+ "required": [
+ "subject",
+ "username",
+ "level",
+ "xp",
+ "rank"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "username": {
+ "type": "string"
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "description": "NetworkLevelBoard: one earned platform level owned by Network; experience is never bought or spent."
+ }
}
}
}
}
}
}
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Actor API",
"title": "OpenVibe.Actor API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.AI API",
"title": "OpenVibe.AI API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Bench API",
"title": "OpenVibe.Bench API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Billing API",
"title": "OpenVibe.Billing API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Blog API",
"title": "OpenVibe.Blog API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Bot API",
"title": "OpenVibe.Bot API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Chat API",
"title": "OpenVibe.Chat API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Codes API",
"title": "OpenVibe.Codes API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Community API",
"title": "OpenVibe.Community API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe Connect API",
"title": "OpenVibe Connect API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Coupons API",
"title": "OpenVibe.Coupons API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Deals API",
"title": "OpenVibe.Deals API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Design API",
"title": "OpenVibe.Design API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Domains API",
"title": "OpenVibe.Domains API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Events API",
"title": "OpenVibe.Events API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Exchange API",
"title": "OpenVibe.Exchange API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Exchange as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Exchange as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Food API",
"title": "OpenVibe.Food API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Games API",
"title": "OpenVibe.Games API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Git API",
"title": "OpenVibe.Git API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Git as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Git as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Host API",
"title": "OpenVibe.Host API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -180,8 +180,8 @@
@@ -180,8 +180,8 @@
"service": "network",
"service": "network",
"name": "OpenVibe.Network",
"name": "OpenVibe.Network",
"origin": "https://openvibe.network",
"origin": "https://openvibe.network",
- "operations": 68,
- "capabilities": 39
+ "operations": 69,
+ "capabilities": 40
},
},
{
{
"service": "news",
"service": "news",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Inventory API",
"title": "OpenVibe.Inventory API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Live API",
"title": "OpenVibe.Live API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Mail API",
"title": "OpenVibe.Mail API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Mail as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Mail as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.MediaHub API",
"title": "OpenVibe.MediaHub API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Media API",
"title": "OpenVibe.Media API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Network API",
"title": "OpenVibe.Network API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -2971,6 +2971,62 @@
@@ -2971,6 +2971,62 @@
}
}
}
}
},
},
+ "/internal/levels/award": {
+ "post": {
+ "operationId": "post_internal_levels_award",
+ "summary": "Award earned, non-spendable experience.",
+ "description": "**network.levels.award** (internal): Award earned, non-spendable experience. Service identity comes from the credential; duplicates are refused with 409. Daily service and person caps apply.",
+ "tags": [
+ "network.levels"
+ ],
+ "x-openvibe-capabilities": [
+ "network.levels.award"
+ ],
+ "x-openvibe-visibility": [
+ "internal"
+ ],
+ "x-openvibe-quota-class": "ledger-write",
+ "security": [
+ {
+ "openvibeToken": [
+ "network.levels.award"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.level-award.v1"
+ }
+ }
+ }
+ },
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.level.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/internal/link-pairings": {
"/internal/link-pairings": {
"post": {
"post": {
"operationId": "post_internal_link_pairings",
"operationId": "post_internal_link_pairings",
@@ -6730,6 +6786,118 @@
@@ -6730,6 +6786,118 @@
}
}
}
}
},
},
+ "network.level-award.v1": {
+ "title": "NetworkLevelAward",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "subject",
+ "reason",
+ "amount",
+ "idempotency_key"
+ ],
+ "properties": {
+ "subject": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "reason": {
+ "enum": [
+ "quest.completed",
+ "coins.earned",
+ "video.published",
+ "stream.watched"
+ ]
+ },
+ "amount": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 10000
+ },
+ "idempotency_key": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 160
+ }
+ },
+ "description": "NetworkLevelAward: one earned platform level owned by Network; experience is never bought or spent."
+ },
+ "network.level.v1": {
+ "title": "NetworkLevel",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "level",
+ "xp",
+ "into",
+ "span",
+ "next_at",
+ "rank",
+ "recent"
+ ],
+ "properties": {
+ "level": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "xp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "into": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "span": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "next_at": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ },
+ "rank": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1
+ },
+ "recent": {
+ "type": "array",
+ "maxItems": 5,
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "at",
+ "amount"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "amount": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1000000000000
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "description": "NetworkLevel: one earned platform level owned by Network; experience is never bought or spent."
+ },
"network.link-list-result.v1": {
"network.link-list-result.v1": {
"title": "NetworkLinkListResult",
"title": "NetworkLinkListResult",
"description": "network.link-list-result@1: GET /api/v1/links on OpenVibe.Network (public, cacheable): every node of the platform, filterable by ?role= and ?region=. The input of openvibe-sdk/geo's nearest().",
"description": "network.link-list-result@1: GET /api/v1/links on OpenVibe.Network (public, cacheable): every node of the platform, filterable by ?role= and ?region=. The input of openvibe-sdk/geo's nearest().",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.News API",
"title": "OpenVibe.News API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenRestream API",
"title": "OpenRestream API",
- "version": "0.390.0",
- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Play API",
"title": "OpenVibe.Play API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Quest API",
"title": "OpenVibe.Quest API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Report API",
"title": "OpenVibe.Report API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Reviews API",
"title": "OpenVibe.Reviews API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Run API",
"title": "OpenVibe.Run API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Search API",
"title": "OpenVibe.Search API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Services API",
"title": "OpenVibe.Services API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Sources API",
"title": "OpenVibe.Sources API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Space API",
"title": "OpenVibe.Space API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Tips API",
"title": "OpenVibe.Tips API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Today API",
"title": "OpenVibe.Today API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Tools API",
"title": "OpenVibe.Tools API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Trade API",
"title": "OpenVibe.Trade API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.VIP API",
"title": "OpenVibe.VIP API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Vision API",
"title": "OpenVibe.Vision API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Watch API",
"title": "OpenVibe.Watch API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Wiki API",
"title": "OpenVibe.Wiki API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Work API",
"title": "OpenVibe.Work API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Zone API",
"title": "OpenVibe.Zone API",
- "version": "0.390.0",
- "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.390.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.391.0",
+ "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.391.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -328190,3 +328190,1150 @@ export interface AiAdvice {
@@ -328190,3 +328190,1150 @@ export interface AiAdvice {
words?: number;
words?: number;
created_at: string;
created_at: string;
}
}
+
+/** [email protected] (owner: network) */
+/**
+ * NetworkLevel: one earned platform level owned by Network; experience is never bought or spent.
+ */
+export interface NetworkLevel {
+ level: number;
+ xp: number;
+ into: number;
+ span: number;
+ next_at: number;
+ rank: number | null;
+ /**
+ * @maxItems 5
+ */
+ recent:
+ | []
+ | [
+ {
+ name: string;
+ at: string;
+ amount: number;
+ }
+ ]
+ | [
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ }
+ ]
+ | [
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ }
+ ]
+ | [
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ }
+ ]
+ | [
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ },
+ {
+ name: string;
+ at: string;
+ amount: number;
+ }
+ ];
+}
+
+/** [email protected] (owner: network) */
+/**
+ * NetworkLevelAward: one earned platform level owned by Network; experience is never bought or spent.
+ */
+export interface NetworkLevelAward {
+ subject: string;
+ reason: "quest.completed" | "coins.earned" | "video.published" | "stream.watched";
+ amount: number;
+ idempotency_key: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * NetworkLevelBatch: one earned platform level owned by Network; experience is never bought or spent.
+ */
+export interface NetworkLevelBatch {
+ levels: {
+ [k: string]: number | undefined;
+ };
+}
+
+/** [email protected] (owner: network) */
+/**
+ * NetworkLevelBoard: one earned platform level owned by Network; experience is never bought or spent.
+ */
+export interface NetworkLevelBoard {
+ all_time: {
+ /**
+ * @maxItems 50
+ */
+ top: {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }[];
+ me: {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ } | null;
+ /**
+ * @maxItems 11
+ */
+ around:
+ | []
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ];
+ };
+ week: {
+ /**
+ * @maxItems 50
+ */
+ top: {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }[];
+ me: {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ } | null;
+ /**
+ * @maxItems 11
+ */
+ around:
+ | []
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ]
+ | [
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ },
+ {
+ subject: string;
+ username: string;
+ level: number;
+ xp: number;
+ rank: number;
+ }
+ ];
+ };
+}
@@ -13,6 +13,7 @@
@@ -13,6 +13,7 @@
const registry = require('./lib/registry');
const registry = require('./lib/registry');
module.exports = {
module.exports = {
+ levels: require('./lib/levels'),
catalog: registry.catalog,
catalog: registry.catalog,
resolve: registry.resolve,
resolve: registry.resolve,
validate: registry.validate,
validate: registry.validate,
new file mode 100644
new file mode 100644
@@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
+'use strict';
+/** One platform level. Experience is an earned, non-spendable whole number. */
+function levelOf(xp) {
+ if (!Number.isSafeInteger(xp) || xp < 0 || xp > 1000000000000) throw new RangeError('xp must be an integer from 0 to 1000000000000');
+ const level = Math.floor((1 + Math.sqrt(1 + xp / 12.5)) / 2);
+ const start = 50 * level * (level - 1);
+ return { level, into: xp - start, span: 100 * level, next_at: 50 * level * (level + 1) };
+}
+const reasons = Object.freeze({
+ 'quest.completed': Object.freeze({ name: 'Finished a quest' }),
+ 'coins.earned': Object.freeze({ name: 'Earned OpenCoins' }),
+ 'video.published': Object.freeze({ name: 'Published a video' }),
+ 'stream.watched': Object.freeze({ name: 'Watched a stream' }),
+});
+function reasonName(code) { return reasons[code]?.name || 'Earned experience'; }
+module.exports = { levelOf, reasons, reasonName };
new file mode 100644
new file mode 100644
@@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
+{
+ "id": "network.levels.award",
+ "version": "1.0",
+ "owner": "network",
+ "status": "active",
+ "visibility": "internal",
+ "description": "Award earned, non-spendable experience. Service identity comes from the credential; duplicates are refused with 409. Daily service and person caps apply.",
+ "permissions": [
+ "levels:write"
+ ],
+ "resourceConstraints": [],
+ "quotaClass": "ledger-write",
+ "events": [],
+ "implementedBy": [
+ "POST /internal/levels/award"
+ ],
+ "inputSchema": "network.level-award@1",
+ "outputSchema": "network.level@1"
+}
@@ -89,7 +89,8 @@
@@ -89,7 +89,8 @@
"network.consent.manage",
"network.consent.manage",
"network.machines.read",
"network.machines.read",
"network.machines.manage",
"network.machines.manage",
- "network.presence.read"
+ "network.presence.read",
+ "network.levels.award"
],
],
"eventsProduced": [
"eventsProduced": [
"network.account.deleted",
"network.account.deleted",
@@ -1,12 +1,12 @@
@@ -1,12 +1,12 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.384.0",
+ "version": "0.391.0",
"lockfileVersion": 3,
"lockfileVersion": 3,
"requires": true,
"requires": true,
"packages": {
"packages": {
"": {
"": {
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.384.0",
+ "version": "0.391.0",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.390.0",
+ "version": "0.391.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"main": "index.js",
"types": "generated/typescript/index.d.ts",
"types": "generated/typescript/index.d.ts",
new file mode 100644
new file mode 100644
@@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
+'use strict';
+const assert = require('assert');
+const { levels, validate } = require('..');
+for (let l = 1; l <= 10000; l++) {
+ const at = 50*l*(l-1);
+ assert.equal(levels.levelOf(at).level, l);
+ if (at) assert.equal(levels.levelOf(at-1).level, l-1);
+ assert.equal(levels.levelOf(at).into, 0);
+ assert.equal(levels.levelOf(at).span, 100*l);
+}
+for (const x of [-1, 1.5, NaN, Infinity, '100']) assert.throws(() => levels.levelOf(x));
+assert.equal(levels.reasonName('quest.completed'), 'Finished a quest');
+assert.equal(levels.reasonName('private:raw-code'), 'Earned experience');
+assert(validate('network.level@1', {...levels.levelOf(300), xp:300, rank:null, recent:[]}).valid);
+console.log('levels: curve boundaries and named reasons passed');
@@ -1,3 +1,4 @@
@@ -1,3 +1,4 @@
+require('./levels.test');
'use strict';
'use strict';
const assert = require('assert');
const assert = require('assert');
const fs = require('fs');
const fs = require('fs');