Create a webhook endpoint
post/v1/webhook-endpoints
Registers a URL to receive the selected events. The response includes the
endpoint's signing secret, shown once per create (and on an idempotent
replay of that create); no other read returns it (roll it to get a new
one). Verify deliveries with the X-Vojo-Signature header.
Idempotent replay: repeating this request with the same
Idempotency-Key within 24 hours returns the original 201 response,
including the original secret, with Idempotent-Replayed: true. The
replay returns that original secret even if it has since been rolled or
the endpoint deleted. The stored response keeps the secret encrypted at
rest, never in plaintext.
Subscribing to verification.score: the endpoint is automatically given
permissive filter settings: no band floor, no event minimums, backfill
off. The event then fires for every play in the endpoint's scope that
reaches its final score after the subscription is made, and never for
plays that were already final (past plays are never replayed).
attestConfigId in the event payload is the id of this auto-created
config. Score filters are not configurable through /v1 yet; they may
be added later as an additive change.
Access
- Authentication
- Secret key or OAuth access token.
- Scope
webhooks:write- User permission
developerAccess- Safe to retry
- Send an Idempotency-Key.
Headers
Vojo-OrganisationstringThe organisation this request acts on (org id). Required for
oauth2callers — a missing header returns 400organisation_header_required; an org the user cannot access (a membership or an access grant, and granted to this OAuth client) returns 403organisation_access_denied. Secret keys are bound to one org: the header may be omitted, and if sent it must match the key's org (else 403). Every query is scoped by the resolved org, never by an id in the body.Vojo-VersionstringOptional API version pin (a date). Overrides the version pinned on the secret key / organisation for this request. Echoed in the
Vojo-Versionresponse header. Within/v1only additive changes ship, so most callers can omit it.Idempotency-KeystringClient-generated unique key (UUID v4 recommended) making this create safe to retry. A replay within 24 hours returns the stored response (with
Idempotent-Replayed: true). Reusing a key with a different body returns 409idempotency_key_reused.
Request body
namestringRequiredurlstringRequiredenabled_eventsarray of stringRequired
Response 201
Created
dataobjectRequiredA webhook endpoint plus its signing secret, returned only on create and roll.
Show 9 fields
idstringRequirednamestringRequiredurlstringRequiredHTTPS only.
enabled_eventsarray of stringRequiredEvent types from the webhook catalogue (event reference). Unknown types return 422.
statusstringRequireddisabled= turned off by Vojo after repeated delivery failures; setactiveto resume.signedbooleanRequiredFalse only for legacy endpoints whose secret predates signing; roll the secret to start signing.
created_atstringRequiredupdated_atstring or nullRequiredsecretstringRequiredSigning secret. Shown only in this response.
metaobjectRequired
Response headers
Vojo-VersionstringThe API version (date) this response was rendered with — the request's
Vojo-Version, else the key/org pin.RateLimitstringIETF RateLimit header: remaining quota in the current window, e.g.
"default";r=97;t=42.RateLimit-PolicystringIETF RateLimit-Policy header, e.g.
"default";q=100;w=60. Portal OAuth clients get a higher tier.LocationstringURL of the created resource.
Idempotent-Replayedstringtruewhen this response is a stored replay of an earlier request with the sameIdempotency-Key.
Errors
Every error is application/problem+json. Branch on its code.
- 400
Malformed request: invalid JSON, a bad cursor, a missing
Vojo-Organisationfor an OAuth caller, or an unknownVojo-Version. - 401
Missing, invalid, expired or revoked credential.
- 403
The caller is authenticated but not allowed: missing scope (
insufficient_scope), missing Permissions flag (permission_denied), a client/installer persona on an operator endpoint (operator_access_required), or no access to the requested org (organisation_access_denied). - 404
The resource does not exist, or belongs to another organisation. Cross-org ids always 404, never 403.
- 422
Well-formed request that failed validation.
errors[]lists each failing field. - 429
Rate limit exceeded for this principal. Back off for
Retry-Afterseconds. - 500
Unexpected server failure.