Reshot

Developer reference

Product Journey Webhooks

Deliver signed, idempotent Product Journey and Publication events through verified webhook adapters while preserving retries, receipts, and privacy boundaries.

Product Journey Webhooks deliver authenticated, idempotent events and Publication consequences to configured external endpoints. A webhook is a delivery adapter, not a source of automatic Product Journey truth.

Current event boundary

The developer authoring SDK emits a journey.publication.created event after an approved exact Journey revision is delivered and its Publication is persisted:

{
  "type": "journey.publication.created",
  "id": "event:publication-invite-v8",
  "subject": {
    "journeyId": "journey-invite-member",
    "publicationId": "publication-invite-v8"
  },
  "occurredAt": "2026-08-24T00:00:00.000Z"
}

Replayed publication returns the same logical event identity rather than inventing another Publication.

Destination adapter contract

The generic webhook adapter declares:

  • webhook-signature authentication;
  • endpoint/subscription target identity;
  • idempotent upsert/delivery behavior;
  • immutable-object version behavior;
  • rate-limit and retry policy;
  • authenticated canonical receipt;
  • compensating-update rollback;
  • disconnect-only deletion;
  • private staging before visibility.

Reference capability is not the same as configured production delivery. Publish provider-specific integration claims only after the real adapter path and receipt work.

Delivery input

A delivery binds the Publication, exact Publication Version, destination target, authenticated principal and scopes, idempotency key, request time, and content hash. The adapter rejects:

  • a version belonging to another Publication;
  • a target that differs from the configured destination;
  • deleted destinations;
  • unavailable source;
  • unapproved policy outcomes;
  • unsupported status;
  • invalid authentication or timestamps.

Signatures

Sign the exact serialized payload with a versioned algorithm and key reference. Include event ID, time, type, subject, and content identity inside the signed bytes. Consumers verify before acting and use the event ID for idempotency.

Do not treat TLS alone as producer authentication. Rotate secrets with an overlap window and identify which key signed each delivery.

Retries

Retry transient network, timeout, and eligible provider responses within declared rate limits. Permanent authentication, target, or payload rejection becomes terminal. Preserve every attempt in the receipt.

The same idempotency key with different input is an error. A successful terminal replay returns the prior receipt without a duplicate external consequence.

Receipts

The canonical receipt identifies adapter, Publication, version, destination, target, attempts, status, authenticated state, and visible version reference where applicable. A 2xx response is provider acknowledgement; verify the intended downstream consequence when the receiver supports a read path.

Inbound Signals

Inbound generic webhooks for experience Signals require authentication and bounded evidence. Preserve producer reference, external identity, privacy class, consent basis, retention, mapping hints, confidence, and human-confirmation state.

An inbound event cannot invent Journey identity. Unknown mapping remains a Signal candidate until deterministic or human binding.

Subscription lifecycle

Create subscriptions with an authorized endpoint, event allowlist, secret/key reference, active state, and owner. Verification challenges must not expose the long-lived signing secret. Pause or disconnect delivery when endpoint ownership or authentication becomes invalid.

Deletion is disconnect-only for the generic webhook reference: it stops future delivery but cannot remove copies already accepted by the consumer. Preserve that limitation in Publication and privacy workflows.

Event versioning

Version payload contracts independently from event type evolution. Add optional fields compatibly or introduce a new schema version. Keep consumers able to reject unsupported versions explicitly. Never repurpose an existing field with different meaning.

Privacy

Send the minimum payload. Prefer stable IDs and public/sanitized references over private Run content. Never include tokens, storage state, customer screenshots, or raw sensitive evidence unless an explicitly authorized private contract requires it.

Log hashes and bounded metadata rather than secrets or full payloads. Apply workspace isolation and deletion policy.

Consumer procedure

  1. read raw request bytes;
  2. identify signature version/key;
  3. verify the signature in constant-time-capable cryptographic code;
  4. reject stale timestamps outside policy;
  5. claim the event ID atomically;
  6. validate schema and tenant/subject scope;
  7. perform the idempotent consequence;
  8. store the result/receipt;
  9. return a bounded response;
  10. replay safely on redelivery.

Failure handling

Quarantine invalid signatures, schema mismatch, tenant mismatch, expired timestamp, idempotency collision, and privacy-policy violations. Do not repeatedly retry permanent failures. Alert on queue age, terminal failure, and receipt mismatch.

Testing

Use a synthetic secret and fixture endpoint. Verify success, tampering, wrong key, stale time, duplicate delivery, same-key/different-input collision, transient retry, permanent rejection, rate-limit behavior, and tenant isolation. Never send production customer evidence to a public webhook tester.

Release consequence

Webhook delivery can become a Publication receipt or Signal source. It does not itself approve the Journey or release. The Release Book retains the exact outward result and unresolved failures.

Continue with Product Journey API, Cloudflare R2 integration, and Release Evidence for Product Journeys.

Start with one release-critical Journey.

Define the outcome, declare its state, run it, inspect the evidence, and record the Decision before expanding coverage.