NetworkRealtimeTicketResult network.realtime-ticket-result@1
Generated at from
openvibe-contracts v0.76.0 and
openvibe-sdk v0.20.1.
- Version
- 1.0.0
- Owner
- network
- Visibility
- first-party
- Status
- active
- Compatibility
- backward
- Decision
- ADR-005
- Schema
https://openvibe.network/contracts/network/realtime-ticket-result.v1.json
What POST /api/v1/realtime/ticket answers (OpenVibe.Network; ADR-005 amendment 2): a realtime ticket (identity.realtime-ticket-claims@1) for the signed-in person, and where to use it. The caller is the person's own session (Bearer Network JWT, or the ov_token cookie on openvibe.network); guests are refused (403 realtime.guest), and 503 realtime.disabled means the operator turned browser realtime off (REALTIME_TICKETS=off): the client stays on polling. The client opens `${stream_url}?topics=${topics}&ticket=${ticket}` (plus last_event_id when it resumes) at once, and asks for a fresh ticket for every reconnect: a ticket opens one stream.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
ticket | string | yes | The signed ticket (a compact JWS). Never logged, never stored. |
|
expires_at | string | yes |
| |
expires_in | integer | yes | Seconds until the ticket expires (120). |
|
stream_url | string | yes | Events' realtime stream (https://events.openvibe.network/realtime/stream). |
|
topics | array of string | yes | The topic patterns the notification badge subscribes to: ["network.notification.*"]. |
|
subject | string | yes | Whose ticket it is; a client ignores any event whose subject is someone else. |
|
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: badge
{
"ticket": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXAiOiJyZWFsdGltZSJ9.c2lnbmF0dXJl",
"expires_at": "2026-09-26T18:05:08.000Z",
"expires_in": 120,
"stream_url": "https://events.openvibe.network/realtime/stream",
"topics": [
"network.notification.*"
],
"subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Rejected: long-lived
{
"ticket": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXAiOiJyZWFsdGltZSJ9.c2lnbmF0dXJl",
"expires_at": "2026-09-27T18:03:08.000Z",
"expires_in": 86400,
"stream_url": "https://events.openvibe.network/realtime/stream",
"topics": [
"network.notification.*"
],
"subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Rejected: not-a-jws
{
"ticket": "not a token",
"expires_at": "2026-09-26T18:05:08.000Z",
"expires_in": 120,
"stream_url": "https://events.openvibe.network/realtime/stream",
"topics": [
"network.notification.*"
],
"subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Rejected: stream-url-with-query
{
"ticket": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXAiOiJyZWFsdGltZSJ9.c2lnbmF0dXJl",
"expires_at": "2026-09-26T18:05:08.000Z",
"expires_in": 120,
"stream_url": "https://events.openvibe.network/realtime/stream?ticket=x",
"topics": [
"network.notification.*"
],
"subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Rejected: user-colon-topic
{
"ticket": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXAiOiJyZWFsdGltZSJ9.c2lnbmF0dXJl",
"expires_at": "2026-09-26T18:05:08.000Z",
"expires_in": 120,
"stream_url": "https://events.openvibe.network/realtime/stream",
"topics": [
"user:usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
],
"subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('network.realtime-ticket-result@1', value); // { valid, errors: [{ path, message }] }