EventsHook events.hook@1

Generated at from openvibe-contracts v0.419.0 and openvibe-sdk v0.161.0.

Version
1.0.0
Owner
events
Visibility
public
Status
active
Compatibility
backward
Schema
https://openvibe.network/contracts/events/hook.v1.json

events.hook@1: one durable webhook subscription managed through OpenVibe.Website Connect, delivered by OpenVibe.Events. The hook names its share, the public ingress path, the event topics it accepts, filters/transform, the retry window and the signature version. The signing secret is shown once when the hook is created or its secret is rotated; secret_set says one exists, and no field of this document ever carries the value.

Fields

FieldTypeRequiredDescriptionConstraints
idstringyes
  • pattern ^hok_[0-9A-HJKMNP-TV-Z]{26}$
owneridentity.subject-refyes
project_idstring | null
  • pattern ^prj_[0-9A-HJKMNP-TV-Z]{26}$
share_idstringyesThe share whose tunnel receives deliveries; delivery never goes to an arbitrary host.
  • pattern ^shr_[0-9A-HJKMNP-TV-Z]{26}$
namestringyes
  • minLength 1
  • maxLength 80
endpointstringyesThe public ingress, https://hooks.openvibe.website/h/<id>; Connect also records the on-share path https://<share host>/__ov/hook/<id>.
  • pattern ^https://
  • format uri
topicsarray of stringyesEvent types this hook accepts, e.g. github.push.received or stripe.invoice.paid; Event's topic patterns may be used by the delivery filter.
  • minItems 1
  • maxItems 50
  • unique items
  • items: pattern ^[a-z][a-z0-9_]*(\.[a-z0-9_]+){2,}$
filtersarray of object
  • maxItems 20
  • items: no other fields
filters[].pathstringyesA JSONPath into the event payload.
  • minLength 1
  • maxLength 200
filters[].equalsone of
transformobject | null
retryobjectyes
  • no other fields
retry.window_secondsintegeryesHow long Events keeps retrying while the share is offline; seven days is the hook default.
  • minimum 60
  • maximum 604800
retry.max_attemptsintegeryes
  • minimum 1
  • maximum 100
signatureobjectyes
  • no other fields
signature.versionconstyes
  • = "v2"
signature.tolerance_secondsintegeryesHow far a signed timestamp may drift before the Link refuses it; 300 is the default.
  • minimum 1
  • maximum 3600
max_payload_bytesinteger
  • minimum 1
  • maximum 1048576
  • default 1048576
statusenumyes
  • one of "active", "paused", "revoked"
secret_setbooleanyesTrue once a signing secret exists. The secret itself is returned only in the create/rotate answer and is never stored in this contract, a delivery record or an audit entry.
secret_rotated_atstring | null
  • format date-time
last_delivery_atstring | null
  • format date-time
dead_atstring | nullWhen the hook stopped receiving deliveries after its retry window; null while it is live.
  • format date-time
created_atstringyes
  • format date-time
updated_atstringyes
  • format date-time
hrefstring
  • pattern ^https://
  • format uri

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: github
{
  "id": "hok_01J8Z3Q4R5S6T7V8W9X0Y1Z2A9",
  "owner": {
    "type": "user",
    "id": "usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A6"
  },
  "project_id": null,
  "share_id": "shr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3",
  "name": "GitHub pushes",
  "endpoint": "https://hooks.openvibe.website/h/hok_01J8Z3Q4R5S6T7V8W9X0Y1Z2A9",
  "topics": [
    "github.push.received",
    "github.pull_request.received"
  ],
  "filters": [
    {
      "path": "$.repository.full_name",
      "equals": "OpenVibers/OpenVibe.Contracts"
    }
  ],
  "transform": null,
  "retry": {
    "window_seconds": 604800,
    "max_attempts": 30
  },
  "signature": {
    "version": "v2",
    "tolerance_seconds": 300
  },
  "max_payload_bytes": 1048576,
  "status": "active",
  "secret_set": true,
  "secret_rotated_at": null,
  "last_delivery_at": "2026-10-29T09:00:00.000Z",
  "dead_at": null,
  "created_at": "2026-10-29T08:00:00.000Z",
  "updated_at": "2026-10-29T09:00:00.000Z"
}
Rejected: http-endpoint
{
  "id": "hok_01J8Z3Q4R5S6T7V8W9X0Y1Z2A9",
  "owner": {
    "type": "user",
    "id": "usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A6"
  },
  "share_id": "shr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3",
  "name": "Insecure hook",
  "endpoint": "http://hooks.openvibe.website/h/hok_01J8Z3Q4R5S6T7V8W9X0Y1Z2A9",
  "topics": [
    "github.push.received"
  ],
  "retry": {
    "window_seconds": 604800,
    "max_attempts": 30
  },
  "signature": {
    "version": "v2",
    "tolerance_seconds": 300
  },
  "status": "active",
  "secret_set": true,
  "created_at": "2026-10-29T08:00:00.000Z",
  "updated_at": "2026-10-29T09:00:00.000Z"
}
Rejected: secret-field
{
  "id": "hok_01J8Z3Q4R5S6T7V8W9X0Y1Z2A9",
  "owner": {
    "type": "user",
    "id": "usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A6"
  },
  "share_id": "shr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3",
  "name": "GitHub pushes",
  "endpoint": "https://hooks.openvibe.website/h/hok_01J8Z3Q4R5S6T7V8W9X0Y1Z2A9",
  "topics": [
    "github.push.received"
  ],
  "retry": {
    "window_seconds": 604800,
    "max_attempts": 30
  },
  "signature": {
    "version": "v2",
    "tolerance_seconds": 300
  },
  "status": "active",
  "secret_set": true,
  "secret": "whsec_this-value-never-belongs-in-a-contract",
  "created_at": "2026-10-29T08:00:00.000Z",
  "updated_at": "2026-10-29T09:00:00.000Z"
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('events.hook@1', value);   // { valid, errors: [{ path, message }] }