Skip to main content
Account and keyword monitors check every second. Webhooks deliver matched events to your server. Every delivery uses an HMAC-SHA256 signature. Use webhooks when events from tracked accounts must reach your app without polling. The 10 tweet types are tweet.new, tweet.reply, tweet.quote, tweet.retweet, tweet.media, tweet.link, tweet.poll, tweet.mention, tweet.hashtag, and tweet.longform. The 11 profile types are profile.avatar.changed, profile.banner.changed, profile.name.changed, profile.username.changed, profile.bio.changed, profile.location.changed, profile.url.changed, profile.verified.changed, profile.protected.changed, profile.pinned_tweet.changed, and profile.unavailable.changed. Keyword monitors support tweet event types only. The setup returns a monitor ID, webhook ID, one-time signing secret, and signed JSON deliveries. Webhook operations are free. Active monitors cost 21 credits/hour and include stored events plus webhook delivery.

Account or keyword monitor

Output: monitor ID, username or query, and selected event types. Cost: 21 credits/hour while active.

Webhook endpoint

Output: webhook ID, URL, event types, and one-time secret. Cost: free.

Signed delivery

Output: HTTPS POST with JSON body and HMAC headers. Cost: included with the active monitor.

Choose the webhook source

Account activity

Create POST /monitors when one X account should emit selected tweet and profile event types. Store monitorId, username, xUserId, and eventTypes.

Keyword matches

Create POST /monitors/keywords when a query should emit matching tweet events. Store keywordMonitorId, query, and eventTypes.

Receiver endpoint

Create POST /webhooks after the monitor. Store the webhook id, URL, selected eventTypes, and one-time secret before sending tests.

Replay and audit

Use GET /events for stored monitor events and GET /webhooks/{id}/deliveries for delivery attempts. Join on streamEventId.

Quick setup

Set up webhooks in 3 steps:
1

Create a monitor

Choose an account monitor for one X account, or a keyword monitor for matching query results.
Store the returned monitor id. Account events include username. Keyword events include query.
2

Register a webhook

Provide an HTTPS URL and select which event types to receive. Xquik generates a signing secret. Store it in a secret manager. The API returns it only once.
Response.
3

Verify signatures

When events arrive, verify the X-Xquik-Signature header using your webhook secret to confirm authenticity. See Signature Verification for implementation details.Send a test payload before connecting production logic:

How it works

Delivery format

Xquik sends webhook events as HTTPS POST requests. It sends each monitor event as its own payload. If one active monitor check finds multiple new matching tweets, expect multiple POST requests, one per matched tweet event, instead of one batched payload.

Headers

Content-Type

application/json. Payloads are always JSON.

User-Agent

xquik-webhooks/1.0 (+https://xquik.com). Identifies Xquik traffic.

X-Xquik-Timestamp

Unix epoch milliseconds. Used in the signing string and for replay window enforcement.

X-Xquik-Nonce

16 random bytes in hex. Reject duplicates within the replay window.

X-Xquik-Signature

sha256=HMAC_HEX_DIGEST. HMAC-SHA256 of <timestamp>.<nonce>.<rawBody>.

Payload body

eventType

Type string. Event type selected by the source monitor and webhook.

schemaVersion

Type number. Webhook payload schema version. Current value is 1.

deliveryId

Type string. Webhook delivery ID. Every retry reuses it. Store it as the delivery-level idempotency key and use it for delivery-log correlation.

streamEventId

Type string. Stored monitor event ID. Store it as the event-level deduplication key when you must process one monitor event once across webhook retries or endpoint changes.

occurredAt

Type string. ISO timestamp for when the event occurred.

monitorId

Type string. ID of the monitor that produced the event. Account monitors and keyword monitors number separately, so read it together with monitorType. Use both to route events when many monitors share 1 webhook URL.

monitorName

Type string. Your monitor label when Xquik created the event. Present when the monitor had a name then. A rename leaves the event unchanged.

monitorType

Type string. account or keyword. Matches monitorType on the events API.

username

Type string. Current X username for account monitor events. It follows a username change. Omitted for keyword-only monitor events and webhook.test.

xUserId

Type string. Permanent X user ID of the monitored account, on account monitor events. It stays equal when the account changes its username, so use it to match events from before and after a change.

query

Type string. Keyword query that matched the event. Present for keyword monitor events.

data

Type object. Raw event object for the monitored tweet activity.
Post fields match REST responses. Profiles use username and verified for the displayed badge. Legacy userName remains available. rawVerified preserves the original X flag. The verified field now includes blue verification. Card, reaction, quote & repost profiles use these fields. Stored posts gain these fields when their source fields are available. Incomplete legacy posts remain readable.

Receiver storage row

After signature verification succeeds, store a compact receiver row before handing the event to workers. Use deliveryId for delivery-level retries and streamEventId for event-level processing. Do not store endpoint signing values, the raw request body, the raw signature, or full headers in shared incident rows.

Tweet & profile event shapes

Each event type includes data. Tweet events contain public post fields and retained legacy fields. The webhook.test event contains a test message and timestamp. The examples below show the most common fields.

tweet.new

A new original tweet posted by the monitored account.

tweet.quote

A quote tweet posted by the monitored account.

tweet.reply

A reply posted by the monitored account.

tweet.retweet

A retweet posted by the monitored account.

webhook.test

A test payload that the Test Webhook endpoint sends to verify that your endpoint is reachable.

Delivery order

Deliveries can arrive in any order. Xquik sends up to 20 at once to 1 endpoint, and retries can come after newer events. Order events by occurredAt, then streamEventId. A 429, 503 or timeout limits Xquik to 8 at once until 1 minute passes without one.

Retry policy

Return 2xx within 10 seconds for every delivery, even one you skip. Any other status, a redirect, a timeout, or a network error is a failure. 410 Gone is a normal failure. Xquik retries a failed delivery until your endpoint returns 2xx. There is no attempt limit. Xquik never pauses or turns off your webhook.

Failing endpoint

After a failed delivery, Xquik treats your endpoint as failing. It retries 1 waiting delivery at a time to check the endpoint. This is a real delivery, not a webhook.test. Checks start 2 seconds apart and slow to 1 every 15 minutes. New deliveries wait as pending until a check succeeds.

Recovery

When a check succeeds, Xquik starts sending pending deliveries at once. A delivery your endpoint rejected can still wait up to 7 days. Resume Webhook sends it at once.

1 rejected delivery

If no new event arrives within 2 seconds of a failure, Xquik retries the rejected delivery at the next check. New events wait for that check, up to 15 minutes. See the table below.

Quiet endpoint

A rejected delivery keeps failing checks while no new events arrive. After about 2 quiet days, the webhook shows needs_attention. Delivery continues.
While a rejected delivery fails, new events can arrive up to 15 minutes late.
If a new event arrives within 2 seconds of each failure, a rejected delivery waits longer: The wait stops growing at 7 days. Retries can arrive a little later than listed.

Pause or delete a webhook

Only you can stop retries. Pause the webhook with Update Webhook, or delete it. Xquik holds the deliveries that were waiting. Within 1 day, they show exhausted. Xquik keeps queued events until all deliveries finish. Events expire 30 days after Xquik creates them. Resume Webhook sends a signed test first. Then it starts sending held deliveries at once. A paused webhook gets no new deliveries. Use stored event pages to catch up. Deleting a monitor removes its waiting deliveries.

Check delivery status

List Deliveries shows each delivery’s status: pending, delivered, failed, or exhausted. attempts counts the tries so far. A retry reuses the same deliveryId, so store it and skip repeats. List Webhooks shows deliveryStatus and consecutiveFailures. needs_attention means 200 failed checks in a row. That takes about 2 days. Xquik keeps retrying.

When deliveries fail

  1. Fix your endpoint so it returns 2xx within 10 seconds.
  2. Call Resume Webhook. It sends a signed test first.
  3. When the test passes, Xquik starts sending waiting and rejected deliveries at once.
Without Resume, a rejected delivery can wait up to 7 days.

Backfill after a receiver outage

Xquik resends failed deliveries after your receiver recovers. Use this handoff when your systems lost work or the webhook was paused. Fix the receiver first. Then use delivery rows and stored event pages to rebuild downstream work.
Store nextCursor after every event page. Reprocess only events your receiver never stored. Skip repeats by streamEventId, since Xquik also resends failed deliveries. Events from a pause may never reach the webhook, so page them here. Scope event pages with monitorId for account monitors or keywordMonitorId for keyword monitors when the source is known. Omit both only for all-monitor replay.

Troubleshoot a delivery

Use this handoff when a receiver fails a signed test or keeps failing deliveries.

Signed receiver test

Run Test Webhook after changing endpoint code, secrets, firewall rules, or queue routing. Treat success: true with a 2xx statusCode as receiver proof.

Signature and IDs

Verify X-Xquik-Signature, X-Xquik-Timestamp, and X-Xquik-Nonce on the raw request body. webhook.test omits deliveryId and streamEventId, while production deliveries include both IDs.

Delivery triage

Check List Deliveries for status, attempts, lastStatusCode, lastError, createdAt, and deliveredAt. Act on failed, wait on pending, and ignore delivered. exhausted means the webhook was paused or deleted.

Needs attention

needs_attention does not stop delivery. Fix the receiver, then call Resume Webhook. It starts sending waiting deliveries at once.

Event context

Join streamEventId to Get Event when the receiver owner needs the original monitor event, tweet fields, username, or keyword query that triggered the delivery.

Requirements

  • The endpoint must use HTTPS
  • The endpoint must not resolve to a private or internal IP address (localhost, 10.x.x.x, 172.16-31.x.x, 192.168.x.x, 169.254.x.x)
  • Endpoints must return 2xx within 10 seconds

Where to go next

Webhook API reference

Create, list, update, deactivate, test, resume, and inspect webhook deliveries.

Signature verification

Verify HMAC-SHA256 signatures and implement idempotency.

Testing webhooks

Test webhook delivery locally with tunnels and mock payloads.

MCP equivalent

Use xquik.request('/api/v1/webhooks', ...) for create, list, update, delete, and test.

Monitor setup

Create account monitors that emit events for webhook delivery.

Keyword monitor setup

Create keyword monitors that emit matching tweet events for webhook delivery.