openvibers/openvibe.contracts Commits
Contracts 0.81.0: opaque event cursors beside the global seq (plan T7, ADR-042): publish-result carries a cursor per stored event, read-result a cursor per event, next_cursor per page and a cursor on a single event; seq stays for one release. Fixtures for both; 14358 checks; compat vs v0.80.0: no breaking changes.
Changes
@@@ -4,6 +4,15 @@ 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.81.0 — 2026-09-29++++**Opaque cursors beside the global seq** (plan T7, ADR-042, additive).++- `events.publish-result@1` gains an optional `cursor` per stored event; `events.read-result@1` gains `cursor` per++ event, `next_cursor` per page and `cursor` on a single event. A cursor is opaque (a position plus a retention epoch):++ hand it back as `after=` or `Last-Event-ID`, never parse it. Events returns both `seq` and `cursor` for one release,++ then `seq`, `next_after_seq`, `latest_seq` and the global-order promise go.++- ADR-042 (the events fabric) is recorded in docs/adr.++## 0.80.0 — 2026-09-29**`chat.moderation.read`: how Live reads the chat tables Chat owns** (plan T3, the six staged tables).@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/events/publish-result.v1.json","title": "EventsPublishResult",-- "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).",++ "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate, cursor? } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).","anyOf": [{"type": "object",@@@ -23,6 +23,12 @@"duplicate": {"type": "boolean","description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}},@@@ -55,6 +61,12 @@"duplicate": {"type": "boolean","description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}}@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/events/read-result.v1.json","title": "EventsReadResult",-- "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, event }], next_after_seq, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.",++ "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, cursor?, event }], next_after_seq, next_cursor?, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the cursor once Events sends one, else the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.","anyOf": [{"type": "object",@@@ -28,6 +28,12 @@},"event": {"$ref": "event-envelope.v1.json"++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}}@@@ -54,6 +60,12 @@"type": "integer"}}++ },++ "next_cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position after this page (ADR-042): pass it back as after= for the next page. Returned beside next_after_seq for one release."}}},@@@ -70,6 +82,12 @@},"event": {"$ref": "event-envelope.v1.json"++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}},nnew file mode 100644@@@ -0,0 +1,6 @@++{++ "event_id": "evt_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "seq": 88213,++ "duplicate": false,++ "cursor": ""++}nnew file mode 100644@@@ -0,0 +1,6 @@++{++ "event_id": "evt_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "seq": 88213,++ "duplicate": false,++ "cursor": "c1.e0.MTIzNDU"++}nnew file mode 100644@@@ -0,0 +1,30 @@++{++ "events": [++ {++ "seq": 88213,++ "event": {++ "event_id": "evt_01JAB2C3D4E5F6G7H8J9K0MNPR",++ "event_type": "app.p01jab2c3d4e5f6g7h8j9k0mnpq.order.created",++ "version": 1,++ "source": "app-01jab2c3d4e5f6g7h8j9k0mnps",++ "actor": {++ "type": "app",++ "id": "app_01JAB2C3D4E5F6G7H8J9K0MNPS"++ },++ "timestamp": "2026-09-23T12:00:00Z",++ "visibility": "internal",++ "subject": {++ "type": "order",++ "id": "42"++ },++ "payload": {++ "total": 3++ }++ },++ "cursor": "c1.e0.1"++ }++ ],++ "next_after_seq": 88240,++ "latest_seq": 88240,++ "next_cursor": "c1.e0.next"++}@@@ -5058,7 +5058,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/events/publish-result.v1.json","title": "EventsPublishResult",-- "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).",++ "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate, cursor? } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).","anyOf": [{"type": "object",@@@ -5079,6 +5079,12 @@"duplicate": {"type": "boolean","description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}},@@@ -5111,6 +5117,12 @@"duplicate": {"type": "boolean","description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}}@@@ -5164,7 +5176,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/events/read-result.v1.json","title": "EventsReadResult",-- "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, event }], next_after_seq, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.",++ "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, cursor?, event }], next_after_seq, next_cursor?, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the cursor once Events sends one, else the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.","anyOf": [{"type": "object",@@@ -5190,6 +5202,12 @@},"event": {"$ref": "event-envelope.v1.json"++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}}@@@ -5216,6 +5234,12 @@"type": "integer"}}++ },++ "next_cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position after this page (ADR-042): pass it back as after= for the next page. Returned beside next_after_seq for one release."}}},@@@ -5232,6 +5256,12 @@},"event": {"$ref": "event-envelope.v1.json"++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}},@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.AI API",-- "version": "0.80.0",-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Codes API",-- "version": "0.80.0",-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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"@@@ -1162,7 +1162,7 @@},"events.publish-result.v1": {"title": "EventsPublishResult",-- "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).",++ "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate, cursor? } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).","anyOf": [{"type": "object",@@@ -1183,6 +1183,12 @@"duplicate": {"type": "boolean","description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}},@@@ -1215,6 +1221,12 @@"duplicate": {"type": "boolean","description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}}@@@ -1254,7 +1266,7 @@},"events.read-result.v1": {"title": "EventsReadResult",-- "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, event }], next_after_seq, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.",++ "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, cursor?, event }], next_after_seq, next_cursor?, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the cursor once Events sends one, else the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.","anyOf": [{"type": "object",@@@ -1280,6 +1292,12 @@},"event": {"$ref": "#/components/schemas/events.event-envelope.v1"++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}}@@@ -1306,6 +1324,12 @@"type": "integer"}}++ },++ "next_cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position after this page (ADR-042): pass it back as after= for the next page. Returned beside next_after_seq for one release."}}},@@@ -1322,6 +1346,12 @@},"event": {"$ref": "#/components/schemas/events.event-envelope.v1"++ },++ "cursor": {++ "type": "string",++ "minLength": 1,++ "maxLength": 200,++ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."}}},@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Games API",-- "version": "0.80.0",-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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": "OpenRe.Stream API",-- "version": "0.80.0",-- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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"@@@ -7492,7 +7492,7 @@ export type EventsDeliveryAdminResult =/** [email protected] (owner: events) *//**-- * events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).++ * events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate, cursor? } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).*/export type EventsPublishResult =| {@@@ -7502,6 +7502,10 @@ export type EventsPublishResult =* true: this event_id was stored before; the stored seq is returned and nothing is stored twice.*/duplicate: boolean;++ /**++ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.++ */++ cursor?: string;}| {/**@@@ -7516,6 +7520,10 @@ export type EventsPublishResult =* true: this event_id was stored before; the stored seq is returned and nothing is stored twice.*/duplicate: boolean;++ /**++ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.++ */++ cursor?: string;},...{event_id: string;@@@ -7524,6 +7532,10 @@ export type EventsPublishResult =* true: this event_id was stored before; the stored seq is returned and nothing is stored twice.*/duplicate: boolean;++ /**++ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.++ */++ cursor?: string;}[]];};@@@ -7547,7 +7559,7 @@ export type EventsReadRequest =/** [email protected] (owner: events) *//**-- * events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, event }], next_after_seq, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.++ * events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, cursor?, event }], next_after_seq, next_cursor?, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the cursor once Events sends one, else the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.*/export type EventsReadResult =| {@@@ -7557,6 +7569,10 @@ export type EventsReadResult =events: {seq: number;event: EventEnvelope;++ /**++ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.++ */++ cursor?: string;}[];next_after_seq: number;latest_seq: number;@@@ -7564,10 +7580,18 @@ export type EventsReadResult =from_seq: number;to_seq: number;};++ /**++ * Opaque position after this page (ADR-042): pass it back as after= for the next page. Returned beside next_after_seq for one release.++ */++ next_cursor?: string;}| {seq: number;event: EventEnvelope;++ /**++ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.++ */++ cursor?: string;}| {consumer: string;@@@ -1,6 +1,6 @@{"name": "openvibe-contracts",-- "version": "0.80.0",++ "version": "0.81.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,15 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
@@ -4,6 +4,15 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
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.81.0 — 2026-09-29
+
+**Opaque cursors beside the global seq** (plan T7, ADR-042, additive).
+- `events.publish-result@1` gains an optional `cursor` per stored event; `events.read-result@1` gains `cursor` per
+ event, `next_cursor` per page and `cursor` on a single event. A cursor is opaque (a position plus a retention epoch):
+ hand it back as `after=` or `Last-Event-ID`, never parse it. Events returns both `seq` and `cursor` for one release,
+ then `seq`, `next_after_seq`, `latest_seq` and the global-order promise go.
+- ADR-042 (the events fabric) is recorded in docs/adr.
+
## 0.80.0 — 2026-09-29
## 0.80.0 — 2026-09-29
**`chat.moderation.read`: how Live reads the chat tables Chat owns** (plan T3, the six staged tables).
**`chat.moderation.read`: how Live reads the chat tables Chat owns** (plan T3, the six staged tables).
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/events/publish-result.v1.json",
"$id": "https://openvibe.network/contracts/events/publish-result.v1.json",
"title": "EventsPublishResult",
"title": "EventsPublishResult",
- "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).",
+ "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate, cursor? } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -23,6 +23,12 @@
@@ -23,6 +23,12 @@
"duplicate": {
"duplicate": {
"type": "boolean",
"type": "boolean",
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
},
},
@@ -55,6 +61,12 @@
@@ -55,6 +61,12 @@
"duplicate": {
"duplicate": {
"type": "boolean",
"type": "boolean",
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
}
}
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/events/read-result.v1.json",
"$id": "https://openvibe.network/contracts/events/read-result.v1.json",
"title": "EventsReadResult",
"title": "EventsReadResult",
- "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, event }], next_after_seq, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.",
+ "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, cursor?, event }], next_after_seq, next_cursor?, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the cursor once Events sends one, else the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -28,6 +28,12 @@
@@ -28,6 +28,12 @@
},
},
"event": {
"event": {
"$ref": "event-envelope.v1.json"
"$ref": "event-envelope.v1.json"
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
}
}
@@ -54,6 +60,12 @@
@@ -54,6 +60,12 @@
"type": "integer"
"type": "integer"
}
}
}
}
+ },
+ "next_cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position after this page (ADR-042): pass it back as after= for the next page. Returned beside next_after_seq for one release."
}
}
}
}
},
},
@@ -70,6 +82,12 @@
@@ -70,6 +82,12 @@
},
},
"event": {
"event": {
"$ref": "event-envelope.v1.json"
"$ref": "event-envelope.v1.json"
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
},
},
new file mode 100644
new file mode 100644
@@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
+{
+ "event_id": "evt_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "seq": 88213,
+ "duplicate": false,
+ "cursor": ""
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
+{
+ "event_id": "evt_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "seq": 88213,
+ "duplicate": false,
+ "cursor": "c1.e0.MTIzNDU"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
+{
+ "events": [
+ {
+ "seq": 88213,
+ "event": {
+ "event_id": "evt_01JAB2C3D4E5F6G7H8J9K0MNPR",
+ "event_type": "app.p01jab2c3d4e5f6g7h8j9k0mnpq.order.created",
+ "version": 1,
+ "source": "app-01jab2c3d4e5f6g7h8j9k0mnps",
+ "actor": {
+ "type": "app",
+ "id": "app_01JAB2C3D4E5F6G7H8J9K0MNPS"
+ },
+ "timestamp": "2026-09-23T12:00:00Z",
+ "visibility": "internal",
+ "subject": {
+ "type": "order",
+ "id": "42"
+ },
+ "payload": {
+ "total": 3
+ }
+ },
+ "cursor": "c1.e0.1"
+ }
+ ],
+ "next_after_seq": 88240,
+ "latest_seq": 88240,
+ "next_cursor": "c1.e0.next"
+}
@@ -5058,7 +5058,7 @@
@@ -5058,7 +5058,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/events/publish-result.v1.json",
"$id": "https://openvibe.network/contracts/events/publish-result.v1.json",
"title": "EventsPublishResult",
"title": "EventsPublishResult",
- "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).",
+ "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate, cursor? } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -5079,6 +5079,12 @@
@@ -5079,6 +5079,12 @@
"duplicate": {
"duplicate": {
"type": "boolean",
"type": "boolean",
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
},
},
@@ -5111,6 +5117,12 @@
@@ -5111,6 +5117,12 @@
"duplicate": {
"duplicate": {
"type": "boolean",
"type": "boolean",
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
}
}
@@ -5164,7 +5176,7 @@
@@ -5164,7 +5176,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/events/read-result.v1.json",
"$id": "https://openvibe.network/contracts/events/read-result.v1.json",
"title": "EventsReadResult",
"title": "EventsReadResult",
- "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, event }], next_after_seq, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.",
+ "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, cursor?, event }], next_after_seq, next_cursor?, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the cursor once Events sends one, else the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -5190,6 +5202,12 @@
@@ -5190,6 +5202,12 @@
},
},
"event": {
"event": {
"$ref": "event-envelope.v1.json"
"$ref": "event-envelope.v1.json"
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
}
}
@@ -5216,6 +5234,12 @@
@@ -5216,6 +5234,12 @@
"type": "integer"
"type": "integer"
}
}
}
}
+ },
+ "next_cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position after this page (ADR-042): pass it back as after= for the next page. Returned beside next_after_seq for one release."
}
}
}
}
},
},
@@ -5232,6 +5256,12 @@
@@ -5232,6 +5256,12 @@
},
},
"event": {
"event": {
"$ref": "event-envelope.v1.json"
"$ref": "event-envelope.v1.json"
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
},
},
@@ -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.80.0",
- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Codes API",
"title": "OpenVibe.Codes API",
- "version": "0.80.0",
- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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"
@@ -1162,7 +1162,7 @@
@@ -1162,7 +1162,7 @@
},
},
"events.publish-result.v1": {
"events.publish-result.v1": {
"title": "EventsPublishResult",
"title": "EventsPublishResult",
- "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).",
+ "description": "events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate, cursor? } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -1183,6 +1183,12 @@
@@ -1183,6 +1183,12 @@
"duplicate": {
"duplicate": {
"type": "boolean",
"type": "boolean",
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
},
},
@@ -1215,6 +1221,12 @@
@@ -1215,6 +1221,12 @@
"duplicate": {
"duplicate": {
"type": "boolean",
"type": "boolean",
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
"description": "true: this event_id was stored before; the stored seq is returned and nothing is stored twice."
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
}
}
@@ -1254,7 +1266,7 @@
@@ -1254,7 +1266,7 @@
},
},
"events.read-result.v1": {
"events.read-result.v1": {
"title": "EventsReadResult",
"title": "EventsReadResult",
- "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, event }], next_after_seq, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.",
+ "description": "events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, cursor?, event }], next_after_seq, next_cursor?, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the cursor once Events sends one, else the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -1280,6 +1292,12 @@
@@ -1280,6 +1292,12 @@
},
},
"event": {
"event": {
"$ref": "#/components/schemas/events.event-envelope.v1"
"$ref": "#/components/schemas/events.event-envelope.v1"
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
}
}
@@ -1306,6 +1324,12 @@
@@ -1306,6 +1324,12 @@
"type": "integer"
"type": "integer"
}
}
}
}
+ },
+ "next_cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position after this page (ADR-042): pass it back as after= for the next page. Returned beside next_after_seq for one release."
}
}
}
}
},
},
@@ -1322,6 +1346,12 @@
@@ -1322,6 +1346,12 @@
},
},
"event": {
"event": {
"$ref": "#/components/schemas/events.event-envelope.v1"
"$ref": "#/components/schemas/events.event-envelope.v1"
+ },
+ "cursor": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 200,
+ "description": "Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes."
}
}
}
}
},
},
@@ -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.80.0",
- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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": "OpenRe.Stream API",
"title": "OpenRe.Stream API",
- "version": "0.80.0",
- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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.80.0",
- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.80.0): each operation lists the capabilities it performs; a token for 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.81.0",
+ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.81.0): each operation lists the capabilities it performs; a token for 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"
@@ -7492,7 +7492,7 @@ export type EventsDeliveryAdminResult =
@@ -7492,7 +7492,7 @@ export type EventsDeliveryAdminResult =
/** [email protected] (owner: events) */
/** [email protected] (owner: events) */
/**
/**
- * events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).
+ * events.publish-result@1: the answer of POST /api/v1/events on OpenVibe.Events (events.event.publish for services, events.app.publish for developer apps). One envelope → { event_id, seq, duplicate, cursor? } (201 when stored, 200 when every event was a repeat); a batch { events: [...] } (at most 100, atomic) → { results } in the same order. Refusals are problem+json: 422 events.invalid_envelope / events.invalid_redaction, 403 events.source_mismatch / events.type_not_allowed / events.actor_mismatch, 413 events.payload_too_large / events.batch_too_large, 429 events.quota_exceeded (apps).
*/
*/
export type EventsPublishResult =
export type EventsPublishResult =
| {
| {
@@ -7502,6 +7502,10 @@ export type EventsPublishResult =
@@ -7502,6 +7502,10 @@ export type EventsPublishResult =
* true: this event_id was stored before; the stored seq is returned and nothing is stored twice.
* true: this event_id was stored before; the stored seq is returned and nothing is stored twice.
*/
*/
duplicate: boolean;
duplicate: boolean;
+ /**
+ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.
+ */
+ cursor?: string;
}
}
| {
| {
/**
/**
@@ -7516,6 +7520,10 @@ export type EventsPublishResult =
@@ -7516,6 +7520,10 @@ export type EventsPublishResult =
* true: this event_id was stored before; the stored seq is returned and nothing is stored twice.
* true: this event_id was stored before; the stored seq is returned and nothing is stored twice.
*/
*/
duplicate: boolean;
duplicate: boolean;
+ /**
+ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.
+ */
+ cursor?: string;
},
},
...{
...{
event_id: string;
event_id: string;
@@ -7524,6 +7532,10 @@ export type EventsPublishResult =
@@ -7524,6 +7532,10 @@ export type EventsPublishResult =
* true: this event_id was stored before; the stored seq is returned and nothing is stored twice.
* true: this event_id was stored before; the stored seq is returned and nothing is stored twice.
*/
*/
duplicate: boolean;
duplicate: boolean;
+ /**
+ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.
+ */
+ cursor?: string;
}[]
}[]
];
];
};
};
@@ -7547,7 +7559,7 @@ export type EventsReadRequest =
@@ -7547,7 +7559,7 @@ export type EventsReadRequest =
/** [email protected] (owner: events) */
/** [email protected] (owner: events) */
/**
/**
- * events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, event }], next_after_seq, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.
+ * events.read-result@1: answers of the pull API on OpenVibe.Events. GET /api/v1/events → { events: [{ seq, cursor?, event }], next_after_seq, next_cursor?, latest_seq, gap? } (keep next_after_seq as the cursor: it moves past events that did not match; gap { from_seq, to_seq } says events after after_seq were already pruned by retention); GET /api/v1/events/:event_id → { seq, event }; GET|PUT /api/v1/checkpoints → { consumer, topic, cursor, updated_at } (cursor 0 and updated_at null when none is stored). GET /realtime/stream?topics= (events.event.read) is a Server-Sent Events feed whose messages carry the same { seq, event } (id: the cursor once Events sends one, else the seq; a gap message when the cursor is older than retention). An app sees only its project's events in its token's environment plus public first-party events.
*/
*/
export type EventsReadResult =
export type EventsReadResult =
| {
| {
@@ -7557,6 +7569,10 @@ export type EventsReadResult =
@@ -7557,6 +7569,10 @@ export type EventsReadResult =
events: {
events: {
seq: number;
seq: number;
event: EventEnvelope;
event: EventEnvelope;
+ /**
+ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.
+ */
+ cursor?: string;
}[];
}[];
next_after_seq: number;
next_after_seq: number;
latest_seq: number;
latest_seq: number;
@@ -7564,10 +7580,18 @@ export type EventsReadResult =
@@ -7564,10 +7580,18 @@ export type EventsReadResult =
from_seq: number;
from_seq: number;
to_seq: number;
to_seq: number;
};
};
+ /**
+ * Opaque position after this page (ADR-042): pass it back as after= for the next page. Returned beside next_after_seq for one release.
+ */
+ next_cursor?: string;
}
}
| {
| {
seq: number;
seq: number;
event: EventEnvelope;
event: EventEnvelope;
+ /**
+ * Opaque position (ADR-042): hand it back as after= to read on from here, or as Last-Event-ID; never parse it. Returned beside seq for one release; seq then goes.
+ */
+ cursor?: string;
}
}
| {
| {
consumer: string;
consumer: string;
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.80.0",
+ "version": "0.81.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",