1. Develop a webhook consumer app
To register a webhook with your X app, you need to develop, deploy, and host a web app that receives X webhook events and responds to CRC security requests.URL requirements
Create a web app with a publicly accessible HTTPS URL that will act as the webhook endpoint to receive events:- The URI path is up to you. These examples are all valid:
https://mydomain.com/service/listenhttps://mydomain.com/webhook/twitter
- The URL cannot include a port specification (e.g.,
https://mydomain.com:5000/webhookwill not work)
What your app needs to handle
Your webhook endpoint must handle two types of HTTP requests:2. The CRC check
The Challenge-Response Check (CRC) is how X validates that the callback URL you provided is valid and that you control it. Your web app must correctly respond to CRC requests to register and maintain your webhook.When CRC is triggered
If your webhook fails a CRC check, it will be marked as
invalid and will stop receiving events until it passes again.
How the CRC works
When X sends a CRC, it makes a GET request to your webhook URL with acrc_token query parameter:
response_token:
How to build the CRC response
- Use the
crc_tokenvalue from the query parameter as the message - Use your app’s consumer secret (API secret key) as the key
- Create an HMAC SHA-256 hash
- Base64 encode the result
- Prepend
sha256=to the encoded string
Example: Python
Example: Node.js
Example: Flask (full endpoint)
This example shows a complete webhook endpoint that handles both CRC validation (GET) and event delivery (POST):3. Securing webhooks
X’s webhook-based APIs provide two methods for confirming the security of your webhook server:Challenge-Response Check (CRC)
The CRC enables X to confirm ownership of the web app receiving webhook events. See Step 2 above for full implementation details.Signature verification
Each POST request from X includes anx-twitter-webhooks-signature header that enables you to confirm that X is the source of the incoming webhook.
To verify the signature:
- Get the
x-twitter-webhooks-signatureheader value from the incoming request - Create an HMAC SHA-256 hash using your consumer secret as the key and the raw request body as the message
- Base64 encode the hash and prepend
sha256= - Compare your computed value to the header value — they should match
4. Register your webhook
Once your app can handle CRC checks, register your webhook URL by making aPOST /2/webhooks request. When you make this request, X will immediately send a CRC request to your web app to verify ownership.
All webhook management endpoints require OAuth2 App Only Bearer Token authentication.
Create a webhook
POST /2/webhooks — API Reference
View webhooks
GET /2/webhooks — API Reference
Retrieve all webhook configurations associated with your application.
Delete a webhook
DELETE /2/webhooks/:webhook_id — API Reference
Delete a webhook using its webhook_id (obtained from the create or list response).
Validate and re-enable a webhook
PUT /2/webhooks/:webhook_id — API Reference
Triggers a CRC check for the given webhook. If the check succeeds, the webhook is re-enabled with valid: true.
valid field reflects the status after the check attempt. You can verify the current status using GET /2/webhooks.
Testing with xurl
For testing purposes, thexurl tool supports temporary webhooks. Install the latest version of the xurl project from GitHub, configure your authorization, then run:
Important notes
Sample apps
Next steps
Filtered Stream Webhooks
Receive filtered Posts via webhook
Account Activity API
Receive account events via webhook