Webhook testing

Test with a sandbox endpoint before creating a production subscription. The simulator builds the same envelope, signs the same raw bytes and creates a real delivery record, so your receiver exercises production verification and retry behaviour without running an entire product flow.

  1. Create a sandbox endpoint and copy its whsec_… secret into your receiver's secret store.
  2. Choose one event from each family your integration handles.
  3. Send a simulated delivery from the endpoint's Testing action.
  4. Confirm your receiver verifies X-Myaza-Signature-V2, persists id, and returns 2xx quickly.
  5. Inspect the endpoint delivery history and correlate it with deliveryId or X-Myaza-Delivery.
  6. Resend the delivery and confirm your business side effect happens only once.
  7. Temporarily return a non-2xx response and confirm a retry is scheduled.
  8. Rotate the secret and confirm both V2 v1 signatures are accepted during the grace period.
  9. If migrating from an alias, subscribe to the canonical name and alias together and confirm the shared event id prevents duplicate work.

Catalogue-driven fixtures

GET /api/v1/webhooks/catalogue returns every supported event and its generated sample. Generate typed fixtures from this response rather than copying an invented schema into a test suite.

shell
curl -H "Authorization: Bearer sk_test_…" \
  https://trust.myaza.app/api/v1/webhooks/catalogue

Samples show realistic public field shapes, but sample identifiers are not reusable API resources. Runtime events can contain additional optional fields documented on each event-family page.

Idempotency assertion

Use the envelope id, not deliveryId, as the unique business key:

sql
insert into received_myaza_events (event_id, event_type, payload)
values (:id, :type, :payload)
on conflict (event_id) do nothing;

A manual resend creates another delivery record but preserves the logical event ID. A compatibility alias also shares the canonical event's ID.

Ordering assertion

Do not write a test that assumes a cross-type sequence such as risk.signal.created always arriving before alert.created. Delay or reverse two accepted events and confirm your handler either applies them by resource version/current API state or processes them independently.

Production readiness checklist

  • HTTPS endpoint uses a valid public certificate and does not redirect.
  • Raw-body signature verification and replay rejection are covered by tests.
  • Event IDs have a durable unique constraint.
  • Slow processing runs outside the request.
  • Unknown event types are safely stored or ignored and still acknowledged.
  • Alerts exist for repeated delivery failures and dead-lettered deliveries.
  • Secrets are environment-scoped, stored outside source code and rotation-tested.