Skip to main content
Webhooks deliver events from monitored X accounts to your server in real time. Every delivery is signed with HMAC-SHA256 so you can verify authenticity.

Quick setup

Get webhooks working in 3 steps:
1

Create a monitor

Start monitoring an X account for specific event types.
curl -X POST https://xquik.com/api/v1/monitors \
  -H "x-api-key: xq_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "elonmusk",
    "eventTypes": ["tweet.new", "tweet.reply"]
  }' | jq
2

Register a webhook

Provide an HTTPS URL and select which event types to receive. Xquik generates a signing secret. Store it securely, it is only returned once.
curl -X POST https://xquik.com/api/v1/webhooks \
  -H "x-api-key: xq_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhook",
    "eventTypes": ["tweet.new", "tweet.reply"]
  }' | jq
Response:
{
  "id": "15",
  "url": "https://your-server.com/webhook",
  "eventTypes": ["tweet.new", "tweet.reply"],
  "secret": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
  "createdAt": "2026-02-24T10:30:00.000Z"
}
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.

How it works

X Account Activity → Xquik Stream → Your Webhook Endpoint

Delivery format

Webhook events are delivered as HTTPS POST requests.

Headers

HeaderValueDescription
Content-Typeapplication/jsonPayload is always JSON
X-Xquik-Signaturesha256=HMAC_HEX_DIGESTHMAC-SHA256 signature for verification

Payload body

{
  "eventType": "tweet.new",
  "username": "elonmusk",
  "data": {
    "id": "1893456789012345678",
    "text": "The future is now.",
    "author": {
      "id": "44196397",
      "userName": "elonmusk",
      "name": "Elon Musk"
    },
    "isRetweet": false,
    "isReply": false,
    "isQuote": false,
    "createdAt": "2026-02-24T14:22:00.000Z"
  }
}
FieldTypeDescription
eventTypestringEvent type (see below)
usernamestringX username of the monitored account. Present on all event types except webhook.test.
dataobjectRaw event object from the X real-time stream
The data field contains the raw tweet object as received from the X real-time stream. Fields may vary by tweet type.

Event data shapes

Each event type includes a data object. Tweet events contain the raw tweet; follower events contain follower profile info. The examples below show the most common fields.

tweet.new

A new original tweet posted by the monitored account.
{
  "eventType": "tweet.new",
  "username": "elonmusk",
  "data": {
    "id": "1893456789012345678",
    "text": "The future is now.",
    "author": {
      "id": "44196397",
      "userName": "elonmusk",
      "name": "Elon Musk"
    },
    "isRetweet": false,
    "isReply": false,
    "isQuote": false,
    "createdAt": "2026-02-24T14:22:00.000Z"
  }
}

tweet.quote

A quote tweet posted by the monitored account.
{
  "eventType": "tweet.quote",
  "username": "elonmusk",
  "data": {
    "id": "1893456789012345679",
    "text": "Interesting take on this.",
    "author": {
      "id": "44196397",
      "userName": "elonmusk",
      "name": "Elon Musk"
    },
    "isRetweet": false,
    "isReply": false,
    "isQuote": true,
    "quoted_tweet": {
      "id": "1893400000000000000",
      "text": "Our latest launch was a success.",
      "author": {
        "userName": "SpaceX"
      }
    },
    "createdAt": "2026-02-24T15:10:00.000Z"
  }
}

tweet.reply

A reply posted by the monitored account.
{
  "eventType": "tweet.reply",
  "username": "elonmusk",
  "data": {
    "id": "1893456789012345680",
    "text": "Great question. Working on it.",
    "author": {
      "id": "44196397",
      "userName": "elonmusk",
      "name": "Elon Musk"
    },
    "isRetweet": false,
    "isReply": true,
    "isQuote": false,
    "inReplyToId": "1893411111111111111",
    "createdAt": "2026-02-24T16:30:00.000Z"
  }
}

tweet.retweet

A retweet posted by the monitored account.
{
  "eventType": "tweet.retweet",
  "username": "elonmusk",
  "data": {
    "id": "1893456789012345681",
    "text": "RT @xai: Exciting news today.",
    "author": {
      "id": "44196397",
      "userName": "elonmusk",
      "name": "Elon Musk"
    },
    "isRetweet": true,
    "isReply": false,
    "isQuote": false,
    "createdAt": "2026-02-24T17:00:00.000Z"
  }
}

follower.gained

A new follower was gained by the monitored account.
{
  "eventType": "follower.gained",
  "username": "elonmusk",
  "data": {
    "followerId": "123456789",
    "followerUsername": "spacefan42",
    "followerName": "Space Fan",
    "followerFollowersCount": 1500,
    "followerVerified": false
  }
}

follower.lost

An existing follower unfollowed the monitored account.
{
  "eventType": "follower.lost",
  "username": "elonmusk",
  "data": {
    "followerId": "987654321",
    "followerUsername": "formerfan",
    "followerName": "Former Fan",
    "followerFollowersCount": 850,
    "followerVerified": false
  }
}

webhook.test

A test payload sent via the Test Webhook endpoint to verify your endpoint is reachable.
{
  "eventType": "webhook.test",
  "data": {
    "message": "Test delivery from Xquik"
  },
  "timestamp": "2026-02-27T12:00:00.000Z"
}

Retry policy

Failed deliveries are retried with exponential backoff (base 1s, multiplier 2x):
AttemptDelay
11 second
22 seconds
34 seconds
48 seconds
516 seconds
After 5 failed attempts, the delivery is marked as exhausted. Check delivery status via the deliveries endpoint.
Retries are processed in batches, so actual delay may be slightly longer than shown.
Permanent failures: Client errors (400–499, except 429 Too Many Requests) are treated as permanent failures and are not retried. Ensure your webhook endpoint returns appropriate status codes.
Auto-disable: Endpoints are automatically disabled after 5 consecutive failed deliveries (across different events). Re-enable a disabled endpoint via the Update Webhook endpoint by setting isActive to true.

Requirements

  • Endpoint must use HTTPS
  • 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 should respond promptly with a 2xx status code. Non-2xx responses (except 429) count as failures and trigger retries

Where to go next

GoalResource
Full REST API reference for webhooksCreate Webhook, List Webhooks, Delivery Logs
Verify HMAC signatures and implement idempotencySignature Verification
Test webhook delivery locally with tunnelsWebhook Testing
MCP equivalentUse the xquik MCP tool: xquik.request('/api/v1/webhooks', ...) for create, list, update, delete, and test (MCP Tools)
Monitor setupCreate Monitor

Signature Verification

Verify HMAC-SHA256 signatures and implement idempotency.

Testing Webhooks

Test webhook delivery locally with tunnels and mock payloads.