x_list Connector Instance receives the posts of its
list’s members within seconds, through an X Filtered Stream linked to a
webhook. Polling stays on as the fallback. Read the X list guide first:
everything there still applies.
What you bring
- A public URL for the API. Set
public_urlin theQUIVR_CONFIGof everyapiandworkerprocess to the address where X reaches your API, for examplehttps://quivr.example.com. Each instance’s webhook address is<public_url>/v0/connector-webhooks/<connector_id>; the instance read shows it aswebhook_url. The route needs no API key, because X signs every request. Put it behind your usual rate limiting. - The x-list plugin reachable from the API. The API relays each delivery
to the plugin, so pin it on the
apiprocesses too (the Railway image runs it beside the API). - An app with Filtered Stream and webhooks. Your X plan must include the Filtered Stream and webhook endpoints. The bearer token must manage the app’s stream rules and webhooks.
- The consumer secret, deposited with the bearer token
(
consumer_secret). The plugin answers X’s CRC check and verifies every delivery’sx-twitter-webhooks-signaturewith it.
Turn it on
Add awebhook block to the instance config:
Set
max_rules and max_rule_length to your plan’s limits. Rules are shared
by every instance of the same X app, so leave room for the others.
Deletion rechecks and resyncs run during polls, so while webhooks work they
also wait up to poll_interval_seconds: keep it within your recheck needs.
What the plugin sets up
During pull runs, the plugin reads the list members and turns them into rulesfrom:<user id> OR …, each within max_rule_length, tagged
quivr:<connector_id>. It adds and deletes only what changed, so a resync
with the same members writes nothing. It registers the webhook address (X
checks it with a CRC request) and links it to the stream. A list that needs
more than max_rules rules stays on polling (rule_limit_exceeded).
Deliveries go through the same mapping as polling. A post seen both ways is
one Record with one Version.
Health and fallback
health.push shows the webhook side:
An access error shows as the
access_error Connector Health state while
polling keeps collecting. To avoid false alarms, polling holds back posts
younger than one minute while webhooks work. A member added to the list shows
up at the next resync.
Check it with a real account
CI tests webhook mode against a local fake X only. To check a real account: turn it on for a test list, wait forhealth.push.state active, post from a
member, and watch the Record arrive within seconds. Then compare
health.usage with the X console.
Turning it off
Setenabled to false, or disable the instance. The rules tagged
quivr:<connector_id> and the webhook stay at X until you delete them in the
developer console or through the X API.