Skip to main content
Test your webhook integration before deploying to production. Use Xquik’s signed test delivery, local HTTPS tunnels, payload inspectors, and delivery logs to verify handlers before real monitor events arrive.

Test with Xquik first

Use the Test Webhook endpoint after you create a webhook. Xquik sends a real webhook.test delivery to the configured URL with the same X-Xquik-Signature, X-Xquik-Timestamp, and X-Xquik-Nonce headers used for production monitor events. webhook.test payloads contain eventType, data.message, and timestamp. They omit deliveryId and streamEventId. Use them for reachability and signature checks, not production deduplication.
Response when your endpoint accepts the delivery.
Response when your endpoint rejects the delivery.
Check your server logs for the webhook.test payload. Verify the HMAC before processing it. Return a 2xx response only after your handler accepts the event.

End-to-end handoff check

Use a signed test delivery to prove the receiver can verify requests. Then use production monitor deliveries to prove idempotency and storage behavior.

Signature checkpoint

Store the webhook secret once. Verify the raw body with X-Xquik-Signature, X-Xquik-Timestamp, and X-Xquik-Nonce before parsing or queueing the event.

Test payload checkpoint

Treat webhook.test as a signed reachability check. It includes eventType, data.message, and timestamp, and omits deliveryId and streamEventId.

Production deduplication

Use deliveryId for receiver retry deduplication. Use streamEventId when one monitor event should process once across endpoint changes.

Delivery triage

Query GET /api/v1/webhooks/{id}/deliveries for status, attempts, lastStatusCode, lastError, createdAt, and deliveredAt before paging or replaying work.

Event join

Use delivery streamEventId as the {id} for Get Event. Store the event monitorId, monitorType, type, occurredAt, and data with the receiver incident.

Receiver replay row

Store signed test deliveries separately from production delivery rows. A webhook.test row proves reachability and HMAC verification only. Production rows carry the IDs your receiver needs for retry deduplication, event deduplication, and event detail joins.
Use this row after verification succeeds and before slow downstream work. Keep the raw body available for the HMAC check, then store only the deduplication IDs, join route, verification state, and sanitized delivery context in shared systems.

Local testing with ngrok

ngrok creates a public HTTPS tunnel to your local server. Xquik can then deliver webhooks to your development machine.
1

Install ngrok

2

Start your local server

Run your webhook handler on a local port such as :3000:
3

Start the ngrok tunnel

ngrok outputs a public HTTPS URL:
Copy the https:// URL.
4

Create a webhook with the ngrok URL

Save the secret from the response for signature verification.
5

Send a signed test delivery

Trigger a signed webhook.test request through the tunnel before waiting for real tweet events:
Inspect your app logs and the ngrok web inspector at http://localhost:4040.
6

Trigger events

When a monitored account posts a tweet, Xquik delivers the event through ngrok to your local server. Check your server logs and the ngrok web inspector at http://localhost:4040.
ngrok URLs change every time you restart the tunnel (free plan). Update your webhook URL after each restart, or use a paid ngrok plan for stable subdomains.

Testing with webhook.site

Use webhook.site to inspect webhook payloads without running a local server.
1

Get a webhook.site URL

Visit webhook.site. The site generates a unique HTTPS URL automatically:
2

Create a webhook with the webhook.site URL

3

View incoming payloads

When events arrive, they appear in the webhook.site dashboard in real time. Inspect headers (X-Xquik-Signature, Content-Type) and the JSON body to verify the payload format matches your expectations.
webhook.site is useful for inspecting payload structure. For testing signature verification and handler logic, use ngrok with a local server instead.

Sending test payloads

Simulate a webhook delivery to your local handler without calling Xquik. This is useful for unit tests or offline debugging. For end-to-end verification of the configured webhook URL, prefer POST /webhooks/{id}/test.
Test payload structure.
Include deliveryId and streamEventId in offline fixtures so receiver idempotency tests match production deliveries. Test other event types by changing the eventType field, for example to tweet.reply, tweet.quote, or tweet.retweet.

Debugging delivery failures

Check delivery status

Query the deliveries endpoint to see delivery attempts and error details:
Response.
Join streamEventId to Get Event when a receiver owner needs the original monitor event behind a failed or exhausted delivery.
Store the event monitorId, monitorType, type, occurredAt, and data with the delivery id, status, attempts, lastStatusCode, and lastError before paging support, queue, or receiver owners.

Reconcile missed deliveries

Use delivery rows for receiver attempts and event pages for stored monitor history. The delivery streamEventId is the event id. A failed receiver can rebuild its downstream queue from stored events after you fix the handler.
Store nextCursor after each event page. Continue with GET /api/v1/events?limit=100&cursor={nextCursor} until hasMore is false. Then compare event IDs with delivery streamEventId values before replaying your own downstream work.

Delivery statuses

pending

Queued for the next delivery attempt. Check recent deploys, tunnel uptime, and receiver availability before forcing a new test.

delivered

Your endpoint returned 2xx. Confirm your handler verified the signature and stored the event before it returned success.

failed

The latest attempt failed and is retrying with backoff. Inspect lastStatusCode, lastError, and your receiver logs.

exhausted

Xquik used all retry attempts, or the receiver returned 410 Gone. Fix the endpoint, then send a new signed test delivery.

Common failure reasons

Respond within 10 seconds. If your handler is slow, return 200 immediately and process the event asynchronously using a background job queue.
Any response outside the 200-299 range counts as a failure. Check your server logs for unhandled exceptions or validation errors in your handler. Common causes include missing middleware such as express.raw(), JSON parse errors, or database connection failures.
Xquik could not resolve the webhook URL hostname. Verify your domain DNS records are correct. If using ngrok, confirm the tunnel is still running.
Webhook URLs must use HTTPS with a valid certificate. Xquik rejects self-signed certificates. Use a trusted CA (Let’s Encrypt, Cloudflare) or ngrok for local development.
The target server is not accepting connections. Verify your server is running and listening on the correct port. Check firewall rules if running on a cloud provider.
Compute the HMAC over the raw request body bytes, not a re-serialized JSON object. Re-serialization can alter whitespace or key ordering. Use express.raw() in Node.js, request.get_data() in Flask, or io.ReadAll(r.Body) in Go.

Webhooks overview

How webhooks work, delivery format, and retry policy.

Signature verification

HMAC-SHA256 verification in Node.js, Python, and Go.

Deliveries API

Query delivery attempts and statuses.