openvibers/openvibe.contracts Commits
Contracts 0.139.0: host.catalog.manage (the hosting catalog's staff entries) (#95)
Changes
@@@ -4,6 +4,13 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) thfrom `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,the notes were in the tag and commit messages (`git tag -n1`).++## 0.139.0 — 2026-10-11++++- `host.catalog.manage` (active, staff only) with `host.catalog-manage-request@1` and `host.catalog-manage-result@1`:++ OpenVibe.Host's hosting catalog (plan T20 step 3), staff entries for providers (affiliate link and its exact++ disclosure), plans (source URL, currency, monthly price, the date it was confirmed) and promotions. The catalog's++ reads are public.++## 0.138.0 — 2026-10-11- Sources category `hosting` (`sources.source@1`, `sources.item@1`, `sources.source-write-request@1` and the@@@ -5526,6 +5526,24 @@"compatibility": "backward","status": "active"},++ {++ "id": "host.catalog-manage-request",++ "version": "1.0.0",++ "owner": "host",++ "schema": "host/catalog-manage-request.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active"++ },++ {++ "id": "host.catalog-manage-result",++ "version": "1.0.0",++ "owner": "host",++ "schema": "host/catalog-manage-result.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active"++ },{"id": "host.site","version": "1.0.0",nnew file mode 100644@@@ -0,0 +1,241 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/host/catalog-manage-request.v1.json",++ "title": "HostCatalogManageRequest",++ "description": "host.catalog-manage-request@1: bodies of host.catalog.manage on OpenVibe.Host (a Network staff user only). POST/PATCH /api/v1/catalog/providers { slug, name, homepage_url, description?, affiliate_url?, affiliate_note?, status? }; POST/PATCH /api/v1/catalog/plans { provider_id, external_id, name, kind, currency, price_monthly, source_url, vcpu?, ram_mb?, disk_gb?, disk_type?, bandwidth_gb?, unmetered?, port_mbps?, ipv4?, locations?, price_hourly?, setup_fee?, checked_at?, status? } (a plan from OpenVibe.Sources takes only status); POST/PATCH /api/v1/catalog/promos { provider_id, title, url, details?, code?, affiliate?, starts_at?, ends_at?, status? }. A PATCH carries any subset. Unknown fields are refused (422 host.catalog.invalid); a missing entry is 404 host.catalog.not_found; anyone but staff is 403 host.catalog.forbidden. A staff plan's checked_at defaults to now: the staff member confirming the price that day.",++ "anyOf": [++ {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "slug": {++ "type": "string",++ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",++ "maxLength": 80++ },++ "name": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "homepage_url": {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ "description": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048++ },++ "affiliate_url": {++ "anyOf": [++ {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ {++ "type": "null"++ }++ ]++ },++ "affiliate_note": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048,++ "description": "The exact disclosure shown beside the provider's affiliate links."++ },++ "status": {++ "enum": [++ "active",++ "hidden"++ ]++ }++ }++ },++ {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "provider_id": {++ "type": "string"++ },++ "external_id": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "name": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "kind": {++ "enum": [++ "cloud",++ "vps",++ "dedicated",++ "storage",++ "domain"++ ]++ },++ "vcpu": {++ "type": "number",++ "minimum": 0++ },++ "ram_mb": {++ "type": "number",++ "minimum": 0++ },++ "disk_gb": {++ "type": "number",++ "minimum": 0++ },++ "disk_type": {++ "enum": [++ "ssd",++ "nvme",++ "hdd",++ null++ ]++ },++ "bandwidth_gb": {++ "type": "number",++ "minimum": 0++ },++ "unmetered": {++ "type": [++ "boolean",++ "null"++ ]++ },++ "port_mbps": {++ "type": "number",++ "minimum": 0++ },++ "ipv4": {++ "type": "integer",++ "minimum": 0++ },++ "locations": {++ "type": [++ "array",++ "null"++ ],++ "items": {++ "type": "string",++ "minLength": 1++ }++ },++ "currency": {++ "type": "string",++ "pattern": "^[A-Z]{3}$",++ "description": "ISO 4217."++ },++ "price_monthly": {++ "type": "number",++ "minimum": 0,++ "exclusiveMaximum": 100000000++ },++ "price_hourly": {++ "type": [++ "number",++ "null"++ ],++ "minimum": 0++ },++ "setup_fee": {++ "type": [++ "number",++ "null"++ ],++ "minimum": 0++ },++ "source_url": {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ "checked_at": {++ "type": "integer",++ "minimum": 0,++ "description": "Epoch milliseconds the price was confirmed."++ },++ "status": {++ "enum": [++ "active",++ "gone",++ "hidden"++ ]++ }++ }++ },++ {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "provider_id": {++ "type": "string"++ },++ "title": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "details": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048++ },++ "code": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048++ },++ "url": {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ "affiliate": {++ "type": [++ "boolean",++ "null"++ ]++ },++ "starts_at": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 0,++ "description": "Epoch milliseconds."++ },++ "ends_at": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 0,++ "description": "Epoch milliseconds."++ },++ "status": {++ "enum": [++ "active",++ "ended",++ "hidden"++ ]++ }++ }++ }++ ]++}nnew file mode 100644@@@ -0,0 +1,68 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/host/catalog-manage-result.v1.json",++ "title": "HostCatalogManageResult",++ "description": "host.catalog-manage-result@1: the saved entry, under its type's name: { provider } (with affiliate_rel and affiliate_disclosure when it has an affiliate link), { plan } or { promo } (an active promo past ends_at reads as ended). 201 on create, 200 on update.",++ "anyOf": [++ {++ "type": "object",++ "required": [++ "provider"++ ],++ "properties": {++ "provider": {++ "type": "object",++ "required": [++ "id"++ ],++ "properties": {++ "id": {++ "type": "string"++ }++ },++ "additionalProperties": true++ }++ }++ },++ {++ "type": "object",++ "required": [++ "plan"++ ],++ "properties": {++ "plan": {++ "type": "object",++ "required": [++ "id"++ ],++ "properties": {++ "id": {++ "type": "string"++ }++ },++ "additionalProperties": true++ }++ }++ },++ {++ "type": "object",++ "required": [++ "promo"++ ],++ "properties": {++ "promo": {++ "type": "object",++ "required": [++ "id"++ ],++ "properties": {++ "id": {++ "type": "string"++ }++ },++ "additionalProperties": true++ }++ }++ }++ ]++}nnew file mode 100644@@@ -0,0 +1,9 @@++{++ "provider_id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",++ "external_id": "x",++ "name": "X",++ "kind": "vps",++ "currency": "USD",++ "price_monthly": -1,++ "source_url": "https://example.com/"++}nnew file mode 100644@@@ -0,0 +1,6 @@++{++ "slug": "x",++ "name": "X",++ "homepage_url": "https://x.example/",++ "rank_boost": 10++}nnew file mode 100644@@@ -0,0 +1,9 @@++{++ "provider_id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",++ "external_id": "x",++ "name": "X",++ "kind": "shared",++ "currency": "USD",++ "price_monthly": 1,++ "source_url": "https://example.com/"++}nnew file mode 100644@@@ -0,0 +1,20 @@++{++ "provider_id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",++ "external_id": "cx22",++ "name": "CX22",++ "kind": "cloud",++ "vcpu": 2,++ "ram_mb": 4096,++ "disk_gb": 40,++ "disk_type": "nvme",++ "bandwidth_gb": 20480,++ "ipv4": 1,++ "locations": [++ "Falkenstein",++ "Nuremberg",++ "Helsinki"++ ],++ "currency": "EUR",++ "price_monthly": 4.59,++ "source_url": "https://www.hetzner.com/cloud/"++}nnew file mode 100644@@@ -0,0 +1,7 @@++{++ "provider_id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",++ "title": "First month free",++ "url": "https://www.example.com/offer",++ "affiliate": false,++ "ends_at": 1793491200000++}nnew file mode 100644@@@ -0,0 +1,7 @@++{++ "slug": "hetzner",++ "name": "Hetzner",++ "homepage_url": "https://www.hetzner.com/",++ "affiliate_url": null,++ "status": "active"++}nnew file mode 100644@@@ -0,0 +1,3 @@++{++ "status": "hidden"++}nnew file mode 100644@@@ -0,0 +1 @@++{}nnew file mode 100644@@@ -0,0 +1,5 @@++{++ "entry": {++ "id": "hpl_01M4C49CWJCFYGJS3T7NFZFQYX"++ }++}nnew file mode 100644@@@ -0,0 +1,10 @@++{++ "plan": {++ "id": "hpl_01M4C49CWJCFYGJS3T7NFZFQYX",++ "external_id": "cx22",++ "name": "CX22",++ "currency": "EUR",++ "price_monthly": "4.5900",++ "origin": "staff"++ }++}nnew file mode 100644@@@ -0,0 +1,12 @@++{++ "provider": {++ "id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",++ "slug": "hetzner",++ "name": "Hetzner",++ "homepage_url": "https://www.hetzner.com/",++ "affiliate_url": null,++ "affiliate_rel": null,++ "affiliate_disclosure": null,++ "status": "active"++ }++}@@@ -63023,6 +63023,325 @@]}},++ "host.catalog-manage-request": {++ "version": "1.0.0",++ "owner": "host",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/host/catalog-manage-request.v1.json",++ "title": "HostCatalogManageRequest",++ "description": "host.catalog-manage-request@1: bodies of host.catalog.manage on OpenVibe.Host (a Network staff user only). POST/PATCH /api/v1/catalog/providers { slug, name, homepage_url, description?, affiliate_url?, affiliate_note?, status? }; POST/PATCH /api/v1/catalog/plans { provider_id, external_id, name, kind, currency, price_monthly, source_url, vcpu?, ram_mb?, disk_gb?, disk_type?, bandwidth_gb?, unmetered?, port_mbps?, ipv4?, locations?, price_hourly?, setup_fee?, checked_at?, status? } (a plan from OpenVibe.Sources takes only status); POST/PATCH /api/v1/catalog/promos { provider_id, title, url, details?, code?, affiliate?, starts_at?, ends_at?, status? }. A PATCH carries any subset. Unknown fields are refused (422 host.catalog.invalid); a missing entry is 404 host.catalog.not_found; anyone but staff is 403 host.catalog.forbidden. A staff plan's checked_at defaults to now: the staff member confirming the price that day.",++ "anyOf": [++ {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "slug": {++ "type": "string",++ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",++ "maxLength": 80++ },++ "name": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "homepage_url": {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ "description": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048++ },++ "affiliate_url": {++ "anyOf": [++ {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ {++ "type": "null"++ }++ ]++ },++ "affiliate_note": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048,++ "description": "The exact disclosure shown beside the provider's affiliate links."++ },++ "status": {++ "enum": [++ "active",++ "hidden"++ ]++ }++ }++ },++ {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "provider_id": {++ "type": "string"++ },++ "external_id": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "name": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "kind": {++ "enum": [++ "cloud",++ "vps",++ "dedicated",++ "storage",++ "domain"++ ]++ },++ "vcpu": {++ "type": "number",++ "minimum": 0++ },++ "ram_mb": {++ "type": "number",++ "minimum": 0++ },++ "disk_gb": {++ "type": "number",++ "minimum": 0++ },++ "disk_type": {++ "enum": [++ "ssd",++ "nvme",++ "hdd",++ null++ ]++ },++ "bandwidth_gb": {++ "type": "number",++ "minimum": 0++ },++ "unmetered": {++ "type": [++ "boolean",++ "null"++ ]++ },++ "port_mbps": {++ "type": "number",++ "minimum": 0++ },++ "ipv4": {++ "type": "integer",++ "minimum": 0++ },++ "locations": {++ "type": [++ "array",++ "null"++ ],++ "items": {++ "type": "string",++ "minLength": 1++ }++ },++ "currency": {++ "type": "string",++ "pattern": "^[A-Z]{3}$",++ "description": "ISO 4217."++ },++ "price_monthly": {++ "type": "number",++ "minimum": 0,++ "exclusiveMaximum": 100000000++ },++ "price_hourly": {++ "type": [++ "number",++ "null"++ ],++ "minimum": 0++ },++ "setup_fee": {++ "type": [++ "number",++ "null"++ ],++ "minimum": 0++ },++ "source_url": {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ "checked_at": {++ "type": "integer",++ "minimum": 0,++ "description": "Epoch milliseconds the price was confirmed."++ },++ "status": {++ "enum": [++ "active",++ "gone",++ "hidden"++ ]++ }++ }++ },++ {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "provider_id": {++ "type": "string"++ },++ "title": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "details": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048++ },++ "code": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048++ },++ "url": {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ "affiliate": {++ "type": [++ "boolean",++ "null"++ ]++ },++ "starts_at": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 0,++ "description": "Epoch milliseconds."++ },++ "ends_at": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 0,++ "description": "Epoch milliseconds."++ },++ "status": {++ "enum": [++ "active",++ "ended",++ "hidden"++ ]++ }++ }++ }++ ]++ }++ },++ "host.catalog-manage-result": {++ "version": "1.0.0",++ "owner": "host",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/host/catalog-manage-result.v1.json",++ "title": "HostCatalogManageResult",++ "description": "host.catalog-manage-result@1: the saved entry, under its type's name: { provider } (with affiliate_rel and affiliate_disclosure when it has an affiliate link), { plan } or { promo } (an active promo past ends_at reads as ended). 201 on create, 200 on update.",++ "anyOf": [++ {++ "type": "object",++ "required": [++ "provider"++ ],++ "properties": {++ "provider": {++ "type": "object",++ "required": [++ "id"++ ],++ "properties": {++ "id": {++ "type": "string"++ }++ },++ "additionalProperties": true++ }++ }++ },++ {++ "type": "object",++ "required": [++ "plan"++ ],++ "properties": {++ "plan": {++ "type": "object",++ "required": [++ "id"++ ],++ "properties": {++ "id": {++ "type": "string"++ }++ },++ "additionalProperties": true++ }++ }++ },++ {++ "type": "object",++ "required": [++ "promo"++ ],++ "properties": {++ "promo": {++ "type": "object",++ "required": [++ "id"++ ],++ "properties": {++ "id": {++ "type": "string"++ }++ },++ "additionalProperties": true++ }++ }++ }++ ]++ }++ },"host.site": {"version": "1.0.0","owner": "host",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Actor API",-- "version": "0.138.0",-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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"@@@ -16,6 +16,372 @@}],"paths": {++ "/api/v1/catalog/plans": {++ "post": {++ "operationId": "post_api_v1_catalog_plans",++ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",++ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",++ "tags": [++ "host.catalog"++ ],++ "x-openvibe-capabilities": [++ "host.catalog.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "host-manage",++ "security": [++ {++ "openvibeToken": [++ "host.catalog.manage"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-request.v1"++ }++ }++ }++ },++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-result.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },++ "/api/v1/catalog/plans/{id}": {++ "patch": {++ "operationId": "patch_api_v1_catalog_plans_id",++ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",++ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",++ "tags": [++ "host.catalog"++ ],++ "x-openvibe-capabilities": [++ "host.catalog.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "host-manage",++ "security": [++ {++ "openvibeToken": [++ "host.catalog.manage"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-request.v1"++ }++ }++ }++ },++ "parameters": [++ {++ "name": "id",++ "in": "path",++ "required": true,++ "schema": {++ "type": "string"++ }++ }++ ],++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-result.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },++ "/api/v1/catalog/promos": {++ "post": {++ "operationId": "post_api_v1_catalog_promos",++ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",++ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",++ "tags": [++ "host.catalog"++ ],++ "x-openvibe-capabilities": [++ "host.catalog.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "host-manage",++ "security": [++ {++ "openvibeToken": [++ "host.catalog.manage"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-request.v1"++ }++ }++ }++ },++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-result.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },++ "/api/v1/catalog/promos/{id}": {++ "patch": {++ "operationId": "patch_api_v1_catalog_promos_id",++ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",++ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",++ "tags": [++ "host.catalog"++ ],++ "x-openvibe-capabilities": [++ "host.catalog.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "host-manage",++ "security": [++ {++ "openvibeToken": [++ "host.catalog.manage"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-request.v1"++ }++ }++ }++ },++ "parameters": [++ {++ "name": "id",++ "in": "path",++ "required": true,++ "schema": {++ "type": "string"++ }++ }++ ],++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-result.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },++ "/api/v1/catalog/providers": {++ "post": {++ "operationId": "post_api_v1_catalog_providers",++ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",++ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",++ "tags": [++ "host.catalog"++ ],++ "x-openvibe-capabilities": [++ "host.catalog.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "host-manage",++ "security": [++ {++ "openvibeToken": [++ "host.catalog.manage"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-request.v1"++ }++ }++ }++ },++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-result.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },++ "/api/v1/catalog/providers/{id}": {++ "patch": {++ "operationId": "patch_api_v1_catalog_providers_id",++ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",++ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",++ "tags": [++ "host.catalog"++ ],++ "x-openvibe-capabilities": [++ "host.catalog.manage"++ ],++ "x-openvibe-visibility": [++ "first-party"++ ],++ "x-openvibe-quota-class": "host-manage",++ "security": [++ {++ "openvibeToken": [++ "host.catalog.manage"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-request.v1"++ }++ }++ }++ },++ "parameters": [++ {++ "name": "id",++ "in": "path",++ "required": true,++ "schema": {++ "type": "string"++ }++ }++ ],++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/host.catalog-manage-result.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }++ },"/api/v1/deploys/{id}": {"delete": {"operationId": "delete_api_v1_deploys_id",@@@ -2490,6 +2856,311 @@}}},++ "host.catalog-manage-request.v1": {++ "title": "HostCatalogManageRequest",++ "description": "host.catalog-manage-request@1: bodies of host.catalog.manage on OpenVibe.Host (a Network staff user only). POST/PATCH /api/v1/catalog/providers { slug, name, homepage_url, description?, affiliate_url?, affiliate_note?, status? }; POST/PATCH /api/v1/catalog/plans { provider_id, external_id, name, kind, currency, price_monthly, source_url, vcpu?, ram_mb?, disk_gb?, disk_type?, bandwidth_gb?, unmetered?, port_mbps?, ipv4?, locations?, price_hourly?, setup_fee?, checked_at?, status? } (a plan from OpenVibe.Sources takes only status); POST/PATCH /api/v1/catalog/promos { provider_id, title, url, details?, code?, affiliate?, starts_at?, ends_at?, status? }. A PATCH carries any subset. Unknown fields are refused (422 host.catalog.invalid); a missing entry is 404 host.catalog.not_found; anyone but staff is 403 host.catalog.forbidden. A staff plan's checked_at defaults to now: the staff member confirming the price that day.",++ "anyOf": [++ {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "slug": {++ "type": "string",++ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",++ "maxLength": 80++ },++ "name": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "homepage_url": {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ "description": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048++ },++ "affiliate_url": {++ "anyOf": [++ {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ {++ "type": "null"++ }++ ]++ },++ "affiliate_note": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048,++ "description": "The exact disclosure shown beside the provider's affiliate links."++ },++ "status": {++ "enum": [++ "active",++ "hidden"++ ]++ }++ }++ },++ {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "provider_id": {++ "type": "string"++ },++ "external_id": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "name": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "kind": {++ "enum": [++ "cloud",++ "vps",++ "dedicated",++ "storage",++ "domain"++ ]++ },++ "vcpu": {++ "type": "number",++ "minimum": 0++ },++ "ram_mb": {++ "type": "number",++ "minimum": 0++ },++ "disk_gb": {++ "type": "number",++ "minimum": 0++ },++ "disk_type": {++ "enum": [++ "ssd",++ "nvme",++ "hdd",++ null++ ]++ },++ "bandwidth_gb": {++ "type": "number",++ "minimum": 0++ },++ "unmetered": {++ "type": [++ "boolean",++ "null"++ ]++ },++ "port_mbps": {++ "type": "number",++ "minimum": 0++ },++ "ipv4": {++ "type": "integer",++ "minimum": 0++ },++ "locations": {++ "type": [++ "array",++ "null"++ ],++ "items": {++ "type": "string",++ "minLength": 1++ }++ },++ "currency": {++ "type": "string",++ "pattern": "^[A-Z]{3}$",++ "description": "ISO 4217."++ },++ "price_monthly": {++ "type": "number",++ "minimum": 0,++ "exclusiveMaximum": 100000000++ },++ "price_hourly": {++ "type": [++ "number",++ "null"++ ],++ "minimum": 0++ },++ "setup_fee": {++ "type": [++ "number",++ "null"++ ],++ "minimum": 0++ },++ "source_url": {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ "checked_at": {++ "type": "integer",++ "minimum": 0,++ "description": "Epoch milliseconds the price was confirmed."++ },++ "status": {++ "enum": [++ "active",++ "gone",++ "hidden"++ ]++ }++ }++ },++ {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "provider_id": {++ "type": "string"++ },++ "title": {++ "type": "string",++ "minLength": 1,++ "maxLength": 2048++ },++ "details": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048++ },++ "code": {++ "type": [++ "string",++ "null"++ ],++ "maxLength": 2048++ },++ "url": {++ "type": "string",++ "maxLength": 2048,++ "pattern": "^https?://"++ },++ "affiliate": {++ "type": [++ "boolean",++ "null"++ ]++ },++ "starts_at": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 0,++ "description": "Epoch milliseconds."++ },++ "ends_at": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 0,++ "description": "Epoch milliseconds."++ },++ "status": {++ "enum": [++ "active",++ "ended",++ "hidden"++ ]++ }++ }++ }++ ]++ },++ "host.catalog-manage-result.v1": {++ "title": "HostCatalogManageResult",++ "description": "host.catalog-manage-result@1: the saved entry, under its type's name: { provider } (with affiliate_rel and affiliate_disclosure when it has an affiliate link), { plan } or { promo } (an active promo past ends_at reads as ended). 201 on create, 200 on update.",++ "anyOf": [++ {++ "type": "object",++ "required": [++ "provider"++ ],++ "properties": {++ "provider": {++ "type": "object",++ "required": [++ "id"++ ],++ "properties": {++ "id": {++ "type": "string"++ }++ },++ "additionalProperties": true++ }++ }++ },++ {++ "type": "object",++ "required": [++ "plan"++ ],++ "properties": {++ "plan": {++ "type": "object",++ "required": [++ "id"++ ],++ "properties": {++ "id": {++ "type": "string"++ }++ },++ "additionalProperties": true++ }++ }++ },++ {++ "type": "object",++ "required": [++ "promo"++ ],++ "properties": {++ "promo": {++ "type": "object",++ "required": [++ "id"++ ],++ "properties": {++ "id": {++ "type": "string"++ }++ },++ "additionalProperties": true++ }++ }++ }++ ]++ },"host.deploy-create-request.v1": {"title": "HostDeployCreateRequest","description": "host.deploy-create-request@1: bodies of host.deploy.create on OpenVibe.Host (a deployer or above of the project; an app principal added as deployer can deploy from CI). POST /api/v1/sites/:id/deploys uploads a deploy: the raw body is a tar or tar.gz archive (Content-Type application/gzip, application/x-gzip, application/x-tar or application/octet-stream), or multipart/form-data with archive=<one archive> or files=<file>… (each part's filename is its path); optional fields activate=1, root=<subdirectory to deploy> and strip=folder (removes a shared first segment) also work as query parameters. It is validated (path traversal, links, special and hidden files, server-side code, file types, sizes and quotas) and never executed; a refusal is a problem whose extra carries the failed deploy_id and its log (413 upload.too_large, quota.storage; 422 validation codes; 429 quota.deploys_per_day; 403 site.taken_down; 503 upload.busy; 507 storage.host_full). POST /api/v1/deploys/:id/activate { expected_active? } and POST /api/v1/sites/:id/rollback { deploy_id?, expected_active? } switch the site's pointer in one step (rollback without deploy_id goes to the deploy active before; 409 deploy.not_ready, site.active_changed when expected_active is stale, deploy.no_previous). GET /api/v1/sites/:id/deploys, /deploys/:id and /deploys/:id/log take no body.",@@@ -89,8 +89,8 @@"service": "host","name": "OpenVibe.Host","origin": "https://openvibe.host",-- "operations": 36,-- "capabilities": 5++ "operations": 42,++ "capabilities": 6},{"service": "inventory",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Inventory API",-- "version": "0.138.0",-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.News API",-- "version": "0.138.0",-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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"@@@ -54816,6 +54816,93 @@ export type HostSiteManageResult =lifted: true;};++/** [email protected] (owner: host) */++/**++ * host.catalog-manage-request@1: bodies of host.catalog.manage on OpenVibe.Host (a Network staff user only). POST/PATCH /api/v1/catalog/providers { slug, name, homepage_url, description?, affiliate_url?, affiliate_note?, status? }; POST/PATCH /api/v1/catalog/plans { provider_id, external_id, name, kind, currency, price_monthly, source_url, vcpu?, ram_mb?, disk_gb?, disk_type?, bandwidth_gb?, unmetered?, port_mbps?, ipv4?, locations?, price_hourly?, setup_fee?, checked_at?, status? } (a plan from OpenVibe.Sources takes only status); POST/PATCH /api/v1/catalog/promos { provider_id, title, url, details?, code?, affiliate?, starts_at?, ends_at?, status? }. A PATCH carries any subset. Unknown fields are refused (422 host.catalog.invalid); a missing entry is 404 host.catalog.not_found; anyone but staff is 403 host.catalog.forbidden. A staff plan's checked_at defaults to now: the staff member confirming the price that day.++ */++export type HostCatalogManageRequest =++ | {++ slug?: string;++ name?: string;++ homepage_url?: string;++ description?: string | null;++ affiliate_url?: string | null;++ /**++ * The exact disclosure shown beside the provider's affiliate links.++ */++ affiliate_note?: string | null;++ status?: "active" | "hidden";++ }++ | {++ provider_id?: string;++ external_id?: string;++ name?: string;++ kind?: "cloud" | "vps" | "dedicated" | "storage" | "domain";++ vcpu?: number;++ ram_mb?: number;++ disk_gb?: number;++ disk_type?: "ssd" | "nvme" | "hdd" | null;++ bandwidth_gb?: number;++ unmetered?: boolean | null;++ port_mbps?: number;++ ipv4?: number;++ locations?: string[] | null;++ /**++ * ISO 4217.++ */++ currency?: string;++ price_monthly?: number;++ price_hourly?: number | null;++ setup_fee?: number | null;++ source_url?: string;++ /**++ * Epoch milliseconds the price was confirmed.++ */++ checked_at?: number;++ status?: "active" | "gone" | "hidden";++ }++ | {++ provider_id?: string;++ title?: string;++ details?: string | null;++ code?: string | null;++ url?: string;++ affiliate?: boolean | null;++ /**++ * Epoch milliseconds.++ */++ starts_at?: number | null;++ /**++ * Epoch milliseconds.++ */++ ends_at?: number | null;++ status?: "active" | "ended" | "hidden";++ };++++/** [email protected] (owner: host) */++/**++ * host.catalog-manage-result@1: the saved entry, under its type's name: { provider } (with affiliate_rel and affiliate_disclosure when it has an affiliate link), { plan } or { promo } (an active promo past ends_at reads as ended). 201 on create, 200 on update.++ */++export type HostCatalogManageResult =++ | {++ provider: {++ id: string;++ [k: string]: unknown | undefined;++ };++ }++ | {++ plan: {++ id: string;++ [k: string]: unknown | undefined;++ };++ }++ | {++ promo: {++ id: string;++ [k: string]: unknown | undefined;++ };++ };++/** [email protected] (owner: host) *//*** host.site@1: one static site on OpenVibe.Host (server/http/serialize.js site): its name (one DNS label), the default hostname and URL it is served at, the deploy it serves (one pointer; null until a deploy is activated) and any staff takedown.nnew file mode 100644@@@ -0,0 +1,26 @@++{++ "id": "host.catalog.manage",++ "version": "1.0",++ "owner": "host",++ "status": "active",++ "visibility": "first-party",++ "description": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",++ "permissions": [++ "host:write"++ ],++ "resourceConstraints": [++ "none"++ ],++ "quotaClass": "host-manage",++ "events": [],++ "implementedBy": [++ "POST /api/v1/catalog/providers",++ "PATCH /api/v1/catalog/providers/:id",++ "POST /api/v1/catalog/plans",++ "PATCH /api/v1/catalog/plans/:id",++ "POST /api/v1/catalog/promos",++ "PATCH /api/v1/catalog/promos/:id"++ ],++ "inputSchema": "host.catalog-manage-request@1",++ "outputSchema": "host.catalog-manage-result@1"++}@@@ -69,7 +69,8 @@"host.deploy.create","host.domain.manage","host.resource.read",-- "host.site.config"++ "host.site.config",++ "host.catalog.manage"],"eventsProduced": ["host.deploy.created",@@@ -1,6 +1,6 @@{"name": "openvibe-contracts",-- "version": "0.138.0",++ "version": "0.139.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",
@@ -4,6 +4,13 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
@@ -4,6 +4,13 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
the notes were in the tag and commit messages (`git tag -n1`).
the notes were in the tag and commit messages (`git tag -n1`).
+## 0.139.0 — 2026-10-11
+
+- `host.catalog.manage` (active, staff only) with `host.catalog-manage-request@1` and `host.catalog-manage-result@1`:
+ OpenVibe.Host's hosting catalog (plan T20 step 3), staff entries for providers (affiliate link and its exact
+ disclosure), plans (source URL, currency, monthly price, the date it was confirmed) and promotions. The catalog's
+ reads are public.
+
## 0.138.0 — 2026-10-11
## 0.138.0 — 2026-10-11
- Sources category `hosting` (`sources.source@1`, `sources.item@1`, `sources.source-write-request@1` and the
- Sources category `hosting` (`sources.source@1`, `sources.item@1`, `sources.source-write-request@1` and the
@@ -5526,6 +5526,24 @@
@@ -5526,6 +5526,24 @@
"compatibility": "backward",
"compatibility": "backward",
"status": "active"
"status": "active"
},
},
+ {
+ "id": "host.catalog-manage-request",
+ "version": "1.0.0",
+ "owner": "host",
+ "schema": "host/catalog-manage-request.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active"
+ },
+ {
+ "id": "host.catalog-manage-result",
+ "version": "1.0.0",
+ "owner": "host",
+ "schema": "host/catalog-manage-result.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active"
+ },
{
{
"id": "host.site",
"id": "host.site",
"version": "1.0.0",
"version": "1.0.0",
new file mode 100644
new file mode 100644
@@ -0,0 +1,241 @@
@@ -0,0 +1,241 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/host/catalog-manage-request.v1.json",
+ "title": "HostCatalogManageRequest",
+ "description": "host.catalog-manage-request@1: bodies of host.catalog.manage on OpenVibe.Host (a Network staff user only). POST/PATCH /api/v1/catalog/providers { slug, name, homepage_url, description?, affiliate_url?, affiliate_note?, status? }; POST/PATCH /api/v1/catalog/plans { provider_id, external_id, name, kind, currency, price_monthly, source_url, vcpu?, ram_mb?, disk_gb?, disk_type?, bandwidth_gb?, unmetered?, port_mbps?, ipv4?, locations?, price_hourly?, setup_fee?, checked_at?, status? } (a plan from OpenVibe.Sources takes only status); POST/PATCH /api/v1/catalog/promos { provider_id, title, url, details?, code?, affiliate?, starts_at?, ends_at?, status? }. A PATCH carries any subset. Unknown fields are refused (422 host.catalog.invalid); a missing entry is 404 host.catalog.not_found; anyone but staff is 403 host.catalog.forbidden. A staff plan's checked_at defaults to now: the staff member confirming the price that day.",
+ "anyOf": [
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "slug": {
+ "type": "string",
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
+ "maxLength": 80
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "homepage_url": {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048
+ },
+ "affiliate_url": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "affiliate_note": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048,
+ "description": "The exact disclosure shown beside the provider's affiliate links."
+ },
+ "status": {
+ "enum": [
+ "active",
+ "hidden"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider_id": {
+ "type": "string"
+ },
+ "external_id": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "kind": {
+ "enum": [
+ "cloud",
+ "vps",
+ "dedicated",
+ "storage",
+ "domain"
+ ]
+ },
+ "vcpu": {
+ "type": "number",
+ "minimum": 0
+ },
+ "ram_mb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "disk_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "disk_type": {
+ "enum": [
+ "ssd",
+ "nvme",
+ "hdd",
+ null
+ ]
+ },
+ "bandwidth_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "unmetered": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "port_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "ipv4": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "locations": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string",
+ "minLength": 1
+ }
+ },
+ "currency": {
+ "type": "string",
+ "pattern": "^[A-Z]{3}$",
+ "description": "ISO 4217."
+ },
+ "price_monthly": {
+ "type": "number",
+ "minimum": 0,
+ "exclusiveMaximum": 100000000
+ },
+ "price_hourly": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0
+ },
+ "setup_fee": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0
+ },
+ "source_url": {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ "checked_at": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Epoch milliseconds the price was confirmed."
+ },
+ "status": {
+ "enum": [
+ "active",
+ "gone",
+ "hidden"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider_id": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "details": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048
+ },
+ "code": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048
+ },
+ "url": {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ "affiliate": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "starts_at": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 0,
+ "description": "Epoch milliseconds."
+ },
+ "ends_at": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 0,
+ "description": "Epoch milliseconds."
+ },
+ "status": {
+ "enum": [
+ "active",
+ "ended",
+ "hidden"
+ ]
+ }
+ }
+ }
+ ]
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/host/catalog-manage-result.v1.json",
+ "title": "HostCatalogManageResult",
+ "description": "host.catalog-manage-result@1: the saved entry, under its type's name: { provider } (with affiliate_rel and affiliate_disclosure when it has an affiliate link), { plan } or { promo } (an active promo past ends_at reads as ended). 201 on create, 200 on update.",
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "provider"
+ ],
+ "properties": {
+ "provider": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "plan"
+ ],
+ "properties": {
+ "plan": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "promo"
+ ],
+ "properties": {
+ "promo": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ }
+ ]
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
+{
+ "provider_id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",
+ "external_id": "x",
+ "name": "X",
+ "kind": "vps",
+ "currency": "USD",
+ "price_monthly": -1,
+ "source_url": "https://example.com/"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
+{
+ "slug": "x",
+ "name": "X",
+ "homepage_url": "https://x.example/",
+ "rank_boost": 10
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
+{
+ "provider_id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",
+ "external_id": "x",
+ "name": "X",
+ "kind": "shared",
+ "currency": "USD",
+ "price_monthly": 1,
+ "source_url": "https://example.com/"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
+{
+ "provider_id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",
+ "external_id": "cx22",
+ "name": "CX22",
+ "kind": "cloud",
+ "vcpu": 2,
+ "ram_mb": 4096,
+ "disk_gb": 40,
+ "disk_type": "nvme",
+ "bandwidth_gb": 20480,
+ "ipv4": 1,
+ "locations": [
+ "Falkenstein",
+ "Nuremberg",
+ "Helsinki"
+ ],
+ "currency": "EUR",
+ "price_monthly": 4.59,
+ "source_url": "https://www.hetzner.com/cloud/"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
+{
+ "provider_id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",
+ "title": "First month free",
+ "url": "https://www.example.com/offer",
+ "affiliate": false,
+ "ends_at": 1793491200000
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
+{
+ "slug": "hetzner",
+ "name": "Hetzner",
+ "homepage_url": "https://www.hetzner.com/",
+ "affiliate_url": null,
+ "status": "active"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
+{
+ "status": "hidden"
+}
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,5 @@
@@ -0,0 +1,5 @@
+{
+ "entry": {
+ "id": "hpl_01M4C49CWJCFYGJS3T7NFZFQYX"
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
+{
+ "plan": {
+ "id": "hpl_01M4C49CWJCFYGJS3T7NFZFQYX",
+ "external_id": "cx22",
+ "name": "CX22",
+ "currency": "EUR",
+ "price_monthly": "4.5900",
+ "origin": "staff"
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
+{
+ "provider": {
+ "id": "hpv_01M4C49CW34NGX7TR2TNRVFWNW",
+ "slug": "hetzner",
+ "name": "Hetzner",
+ "homepage_url": "https://www.hetzner.com/",
+ "affiliate_url": null,
+ "affiliate_rel": null,
+ "affiliate_disclosure": null,
+ "status": "active"
+ }
+}
@@ -63023,6 +63023,325 @@
@@ -63023,6 +63023,325 @@
]
]
}
}
},
},
+ "host.catalog-manage-request": {
+ "version": "1.0.0",
+ "owner": "host",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/host/catalog-manage-request.v1.json",
+ "title": "HostCatalogManageRequest",
+ "description": "host.catalog-manage-request@1: bodies of host.catalog.manage on OpenVibe.Host (a Network staff user only). POST/PATCH /api/v1/catalog/providers { slug, name, homepage_url, description?, affiliate_url?, affiliate_note?, status? }; POST/PATCH /api/v1/catalog/plans { provider_id, external_id, name, kind, currency, price_monthly, source_url, vcpu?, ram_mb?, disk_gb?, disk_type?, bandwidth_gb?, unmetered?, port_mbps?, ipv4?, locations?, price_hourly?, setup_fee?, checked_at?, status? } (a plan from OpenVibe.Sources takes only status); POST/PATCH /api/v1/catalog/promos { provider_id, title, url, details?, code?, affiliate?, starts_at?, ends_at?, status? }. A PATCH carries any subset. Unknown fields are refused (422 host.catalog.invalid); a missing entry is 404 host.catalog.not_found; anyone but staff is 403 host.catalog.forbidden. A staff plan's checked_at defaults to now: the staff member confirming the price that day.",
+ "anyOf": [
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "slug": {
+ "type": "string",
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
+ "maxLength": 80
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "homepage_url": {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048
+ },
+ "affiliate_url": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "affiliate_note": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048,
+ "description": "The exact disclosure shown beside the provider's affiliate links."
+ },
+ "status": {
+ "enum": [
+ "active",
+ "hidden"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider_id": {
+ "type": "string"
+ },
+ "external_id": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "kind": {
+ "enum": [
+ "cloud",
+ "vps",
+ "dedicated",
+ "storage",
+ "domain"
+ ]
+ },
+ "vcpu": {
+ "type": "number",
+ "minimum": 0
+ },
+ "ram_mb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "disk_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "disk_type": {
+ "enum": [
+ "ssd",
+ "nvme",
+ "hdd",
+ null
+ ]
+ },
+ "bandwidth_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "unmetered": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "port_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "ipv4": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "locations": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string",
+ "minLength": 1
+ }
+ },
+ "currency": {
+ "type": "string",
+ "pattern": "^[A-Z]{3}$",
+ "description": "ISO 4217."
+ },
+ "price_monthly": {
+ "type": "number",
+ "minimum": 0,
+ "exclusiveMaximum": 100000000
+ },
+ "price_hourly": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0
+ },
+ "setup_fee": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0
+ },
+ "source_url": {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ "checked_at": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Epoch milliseconds the price was confirmed."
+ },
+ "status": {
+ "enum": [
+ "active",
+ "gone",
+ "hidden"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider_id": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "details": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048
+ },
+ "code": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048
+ },
+ "url": {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ "affiliate": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "starts_at": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 0,
+ "description": "Epoch milliseconds."
+ },
+ "ends_at": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 0,
+ "description": "Epoch milliseconds."
+ },
+ "status": {
+ "enum": [
+ "active",
+ "ended",
+ "hidden"
+ ]
+ }
+ }
+ }
+ ]
+ }
+ },
+ "host.catalog-manage-result": {
+ "version": "1.0.0",
+ "owner": "host",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/host/catalog-manage-result.v1.json",
+ "title": "HostCatalogManageResult",
+ "description": "host.catalog-manage-result@1: the saved entry, under its type's name: { provider } (with affiliate_rel and affiliate_disclosure when it has an affiliate link), { plan } or { promo } (an active promo past ends_at reads as ended). 201 on create, 200 on update.",
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "provider"
+ ],
+ "properties": {
+ "provider": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "plan"
+ ],
+ "properties": {
+ "plan": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "promo"
+ ],
+ "properties": {
+ "promo": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ }
+ ]
+ }
+ },
"host.site": {
"host.site": {
"version": "1.0.0",
"version": "1.0.0",
"owner": "host",
"owner": "host",
@@ -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.138.0",
- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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"
@@ -16,6 +16,372 @@
@@ -16,6 +16,372 @@
}
}
],
],
"paths": {
"paths": {
+ "/api/v1/catalog/plans": {
+ "post": {
+ "operationId": "post_api_v1_catalog_plans",
+ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",
+ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",
+ "tags": [
+ "host.catalog"
+ ],
+ "x-openvibe-capabilities": [
+ "host.catalog.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "host-manage",
+ "security": [
+ {
+ "openvibeToken": [
+ "host.catalog.manage"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-request.v1"
+ }
+ }
+ }
+ },
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-result.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/v1/catalog/plans/{id}": {
+ "patch": {
+ "operationId": "patch_api_v1_catalog_plans_id",
+ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",
+ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",
+ "tags": [
+ "host.catalog"
+ ],
+ "x-openvibe-capabilities": [
+ "host.catalog.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "host-manage",
+ "security": [
+ {
+ "openvibeToken": [
+ "host.catalog.manage"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-request.v1"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-result.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/v1/catalog/promos": {
+ "post": {
+ "operationId": "post_api_v1_catalog_promos",
+ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",
+ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",
+ "tags": [
+ "host.catalog"
+ ],
+ "x-openvibe-capabilities": [
+ "host.catalog.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "host-manage",
+ "security": [
+ {
+ "openvibeToken": [
+ "host.catalog.manage"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-request.v1"
+ }
+ }
+ }
+ },
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-result.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/v1/catalog/promos/{id}": {
+ "patch": {
+ "operationId": "patch_api_v1_catalog_promos_id",
+ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",
+ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",
+ "tags": [
+ "host.catalog"
+ ],
+ "x-openvibe-capabilities": [
+ "host.catalog.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "host-manage",
+ "security": [
+ {
+ "openvibeToken": [
+ "host.catalog.manage"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-request.v1"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-result.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/v1/catalog/providers": {
+ "post": {
+ "operationId": "post_api_v1_catalog_providers",
+ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",
+ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",
+ "tags": [
+ "host.catalog"
+ ],
+ "x-openvibe-capabilities": [
+ "host.catalog.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "host-manage",
+ "security": [
+ {
+ "openvibeToken": [
+ "host.catalog.manage"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-request.v1"
+ }
+ }
+ }
+ },
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-result.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/v1/catalog/providers/{id}": {
+ "patch": {
+ "operationId": "patch_api_v1_catalog_providers_id",
+ "summary": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL,",
+ "description": "**host.catalog.manage** (first-party): Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",
+ "tags": [
+ "host.catalog"
+ ],
+ "x-openvibe-capabilities": [
+ "host.catalog.manage"
+ ],
+ "x-openvibe-visibility": [
+ "first-party"
+ ],
+ "x-openvibe-quota-class": "host-manage",
+ "security": [
+ {
+ "openvibeToken": [
+ "host.catalog.manage"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-request.v1"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/host.catalog-manage-result.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/api/v1/deploys/{id}": {
"/api/v1/deploys/{id}": {
"delete": {
"delete": {
"operationId": "delete_api_v1_deploys_id",
"operationId": "delete_api_v1_deploys_id",
@@ -2490,6 +2856,311 @@
@@ -2490,6 +2856,311 @@
}
}
}
}
},
},
+ "host.catalog-manage-request.v1": {
+ "title": "HostCatalogManageRequest",
+ "description": "host.catalog-manage-request@1: bodies of host.catalog.manage on OpenVibe.Host (a Network staff user only). POST/PATCH /api/v1/catalog/providers { slug, name, homepage_url, description?, affiliate_url?, affiliate_note?, status? }; POST/PATCH /api/v1/catalog/plans { provider_id, external_id, name, kind, currency, price_monthly, source_url, vcpu?, ram_mb?, disk_gb?, disk_type?, bandwidth_gb?, unmetered?, port_mbps?, ipv4?, locations?, price_hourly?, setup_fee?, checked_at?, status? } (a plan from OpenVibe.Sources takes only status); POST/PATCH /api/v1/catalog/promos { provider_id, title, url, details?, code?, affiliate?, starts_at?, ends_at?, status? }. A PATCH carries any subset. Unknown fields are refused (422 host.catalog.invalid); a missing entry is 404 host.catalog.not_found; anyone but staff is 403 host.catalog.forbidden. A staff plan's checked_at defaults to now: the staff member confirming the price that day.",
+ "anyOf": [
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "slug": {
+ "type": "string",
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
+ "maxLength": 80
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "homepage_url": {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048
+ },
+ "affiliate_url": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "affiliate_note": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048,
+ "description": "The exact disclosure shown beside the provider's affiliate links."
+ },
+ "status": {
+ "enum": [
+ "active",
+ "hidden"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider_id": {
+ "type": "string"
+ },
+ "external_id": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "kind": {
+ "enum": [
+ "cloud",
+ "vps",
+ "dedicated",
+ "storage",
+ "domain"
+ ]
+ },
+ "vcpu": {
+ "type": "number",
+ "minimum": 0
+ },
+ "ram_mb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "disk_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "disk_type": {
+ "enum": [
+ "ssd",
+ "nvme",
+ "hdd",
+ null
+ ]
+ },
+ "bandwidth_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "unmetered": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "port_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "ipv4": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "locations": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string",
+ "minLength": 1
+ }
+ },
+ "currency": {
+ "type": "string",
+ "pattern": "^[A-Z]{3}$",
+ "description": "ISO 4217."
+ },
+ "price_monthly": {
+ "type": "number",
+ "minimum": 0,
+ "exclusiveMaximum": 100000000
+ },
+ "price_hourly": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0
+ },
+ "setup_fee": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0
+ },
+ "source_url": {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ "checked_at": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "Epoch milliseconds the price was confirmed."
+ },
+ "status": {
+ "enum": [
+ "active",
+ "gone",
+ "hidden"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider_id": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 2048
+ },
+ "details": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048
+ },
+ "code": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 2048
+ },
+ "url": {
+ "type": "string",
+ "maxLength": 2048,
+ "pattern": "^https?://"
+ },
+ "affiliate": {
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "starts_at": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 0,
+ "description": "Epoch milliseconds."
+ },
+ "ends_at": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 0,
+ "description": "Epoch milliseconds."
+ },
+ "status": {
+ "enum": [
+ "active",
+ "ended",
+ "hidden"
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "host.catalog-manage-result.v1": {
+ "title": "HostCatalogManageResult",
+ "description": "host.catalog-manage-result@1: the saved entry, under its type's name: { provider } (with affiliate_rel and affiliate_disclosure when it has an affiliate link), { plan } or { promo } (an active promo past ends_at reads as ended). 201 on create, 200 on update.",
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "provider"
+ ],
+ "properties": {
+ "provider": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "plan"
+ ],
+ "properties": {
+ "plan": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "promo"
+ ],
+ "properties": {
+ "promo": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ }
+ ]
+ },
"host.deploy-create-request.v1": {
"host.deploy-create-request.v1": {
"title": "HostDeployCreateRequest",
"title": "HostDeployCreateRequest",
"description": "host.deploy-create-request@1: bodies of host.deploy.create on OpenVibe.Host (a deployer or above of the project; an app principal added as deployer can deploy from CI). POST /api/v1/sites/:id/deploys uploads a deploy: the raw body is a tar or tar.gz archive (Content-Type application/gzip, application/x-gzip, application/x-tar or application/octet-stream), or multipart/form-data with archive=<one archive> or files=<file>… (each part's filename is its path); optional fields activate=1, root=<subdirectory to deploy> and strip=folder (removes a shared first segment) also work as query parameters. It is validated (path traversal, links, special and hidden files, server-side code, file types, sizes and quotas) and never executed; a refusal is a problem whose extra carries the failed deploy_id and its log (413 upload.too_large, quota.storage; 422 validation codes; 429 quota.deploys_per_day; 403 site.taken_down; 503 upload.busy; 507 storage.host_full). POST /api/v1/deploys/:id/activate { expected_active? } and POST /api/v1/sites/:id/rollback { deploy_id?, expected_active? } switch the site's pointer in one step (rollback without deploy_id goes to the deploy active before; 409 deploy.not_ready, site.active_changed when expected_active is stale, deploy.no_previous). GET /api/v1/sites/:id/deploys, /deploys/:id and /deploys/:id/log take no body.",
"description": "host.deploy-create-request@1: bodies of host.deploy.create on OpenVibe.Host (a deployer or above of the project; an app principal added as deployer can deploy from CI). POST /api/v1/sites/:id/deploys uploads a deploy: the raw body is a tar or tar.gz archive (Content-Type application/gzip, application/x-gzip, application/x-tar or application/octet-stream), or multipart/form-data with archive=<one archive> or files=<file>… (each part's filename is its path); optional fields activate=1, root=<subdirectory to deploy> and strip=folder (removes a shared first segment) also work as query parameters. It is validated (path traversal, links, special and hidden files, server-side code, file types, sizes and quotas) and never executed; a refusal is a problem whose extra carries the failed deploy_id and its log (413 upload.too_large, quota.storage; 422 validation codes; 429 quota.deploys_per_day; 403 site.taken_down; 503 upload.busy; 507 storage.host_full). POST /api/v1/deploys/:id/activate { expected_active? } and POST /api/v1/sites/:id/rollback { deploy_id?, expected_active? } switch the site's pointer in one step (rollback without deploy_id goes to the deploy active before; 409 deploy.not_ready, site.active_changed when expected_active is stale, deploy.no_previous). GET /api/v1/sites/:id/deploys, /deploys/:id and /deploys/:id/log take no body.",
@@ -89,8 +89,8 @@
@@ -89,8 +89,8 @@
"service": "host",
"service": "host",
"name": "OpenVibe.Host",
"name": "OpenVibe.Host",
"origin": "https://openvibe.host",
"origin": "https://openvibe.host",
- "operations": 36,
- "capabilities": 5
+ "operations": 42,
+ "capabilities": 6
},
},
{
{
"service": "inventory",
"service": "inventory",
@@ -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.138.0",
- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.News API",
"title": "OpenVibe.News API",
- "version": "0.138.0",
- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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.138.0",
- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.138.0): each operation lists the capabilities it performs; a token for 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.139.0",
+ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.139.0): each operation lists the capabilities it performs; a token for 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"
@@ -54816,6 +54816,93 @@ export type HostSiteManageResult =
@@ -54816,6 +54816,93 @@ export type HostSiteManageResult =
lifted: true;
lifted: true;
};
};
+/** [email protected] (owner: host) */
+/**
+ * host.catalog-manage-request@1: bodies of host.catalog.manage on OpenVibe.Host (a Network staff user only). POST/PATCH /api/v1/catalog/providers { slug, name, homepage_url, description?, affiliate_url?, affiliate_note?, status? }; POST/PATCH /api/v1/catalog/plans { provider_id, external_id, name, kind, currency, price_monthly, source_url, vcpu?, ram_mb?, disk_gb?, disk_type?, bandwidth_gb?, unmetered?, port_mbps?, ipv4?, locations?, price_hourly?, setup_fee?, checked_at?, status? } (a plan from OpenVibe.Sources takes only status); POST/PATCH /api/v1/catalog/promos { provider_id, title, url, details?, code?, affiliate?, starts_at?, ends_at?, status? }. A PATCH carries any subset. Unknown fields are refused (422 host.catalog.invalid); a missing entry is 404 host.catalog.not_found; anyone but staff is 403 host.catalog.forbidden. A staff plan's checked_at defaults to now: the staff member confirming the price that day.
+ */
+export type HostCatalogManageRequest =
+ | {
+ slug?: string;
+ name?: string;
+ homepage_url?: string;
+ description?: string | null;
+ affiliate_url?: string | null;
+ /**
+ * The exact disclosure shown beside the provider's affiliate links.
+ */
+ affiliate_note?: string | null;
+ status?: "active" | "hidden";
+ }
+ | {
+ provider_id?: string;
+ external_id?: string;
+ name?: string;
+ kind?: "cloud" | "vps" | "dedicated" | "storage" | "domain";
+ vcpu?: number;
+ ram_mb?: number;
+ disk_gb?: number;
+ disk_type?: "ssd" | "nvme" | "hdd" | null;
+ bandwidth_gb?: number;
+ unmetered?: boolean | null;
+ port_mbps?: number;
+ ipv4?: number;
+ locations?: string[] | null;
+ /**
+ * ISO 4217.
+ */
+ currency?: string;
+ price_monthly?: number;
+ price_hourly?: number | null;
+ setup_fee?: number | null;
+ source_url?: string;
+ /**
+ * Epoch milliseconds the price was confirmed.
+ */
+ checked_at?: number;
+ status?: "active" | "gone" | "hidden";
+ }
+ | {
+ provider_id?: string;
+ title?: string;
+ details?: string | null;
+ code?: string | null;
+ url?: string;
+ affiliate?: boolean | null;
+ /**
+ * Epoch milliseconds.
+ */
+ starts_at?: number | null;
+ /**
+ * Epoch milliseconds.
+ */
+ ends_at?: number | null;
+ status?: "active" | "ended" | "hidden";
+ };
+
+/** [email protected] (owner: host) */
+/**
+ * host.catalog-manage-result@1: the saved entry, under its type's name: { provider } (with affiliate_rel and affiliate_disclosure when it has an affiliate link), { plan } or { promo } (an active promo past ends_at reads as ended). 201 on create, 200 on update.
+ */
+export type HostCatalogManageResult =
+ | {
+ provider: {
+ id: string;
+ [k: string]: unknown | undefined;
+ };
+ }
+ | {
+ plan: {
+ id: string;
+ [k: string]: unknown | undefined;
+ };
+ }
+ | {
+ promo: {
+ id: string;
+ [k: string]: unknown | undefined;
+ };
+ };
+
/** [email protected] (owner: host) */
/** [email protected] (owner: host) */
/**
/**
* host.site@1: one static site on OpenVibe.Host (server/http/serialize.js site): its name (one DNS label), the default hostname and URL it is served at, the deploy it serves (one pointer; null until a deploy is activated) and any staff takedown.
* host.site@1: one static site on OpenVibe.Host (server/http/serialize.js site): its name (one DNS label), the default hostname and URL it is served at, the deploy it serves (one pointer; null until a deploy is activated) and any staff takedown.
new file mode 100644
new file mode 100644
@@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
+{
+ "id": "host.catalog.manage",
+ "version": "1.0",
+ "owner": "host",
+ "status": "active",
+ "visibility": "first-party",
+ "description": "Keep OpenVibe.Host's hosting catalog (plan T20 step 3: hosting compared): create and edit providers (with their affiliate link and the exact disclosure), staff-entered plans (each with its source URL, currency, monthly price and the date it was confirmed; a plan that came from OpenVibe.Sources takes only a status change) and promotions. Held by Network staff users only. The catalog's reads are public and need no capability.",
+ "permissions": [
+ "host:write"
+ ],
+ "resourceConstraints": [
+ "none"
+ ],
+ "quotaClass": "host-manage",
+ "events": [],
+ "implementedBy": [
+ "POST /api/v1/catalog/providers",
+ "PATCH /api/v1/catalog/providers/:id",
+ "POST /api/v1/catalog/plans",
+ "PATCH /api/v1/catalog/plans/:id",
+ "POST /api/v1/catalog/promos",
+ "PATCH /api/v1/catalog/promos/:id"
+ ],
+ "inputSchema": "host.catalog-manage-request@1",
+ "outputSchema": "host.catalog-manage-result@1"
+}
@@ -69,7 +69,8 @@
@@ -69,7 +69,8 @@
"host.deploy.create",
"host.deploy.create",
"host.domain.manage",
"host.domain.manage",
"host.resource.read",
"host.resource.read",
- "host.site.config"
+ "host.site.config",
+ "host.catalog.manage"
],
],
"eventsProduced": [
"eventsProduced": [
"host.deploy.created",
"host.deploy.created",
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.138.0",
+ "version": "0.139.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",