rostack_v1 / 2026-08-13 / draft

websocket-message.schema.json

Machine-readable JSON artifact.

json{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://spec.pmh.codes/apis/rostack_v1/releases/2026-08-13/schemas/websocket-message.schema.json",
  "title": "rostack_v1 WebSocket message",
  "oneOf": [
    {"$ref": "#/$defs/authenticate"},
    {"$ref": "#/$defs/authenticated"},
    {"$ref": "#/$defs/subscribe"},
    {"$ref": "#/$defs/subscribed"},
    {"$ref": "#/$defs/replayComplete"},
    {"$ref": "#/$defs/unsubscribe"},
    {"$ref": "#/$defs/event"},
    {"$ref": "#/$defs/compactEvent"},
    {"$ref": "#/$defs/error"},
    {"$ref": "#/$defs/goAway"},
    {"$ref": "#/$defs/ping"},
    {"$ref": "#/$defs/pong"}
  ],
  "$defs": {
    "authenticate": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "method", "token"],
      "properties": {
        "type": {"const": "authenticate"},
        "method": {"enum": ["oauth2", "shared_token"]},
        "token": {"type": "string", "minLength": 1}
      }
    },
    "authenticated": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "method", "protocol_version", "api_version", "principal_id"],
      "properties": {
        "type": {"const": "authenticated"},
        "method": {"enum": ["oauth2", "shared_token"]},
        "protocol_version": {"const": "rostack_v1"},
        "api_version": {"type": "string", "minLength": 1},
        "principal_id": {"type": "string", "minLength": 1},
        "reauthenticate_at": {"type": "string", "format": "date-time"}
      }
    },
    "subscribe": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "subscription_id", "resource"],
      "properties": {
        "type": {"const": "subscribe"},
        "subscription_id": {"type": "string", "minLength": 1},
        "resource": {"type": "string", "minLength": 1},
        "event_types": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string"}},
        "filter": {"$ref": "filter.schema.json"},
        "cursor": {"type": "string", "minLength": 1},
        "event_encoding": {"enum": ["json", "compact-json"], "default": "json"}
      }
    },
    "subscribed": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "subscription_id", "event_encoding", "replaying"],
      "properties": {
        "type": {"const": "subscribed"},
        "subscription_id": {"type": "string", "minLength": 1},
        "event_encoding": {"enum": ["json", "compact-json"]},
        "replaying": {"type": "boolean"}
      }
    },
    "replayComplete": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "subscription_id"],
      "properties": {
        "type": {"const": "replay_complete"},
        "subscription_id": {"type": "string", "minLength": 1}
      }
    },
    "unsubscribe": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "subscription_id"],
      "properties": {
        "type": {"const": "unsubscribe"},
        "subscription_id": {"type": "string", "minLength": 1}
      }
    },
    "event": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "subscription_id", "event_id", "cursor", "occurred_at", "event_type", "resource_id", "resource_version"],
      "properties": {
        "type": {"const": "event"},
        "subscription_id": {"type": "string", "minLength": 1},
        "event_id": {"type": "string", "minLength": 1},
        "cursor": {"type": "string", "minLength": 1},
        "occurred_at": {"type": "string", "format": "date-time"},
        "event_type": {"type": "string", "minLength": 1},
        "resource_id": {"type": "string", "minLength": 1},
        "resource_version": {"type": "string", "minLength": 1},
        "detail_url": {"type": "string", "format": "uri", "pattern": "^https://"},
        "data": true
      }
    },
    "compactEvent": {
      "type": "array",
      "minItems": 8,
      "maxItems": 10,
      "prefixItems": [
        {"const": "e"},
        {"type": "string", "minLength": 1},
        {"type": "string", "minLength": 1},
        {"type": "string", "minLength": 1},
        {"type": "integer", "minimum": 0},
        {"type": "string", "minLength": 1},
        {"type": "string", "minLength": 1},
        {"type": "string", "minLength": 1},
        {"type": ["string", "null"], "format": "uri", "pattern": "^https://"},
        true
      ]
    },
    "error": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "code", "message", "retryable"],
      "properties": {
        "type": {"const": "error"},
        "subscription_id": {"type": "string"},
        "code": {
          "enum": [
            "invalid_message",
            "authentication_failed",
            "reauthentication_identity_mismatch",
            "permission_denied",
            "permission_revoked",
            "resource_not_found",
            "unsupported_event_type",
            "unsupported_filter",
            "unsupported_encoding",
            "subscription_id_conflict",
            "cursor_scope_mismatch",
            "cursor_unavailable",
            "rate_limited",
            "internal_error",
            "service_unavailable"
          ]
        },
        "message": {"type": "string", "minLength": 1},
        "retryable": {"type": "boolean"},
        "retry_after_ms": {"type": "integer", "minimum": 0}
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "code": {"enum": ["authentication_failed", "rate_limited", "internal_error", "service_unavailable"]}
            },
            "required": ["code"]
          },
          "then": {"properties": {"retryable": {"const": true}}},
          "else": {"properties": {"retryable": {"const": false}}}
        },
        {
          "if": {
            "properties": {"code": {"enum": ["rate_limited", "service_unavailable"]}},
            "required": ["code"]
          },
          "then": {
            "properties": {"retry_after_ms": {"type": "integer", "minimum": 0}},
            "required": ["retry_after_ms"]
          },
          "else": {"properties": {"retry_after_ms": false}}
        },
        {
          "if": {
            "properties": {
              "code": {
                "enum": [
                  "permission_revoked",
                  "resource_not_found",
                  "unsupported_event_type",
                  "unsupported_filter",
                  "unsupported_encoding",
                  "subscription_id_conflict",
                  "cursor_scope_mismatch",
                  "cursor_unavailable"
                ]
              }
            },
            "required": ["code"]
          },
          "then": {
            "properties": {"subscription_id": {"type": "string", "minLength": 1}},
            "required": ["subscription_id"]
          }
        }
      ]
    },
    "goAway": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "reason", "reconnect_after_ms", "drain_timeout_ms"],
      "properties": {
        "type": {"const": "go_away"},
        "reason": {"type": "string", "minLength": 1},
        "reconnect_after_ms": {"type": "integer", "minimum": 0},
        "drain_timeout_ms": {"type": "integer", "minimum": 0},
        "gateway_url": {"type": "string", "format": "uri", "pattern": "^wss://"}
      }
    },
    "ping": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "id"],
      "properties": {"type": {"const": "ping"}, "id": {"type": "string", "minLength": 1}}
    },
    "pong": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "id"],
      "properties": {"type": {"const": "pong"}, "id": {"type": "string", "minLength": 1}}
    }
  }
}