Made by Desearch (desearch.ai).
AI News Today Board is a small Python script for analysts and founders who want one AI news today list instead of scrolling several feeds. Once a day it pulls the latest AI posts on X from the last 24 hours and recent coverage from a short list of tech news sites you choose, each with a link, and marks what is new since your last run.
The problem
Keeping up with AI means opening several feeds every morning and scrolling past the same stories twice. A single broad phrase like "ai news today" is too loose: the example notes that a broad query on that raw phrase brought back mostly off-topic posts. What helps is a short, fixed list of focused searches, one place to read the results, and a way to see only what is new since yesterday.
What the app does
- Runs a fixed query plan of five AI sub-queries: new AI model release, open source LLM, AI startup funding round, AI regulation, and AI agents launch.
- For each sub-query, gets the latest 30 X posts with at least 20 likes and keeps the ones from the last 24 hours.
- For each sub-query, gets 10 pages from a short list of tech news sites (
NEWS_SITESnear the top of the script, or--sitesfor one run) and keeps recent coverage: pages dated in the last 7 days, plus undated pages marked "no date". - Drops link-only posts and posts that mention an account, dedupes by link, and tags every item with its sub-query.
- Remembers the links it has already shown you in
seen-urls.txt, so the next board marks only fresh items as new. - Writes a CSV (one row per item) and a Markdown board: the top 15 posts by likes plus reposts plus replies, then recent coverage from the news sites, newest first.
How it works
- X posts. For each sub-query,
GET /twitterwithsort=Latest,count=30andmin_likes=20, throughx_searchin the desearch-py SDK.min_likesis passed as a string. Yes/no filters are not passed. - News pages. For each sub-query,
POST /desearch/ai/searchwithtools: ["web"],include_domainsset to your news sites,result_type: "ONLY_LINKS"anddate_filter: "PAST_24_HOURS", over REST withrequests. The SDK'sai_searchin desearch-py 1.2.1 (checked 2026-10-18 in the example README) has noinclude_domainsargument. - Filter. Keep posts from the last 24 hours, drop link-only posts and posts that mention an account (so every quote stays exactly as written), and keep pages from the last 7 days or undated ones. The example notes that the date filter did not narrow the web results to recent pages, so the script still drops pages older than 7 days.
- Merge. Dedupe by link, tag each item with its sub-query, and compare with
seen-urls.txt. - Write. Save the CSV, the Markdown board and the raw responses as JSON, and print the total cost from the response headers.
One run is 10 calls: 5 sub-queries times 2 sources.
The code
The script reads the API key only from a key file (~/.desearch_api_key by default, or --key-file PATH). It does not read environment variables. The X call, copied from ai_news_board.py on main (lines 55 to 72):
async def x_call(client, tag, query, count, min_likes):
"""GET /twitter through the desearch-py SDK (x_search). Yes/no filters are not passed."""
at, t0 = now(), time.time()
params = {"query": query, "sort": "Latest", "count": count, "min_likes": str(min_likes)}
try:
res = await client.x_search(query=query, sort="Latest", count=count, min_likes=str(min_likes), include_metadata=True)
data, meta = res.data, res.metadata
body = [d.model_dump(mode="json") if hasattr(d, "model_dump") else d for d in (data if isinstance(data, list) else [data])]
if isinstance(data, dict): body = data
status = 200
cost = getattr(meta, "cost_usd", None) if meta else None
meta_d = meta.model_dump(mode="json") if hasattr(meta, "model_dump") else (vars(meta) if meta else {})
except Exception as e:
status = getattr(e, "status", None); body = {"_error": repr(e)[:500]}; cost = None; meta_d = {}
rec = {"source": "x", "tag": tag, "params": params, "at": at, "seconds": round(time.time() - t0, 2),
"status": status, "cost_usd": cost, "meta": meta_d, "body": body}
log(rec, len(body) if isinstance(body, list) else 0)
return recThe script runs this once per sub-query. It also adds recent coverage from an editable list of news sites (NEWS_SITES near the top of the script) through POST /desearch/ai/search. That call is web_call in the same file (lines 75 to 91). QUERY_PLAN holds the five sub-queries, samples/ holds a saved run you can rebuild offline, and tests/ has offline tests.
Endpoints
GET /twitterPOST /desearch/ai/search
Example output
Saved sample from a run at 2026-10-18T16:00:15+04:00 (16:00 Asia/Tbilisi). This page shows that stored response. It does not run a live demo.
The live run log in samples/live-run-2026-10-18.md records 10 calls. Every call returned 200 and the number of items asked for (30 posts, 10 pages).
| call | sub-query | status | seconds | items returned |
|---|---|---|---|---|
GET /twitter sort=Latest count=30 min_likes=20 | model release | 200 | 9.26 | 30 |
GET /twitter sort=Latest count=30 min_likes=20 | open source llm | 200 | 4.07 | 30 |
GET /twitter sort=Latest count=30 min_likes=20 | ai funding | 200 | 7.71 | 30 |
GET /twitter sort=Latest count=30 min_likes=20 | ai regulation | 200 | 6.45 | 30 |
GET /twitter sort=Latest count=30 min_likes=20 | ai agents | 200 | 4.86 | 30 |
POST /desearch/ai/search tools=web count=10 | model release | 200 | 6.23 | 10 |
POST /desearch/ai/search tools=web count=10 | open source llm | 200 | 6.04 | 10 |
POST /desearch/ai/search tools=web count=10 | ai funding | 200 | 6.03 | 10 |
POST /desearch/ai/search tools=web count=10 | ai regulation | 200 | 6.03 | 10 |
POST /desearch/ai/search tools=web count=10 | ai agents | 200 | 7.95 | 10 |
After those filters, the log says the board had 34 X posts and 18 pages (4 dated in the last 7 days, 14 undated).
The public sample (samples/sample-raw.json) leaves out some posts, so rebuilding it makes a smaller board. samples/sample-ai-news.md reports:
- calls: 10
- X posts returned: 103, below the like threshold: 0, older than 24 h: 65, link only: 8, left out because they mention an account: 0
- web pages returned: 50, outside the site list: 0, older than 7 days: 32, no date: 14
- duplicates removed: 1, items on the board: 47, new: 47, on topic by keyword check: 44
Authors on the board are shown as "a user".
Run it yourself
git clone https://github.com/Desearch-ai/desearch-py-examples && cd desearch-py-examples/ai-news-today-board
pip install -r requirements.txt
printf '%s' 'YOUR_KEY' > ~/.desearch_api_key && chmod 600 ~/.desearch_api_key # key from console.desearch.ai
python ai_news_board.py --key-file ~/.desearch_api_key --out outputFlags that matter: --min-likes (default 20), --max-age-hours (default 24), --count (X posts per sub-query, default 30), --web-count (pages per sub-query, default 10), --page-days (default 7), --sites to use your own news sites for one run. To try it with no key and no cost, rebuild the saved board: python ai_news_board.py --from-raw samples/sample-raw.json --out output/sample.
What it costs
One daily run is 10 calls. The script prints each call's X-Desearch-Cost-Usd header and the sum. The saved live-run log and the sample do not include those header values, so this page does not state a dollar amount. See pricing.
Ideas to extend it
- Run it with cron every morning and keep
seen-urls.txtbetween runs, so each board shows only what is new. - Swap the sub-queries in
QUERY_PLANfor your own niche, for example one field or one product category. - Replace
NEWS_SITESwith the sites your team reads. - Post the top five items to a team chat each morning.
