Skip to main content
← All docs
UUsable
    usable/webhooks automation

    Build a secure and reliable webhook receiver

    Bergur Davidsen·Updated 2026-07-14

    |Open in||History

    A webhook receiver is an internet-facing data ingestion endpoint. Keep its synchronous work small: authenticate, validate, persist or enqueue, and acknowledge.

    Receiver flow

    HTTPS request → authenticate → validate envelope → deduplicate → persist/enqueue → acknowledge quickly → process asynchronously

    Do not perform slow external calls or destructive business logic before acknowledging.

    Authenticate first

    Validate the released authentication header or secret configured for the webhook before parsing sensitive content deeply.

    • Compare secrets safely.
    • Reject missing or invalid credentials.
    • Keep credentials in a secret manager.
    • Support deliberate rotation.
    • Never log authorization values.
    • Restrict accepted methods and content types.

    The x-usable-test-trigger header identifies tests but is not proof of authenticity.

    Validate input

    Enforce:

    • POST and JSON content type;
    • bounded body size;
    • recognized event type;
    • valid workspace/resource IDs;
    • envelope/data consistency;
    • parsable timestamp;
    • approved workspace allowlist;
    • safe string and array limits.

    Treat all payload fields as untrusted. Never interpolate titles, tags, or content into SQL, shell commands, file paths, or templates without safe handling.

    Acknowledge quickly

    Persist or enqueue the validated event, then return a 2xx response. Keep queue insertion durable enough that acknowledgment does not lose the event.

    Return non-2xx only when redelivery could help or the request must be rejected. Avoid detailed responses that disclose receiver internals.

    Make processing idempotent

    Webhook delivery can be duplicated. If an explicit event ID is unavailable, derive a conservative key from documented stable fields such as event type, workspace/resource identity, and occurrence time, while retaining logic that can safely upsert the latest canonical state.

    For side effects:

    • use database uniqueness constraints;
    • record completed operations;
    • make notification sends deduplicated;
    • make deletes/tombstones repeatable;
    • check current state before writing.

    Handle ordering

    Events can arrive out of order. Prefer the newest canonical resource state for update-driven synchronization. For deletion, use a tombstone and ensure a late update cannot silently resurrect stale data.

    When exact ordering is essential, serialize processing per fragment or workspace and compare version/timestamps where available.

    Retry responsibly

    Separate transient from permanent failures:

    • retry timeouts, temporary upstream failures, and queue outages with bounded exponential backoff and jitter;
    • do not retry invalid payloads or unauthorized requests unchanged;
    • cap attempts;
    • send terminal failures to a dead-letter or review queue;
    • provide replay tooling that remains idempotent.

    Do not assume Usable's sender retry policy; design the receiver to survive duplicates whether they come from sender retry, manual test, or operator replay.

    Protect sensitive data

    • Encrypt transport and approved storage.
    • Minimize retained payload fields.
    • Redact logs.
    • Apply workspace-specific retention.
    • Restrict queue and support access.
    • Do not forward private content to third parties without approval.
    • Delete data when the integration is retired.

    Observability

    Monitor request count, authentication failures, validation failures, acknowledgment latency, queue depth, processing success/failure, retry/dead-letter count, duplicate rate, and event age.

    Use correlation data where documented, but do not turn credentials or full payloads into labels.

    Rotation and incident response

    1. Generate a new dedicated receiver credential.
    2. Update the receiver to accept the transition safely.
    3. Update the webhook configuration.
    4. Trigger a test.
    5. Confirm successful authenticated delivery.
    6. Remove the old credential.
    7. Review recent failures and access logs.

    After exposure, rotate immediately and assess delivered workspace data. Deleting a configuration does not invalidate a secret copied elsewhere.

    Minimal pseudocode

    receive request
    require POST + application/json
    verify receiver credential
    parse bounded JSON
    validate event type and workspace
    if duplicate: acknowledge
    persist event atomically
    acknowledge 202
    process queued event with bounded retries

    Related pages

    • Webhook events and payloads
    • Test and troubleshoot webhooks
    • Configure permissions, access, and token security
    PreviousTest and troubleshoot webhooksNextNotification and auto-link automation