You bring the posts from X.
Find out who wants to buy.
Published · X’s rules and prices checked at the source the same day
Search X with your own API access, send the posts to SignalPipe’s batch endpoint 25 at a time, and get a verdict on each: a buyer or not, and whether the three judges agreed. Reading 100 posts costs about 50 cents at X’s pay-per-use rates, and posts the judges do not need to convene for cost nothing on SignalPipe. The replies stay yours: one at a time, approved by you, under X’s rules.
X’s rules, before you start
- Reading: through the X API. X’s automation rules forbid automating its website instead. The API is pay-per-use: $0.005 per post read, up to 3 million reads a month.
- Sharing: X’s Developer Policy limits what you may pass to third parties to post IDs, beyond small manual exports, and does not address a service processing posts on your behalf. Read it for your use, and ask X if you are unsure.
- Replying: X bans automated replies to posts found by keyword search, requires its written approval to run an AI reply bot, and bans unsolicited automated direct messages.
What you need
- X API access, with a bearer token for reading. Or an agent that can already search X, such as one using Grok’s X Search tool.
- A SignalPipe operator key and product id. The key is in your console;
GET /products/listreturns the id.
1. Search X, then score the posts
Recent search covers the last seven days and returns up to 100 posts per request, so one search is four scoring calls. Write the query the way a buyer writes: the phrases people use when they ask for help, not your product’s name.
import os
import requests
X_HEADERS = {"Authorization": f"Bearer {os.environ['X_BEARER_TOKEN']}"}
SP_HEADERS = {"Authorization": f"Bearer {os.environ['SIGNALPIPE_OPERATOR_KEY']}"}
PRODUCT_ID = os.environ["SIGNALPIPE_PRODUCT_ID"]
# 1. Search the last 7 days of X. Every post returned is a paid read.
found = requests.get(
"https://api.x.com/2/tweets/search/recent",
headers=X_HEADERS,
params={"query": '("looking for" OR "any recommendations") help desk -is:retweet lang:en',
"max_results": 100},
timeout=30,
)
found.raise_for_status()
posts = found.json().get("data", [])
# 2. Score them against your product, 25 per call.
results = []
for i in range(0, len(posts), 25):
items = [{"id": p["id"], "text": p["text"], "source_hint": "x"} for p in posts[i:i + 25]]
scored = requests.post(
"https://api.signalpipe.io/signal/score_batch",
headers=SP_HEADERS,
json={"product_id": PRODUCT_ID, "items": items, "include_drafting_context": False},
timeout=600,
)
scored.raise_for_status()
results.extend(scored.json()["results"])
# 3. The buyers, as links you can open and answer yourself.
for v in results:
if v["ok"] and v["classification"] == "buying_intent":
print(f"https://x.com/i/web/status/{v['id']}")const X = { Authorization: `Bearer ${process.env.X_BEARER_TOKEN}` }
const SP = { Authorization: `Bearer ${process.env.SIGNALPIPE_OPERATOR_KEY}`, 'Content-Type': 'application/json' }
// 1. Search the last 7 days of X. Every post returned is a paid read.
const q = new URLSearchParams({
query: '("looking for" OR "any recommendations") help desk -is:retweet lang:en',
max_results: '100',
})
const found = await fetch(`https://api.x.com/2/tweets/search/recent?${q}`, { headers: X }).then(r => r.json())
const posts = found.data ?? []
// 2. Score them against your product, 25 per call.
const results = []
for (let i = 0; i < posts.length; i += 25) {
const items = posts.slice(i, i + 25).map(p => ({ id: p.id, text: p.text, source_hint: 'x' }))
const res = await fetch('https://api.signalpipe.io/signal/score_batch', {
method: 'POST',
headers: SP,
body: JSON.stringify({ product_id: process.env.SIGNALPIPE_PRODUCT_ID, items, include_drafting_context: false }),
})
if (!res.ok) throw new Error(`score_batch ${res.status}: ${await res.text()}`)
results.push(...(await res.json()).results)
}
const buyers = results.filter(v => v.ok && v.classification === 'buying_intent')2. Read the verdicts
Each post comes back with its id, a classification (buying_intent, competitor_mention, borderline or noise), whether the panel ran, and split: true when the judges disagreed. Act on the buyers they agreed on, read the split ones yourself, and re-check anything marked degraded. The fields are the same as in the Reddit recipe, which lists them in full.
3. Answer the buyers yourself
Open each buyer’s post and reply from your own account. If you would rather approve replies than type them, the open-source daemon posts a reply you have approved, as a reply to that post, using your own X app’s keys, with a daily cap. SignalPipe never auto-sends an X reply: each one waits for your approval, and publishing through the API costs $0.015 per post ($0.20 with a link). The drafts are written by AI, so read and edit each one in your own words before you approve it.
pip install "signalpipe-daemon[twitter]"
export SIGNALPIPE_OPERATOR_KEY=...
export X_API_KEY=... # your own X app
export X_API_SECRET=...
export X_ACCESS_TOKEN=... # the account the replies come from
export X_ACCESS_SECRET=...
export MAX_TWITTER_ACTIONS_PER_DAY=10From an agent
If your agent already reads X, connect SignalPipe’s MCP server beside it, with the same one-line setup as in the Reddit recipe, and ask it to score each post with score_signal, passing source_hint x. The full tool list is on the agents page.
Try one post first.
Paste a real post into the live panel and see the verdict and the three judges before you spend anything on the X API. Free, and no account needed.
Questions
Does SignalPipe read X for me?
No. X has no feed to read, so the posts come from you: your own X API access, or an agent that can already search X. SignalPipe scores the text you send and returns a verdict on each post.
What does it cost to read posts from X?
X’s API is pay-per-use: $0.005 for each post read, up to 3 million reads a month, and $0.015 to publish a post ($0.20 if it contains a link), at the rates on X’s pricing page. Scoring on SignalPipe is metered separately in judgements, and clear-cut posts cost nothing.
May I send X posts to an outside service?
X’s Developer Policy limits what you may pass to third parties to post IDs, beyond small manual exports, and it does not address a service processing posts on your behalf. Read it for your use, and ask X if you are unsure.
Can SignalPipe reply on X for me?
Replies come from your own account. The open-source daemon posts a reply you have approved, using your own X API keys, with a daily cap. SignalPipe never auto-sends an X reply: X bans automated replies to posts found by keyword search, so each one waits for you.
How many posts can I score per call?
Up to 25 per call to POST /signal/score_batch. Recent search returns up to 100 posts per request, so one search is four scoring calls.
Can I do this from Claude Code or another agent?
Yes. If your agent already reads X, through an X MCP server with your API keys or Grok’s X Search tool, connect SignalPipe’s MCP server and ask it to score each post with the score_signal tool.