API changelog
Append-only record of every change to the v1 API contract, newest first.
The v1 contract is append-only: fields may be added, existing fields and code values never change
meaning. Anything that would break a parser lands in a v2, not here. Newest changes come first.
New hosts for the API and capture URLs
The API and capture URLs moved to webhookvault.net. Paths, request and response shapes are unchanged; only the host differs.
- API base URL:
https://app.webhookvault.net. The OpenAPI document'sserversentry names it, and the document itself is served at/openapi/v1.json.webhookvault.devanswers every path with a 301 to the same path onapp.webhookvault.net. Point your client at the new host: most HTTP clients do not repeat a POST, PUT, PATCH or DELETE across a 301 (they switch to GET or stop), and many drop theAuthorizationheader when a redirect changes host. - Capture URLs: an endpoint's
urlis now onhttps://in.webhookvault.net, with the same path as before.in.webhookvault.devno longer answers, so a provider still sending to the old host needs the new URL from the endpoint.
Alert deliveries and parked-delivery alerts
eventKind=delivery.recoveredis a valid filter onGET /api/v1/alert-channels/deliveries. It lists the notices that close a parked-delivery incident, sent when a delivery to the action succeeds again.subjectIdon a parked-delivery alert and on its recovered notice now holds the action's id, where it held the request's id. The same value issubject_idin a webhook channel's payload. Parked-delivery alerts also coalesce: one per action per outage, with a running count, instead of one per request. See Alerts.eventKindlists every kind it accepts: the filter takes any kind a delivery can carry,action.notifyincluded, and the OpenAPI document now enumerates all eight. Any other value answers 400 (code: validation_failed).
Replay to one action, action signing, the single-URL fields
Two additions, and one read rule stated plainly because an integrator can see it change.
- Replay to one action:
POST /api/v1/endpoints/{endpointId}/requests/{requestId}/replayaccepts an optionalactionIdquery parameter, andPOST /api/v1/endpoints/{endpointId}/requests/bulk-replayan optionalactionIdin its body. With it, the request goes through that one action only and the endpoint's other actions send nothing. The action must belong to the endpoint (an action of any other endpoint answers 404, the same as one that never existed) and must be switched on (400,code: action_inactive). Without it, replay is unchanged: every action that is switched on. - Action signing:
POST /api/v1/endpoints/{id}/actionsandPUT /api/v1/endpoints/{id}/actions/{actionId}accept a write-onlysigningSecreton aforward: omitted leaves it, an empty string stops signing, a value sets or rotates it (at least 16 characters). It is never returned; the action reports only whether it is signed and since when. It replaces the endpoint's deprecatedforwardSigningSecret. - The deprecated single-URL fields read the first forward action by position: an endpoint's
forwardUrlandforwardSigningnow describe the endpoint's first action of kindforwardby position, whether or not it is switched on, and arenull(withsigned: false) when the endpoint has no forward action. They used to describe the first switched-on action of any kind, so an endpoint whose first active action was a notify readforwardUrl: "". The read now names the same row a write to these fields changes.forwardingEnabledstill reads true when any action is switched on. - Writes to those fields:
forwardingEnabled: truesent withoutforwardUrlto an endpoint that has no forward action is now refused (400) rather than accepted and ignored, because there is no forward to switch on.forwardingEnabled: falsein the same case still answers 200 and changes nothing: no forward means nothing forwards, which is the state it asks for.forwardSigningSecretsent on its own no longer re-checks the forward's URL, so rotating it never depends on the receiver's DNS. - Concurrent changes:
PATCH /api/v1/endpoints/{id}answers 409 (code: concurrent_change) when one of the endpoint's actions was removed by another request while the update was saving. Nothing is saved; read the endpoint again and retry. This used to surface as a 500. - Marked deprecated:
forwardUrl,forwardingEnabled,forwardSigningandforwardSigningSecreton an endpoint carrydeprecated: truein the OpenAPI document. They are still read and honoured as described above; new integrations should use the endpoint's actions (GET /api/v1/endpoints/{id}/actions).
Provider setup paths
Additive. No existing field changes meaning.
- setupPath: each provider returned by
GET /api/v1/providersnow carriessetupPath: where the webhook URL is entered in that provider's own console, or, for the few providers with no console field, the one step that registers it. It is null when no path is documented.
The Skipped delivery state
Additive: a new value in an existing enum.
Skippedjoins the deliverystatevalues on a request's latest delivery and on thestatefilter ofGET /api/v1/endpoints/{endpointId}/requests. It means every action on the endpoint carries a condition and none matched the request, so nothing was queued.NotAttemptednow means the endpoint had no action switched on when the request arrived.
Capture responses: what they may contain
A capture URL is public, so the response it returns to a sender is now limited to what a webhook acknowledgement needs. Writes that used to be accepted can now be refused.
responseContentTypemust be one media type from an allowlist:application/jsonor any+jsontype,application/problem+json,text/plain,text/csv,application/xml,text/xml,application/soap+xml,application/x-www-form-urlencodedorapplication/octet-stream. HTML, images and scripts are refused.responseStatusCodemay not be a 3xx: a capture response never redirects.responseHeadersmay not setContent-Type(it has its own field), cookies, redirects (Location,Refresh,Link), security policies, framing or transport headers.- A refused value answers 400 (
code: validation_failed) onPOST /api/v1/endpointsandPATCH /api/v1/endpoints/{id}, withdetailnaming what was refused. - Endpoints saved before the rule keep working: a content type outside the list is served as
text/plain, a stored 3xx is served as 200, and blocked headers are dropped. Every capture response also carriesX-Content-Type-Options: nosniffand a sandboxingContent-Security-Policy.
Signed forwards, computed values, two more signature schemes
Additive. No existing field changes meaning.
- Signed forwards: a destination can carry a signing secret, and every delivery to it then
leaves with a
wv-signatureheader the receiver can verify. Set it withforwardSigningSecretonPOST /api/v1/endpointsorPATCH /api/v1/endpoints/{id}(write-only, at least 16 characters; an empty string stops signing). The endpoint reportsforwardSigningwithsignedandsetAtand never the secret. See Deliveries. - compute: a new transformation op that writes a value worked out from the payload.
fnnames one function from a fixed table andargsis a list of paths, literals and nested calls. It is not an expression language: no operators, variables or control flow. See Transformations. - Rules that keep failing:
TransformationRuleViewgainsdisabledReason, set when WebhookVault switches a rule off after it faults on consecutive deliveries, and null otherwise. A new alert event,transformation.disabled, is available onGET /api/v1/alert-channels/event-kindsand can be subscribed to. - Verification: Discord (Ed25519) and Wise (RSA-SHA256) are now verified rather than reported
as unsupported, so their
verification.supportedflips totrue.signatureAlgorithmacceptsrsa-sha256,rsa-sha512anded25519for a manual scheme, wheresigningSecretthen holds a public key rather than a shared secret.
Watchdogs
Additive. A new tag, Watchdogs, and no change to any existing route.
- Watchdogs:
GET/POST/api/v1/watchdogs,GET/PUT/DELETE/api/v1/watchdogs/{id}, andPOST /api/v1/watchdogs/{id}/activeto pause or resume one without deleting it. A watchdog reports itsstate, whether it isactive, andpausedByPlanwhen it is kept but over the plan's limit and therefore not being evaluated. - Cadence:
GET /api/v1/watchdogs/suggest?endpointId=…proposes an interval and grace from what the endpoint has actually received.available: falsewith areasonwhen there is too little history to propose anything. - Labels:
GET /api/v1/watchdogs/labels?endpointId=…lists the event labels an endpoint has sent, with counts, for building a match that will fire. - See Watchdogs.
Alert channels
Additive. A new tag, Alert channels, and no change to any existing route.
- Channels:
GET/POST/api/v1/alert-channels,GET/PUT/DELETE/api/v1/alert-channels/{id}. A channel reportshealth(untested,verified,failing), whether a credential is set and when, and what it is subscribed to. Credentials are write-only:secretis accepted on write and returned by nothing. Omit it on update to keep the stored one. - Discovery:
GET /api/v1/alert-channels/kindslists the destinations this workspace can add, withcredentialLabelnaming the credential each one needs and any extra fields;GET /api/v1/alert-channels/eventslists the event kinds a channel can subscribe to. - Test:
POST /api/v1/alert-channels/{id}/testsends a real message and answers what the provider said. A rejected send is200withdelivered: falseand the provider's own words indetail; the request succeeded, the send did not. - History:
GET /api/v1/alert-channels/deliveriesreturns every send, newest first, filterable by channel, event kind and outcome.emailFallbackmarks an alert that went by email because a channel was failing. - Email needs no channel and cannot be created as one: it is on for every plan and is managed from workspace contacts. See Alerts.
The recycle bin
DELETE on a captured request changes meaning: it no longer removes the request.
- Deletes move requests to the workspace recycle bin, restorable for up to 7 days or until the
plan's retention window ends, whichever comes first. This applies
to
DELETE …/requests/{id},POST …/requests/bulk-deleteandDELETE …/requests. Their response shapes are unchanged; a deleted request still answers404everywhere and is gone from every list, search and replay. - Recycle bin (new tag):
GET /api/v1/recycle-binlists what is in the bin withpurgesAtper row, andPOST /api/v1/recycle-bin/restoreputs requests back by id and answersrestoredCountplusskippedAtCap(rows left in the bin because their endpoint is at the plan's stored-request limit). - Only the retention sweep or a purge applied by WebhookVault support removes a deleted request for good. See Recycle bin.
Transformation sets, versions, full delivery records
Additive; the singular transformation routes keep working.
- Transformations become an ordered set per destination:
GET/POST…/endpoints/{id}/transformations,GET/PUT/DELETE…/transformations/{ruleId},PUT …/transformations/order,POST …/transformations/preview-set. Every rule carriesposition,enabled,conditionandversion;PUTtakes{ rule, enabled }. New problem code onPOST:limit_reached(409). - Versions:
GET …/transformations/{ruleId}/versionsandPOST …/versions/{n}/restore(a restore is a new version; history is never rewritten). - The singular
…/endpoints/{id}/transformationroutes now address the first rule of the set; their view gainsruleIdandruleCount. - Deliveries (new tag):
GET …/endpoints/{id}/deliverieslists every attempt on the endpoint;GET …/deliveries/{attemptId}returns exactly what was sent (method, URL, headers, body) and exactly what came back (status, headers, body, content type), with truncation flags. Delivery attempts carryhasDetail. transformationVersionon an attempt is set only when exactly one rule was in force; with several,transformNotenames each rule and version.
Verification and transformations
Additive only; every existing field keeps its meaning.
- Requests carry
verification: { verdict, note }, the signature verdict computed at capture time (verified,failed,unsigned,unverifiable, ornullwhen nothing was checked). Averificationquery filter joinsmethod,stateandqon list and await (verification=noneselects unchecked requests). - Endpoints carry a read-only
verificationobject (scheme in force, whether a secret is set, handshake token flags, the manual scheme) and accept write-only inputs on create and update:signingSecret,handshakeToken,signatureHeader,signatureAlgorithm,signatureEncoding,signaturePrefix. The secret is never returned. - Providers carry
verification: { supported, scheme, secretLabel }(null when the provider does not sign) andhandshakeTokenNeeded. - Delivery attempts carry
transformed,transformationVersionandtransformNote. - Transformations (new tag):
GET /transformations/schema,POST /transformations/preview, andGET/PUT/DELETE …/endpoints/{id}/transformation. See Transformations. New problem code onPUT:no_destination(409).
v1 launch
The first public surface:
- Introspection:
GET /me: key, workspace, plan, limits. - Endpoints: list, create (including ephemeral endpoints via
ttlSeconds), get,PATCHpartial update, delete, andGET …/stats(storage, last traffic, retention, delivery backlog). - Requests: list with search-lite filters (
method,state,q,since,until,afterId), get, delete, clear, bulk delete. - Await:
GET …/requests/await: block until a matching webhook arrives (200) or time out clean (204). No polling. - Replay: single replay with inline outcome, full per-request attempt history, and bulk replay queued through the delivery pipeline (plan-gated).
- Contract: RFC 9457 problems with stable
codes everywhere; one pagination envelope; per-key rate limits with honestRetry-After429s.
The OpenAPI document this reference renders from is public:
/openapi/v1.json.