Build an SEC filings bot for X
8-K events, insider trades, 13D stakes
EDGAR publishes every new filing in free Atom feeds within minutes. Filter them to the ones that move a stock, add the ticker, and post to X. A 50-line script and no X developer account.
Card required, cancel any time.
The short answer
Every 5 to 15 minutes, fetch https://www.sec.gov/cgi-bin/browse-edgar?action=getcurrent&type=8-K&count=100&output=atom with a User-Agent that names you and an email (the SEC requires it, and allows 10 requests a second). Keep the 8-K items worth a post (1.01, 1.03, 2.01, 3.01, 4.02, 5.02), look up the ticker in sec.gov/files/company_tickers.json, and send each new filing to POST https://opentweet.io/api/v1/posts. Key on the accession number so nothing posts twice.
Filings accounts already run on OpenTweet. In the last 30 days, 12 paying accounts posted SEC content through it: reverse split and CUSIP change alerts with the cashtag, SEC rule proposals explained for traders, and newsroom accounts whose stories start in the filings. Demand is there too: on Google Trends over the last three months, "sec filings" was searched about ten times as often as "twitter bot".
The EDGAR feeds a filings bot reads
All free, no key. Each URL starts with https://www.sec.gov/cgi-bin/browse-edgar? and ends with &count=100&output=atom. We called every one on November 6, 2026.
| Form | What it tells followers | Feed parameters | Note |
|---|---|---|---|
| 8-K | Material events: deals, bankruptcies, CEO exits, delisting notices, earnings | action=getcurrent&type=8-K | The summary lists item numbers, so you can filter without opening the filing |
| Form 4 | Insider buys, sells, grants and option exercises | action=getcurrent&type=4 | Listed twice (Reporting and Issuer); shares and price are in the filing XML |
| Schedule 13D | A holder crossed 5% with intent to influence: activists, takeovers | action=getcurrent&type=SCHEDULE%2013D | type=SC 13D returned nothing on Nov 6, 2026; use the new name |
| S-1 | IPO registrations and amendments | action=getcurrent&type=S-1 | Few a day; amendments (S-1/A) show pricing getting close |
| One company | Every filing of one issuer, by CIK | action=getcompany&CIK=...&type=8-K | Works in the OpenTweet RSS connector with no code |
| SEC press releases | Enforcement actions, rule proposals, statements | sec.gov/news/pressreleases.rss | For regulation-watch accounts |
Need more than the feed? data.sec.gov/submissions/CIK##########.json has a company's full filing history, and EDGAR full-text search finds phrases such as "reverse stock split" inside filings.
Six 8-K items worth a post
Most 8-Ks carry Items 7.01 and 9.01, which on their own mean little. Of the 100 newest 8-Ks on November 6, 2026, 46 were earnings (Item 2.02), 15 had executive changes and 15 had material agreements. Filter on these:
Material agreement
Item 1.01A big contract, credit line or merger agreement.
Bankruptcy or receivership
Item 1.03Rare, and always news.
Acquisition or sale closed
Item 2.01The deal is done, not just announced.
Delisting notice
Item 3.01The exchange says the company missed a listing rule. Reverse splits often follow.
Non-reliance
Item 4.02Past financials can no longer be relied on: a restatement is coming.
Executive or board change
Item 5.02CEO, CFO and director exits and appointments.
Posting earnings (Item 2.02)? The earnings call bot turns the press release exhibit into a number-checked thread.
An 8-K alert bot in Python
Reads the 100 newest 8-Ks, keeps listed companies with an item from the list above, adds the cashtag and posts. Run it from cron every 5 to 15 minutes; seen.json keeps it from posting a filing twice. We ran it against the live feed on November 6, 2026 (with the post call swapped for a print).
import os, re, json, time, requests, xml.etree.ElementTree as ET
from pathlib import Path
SEC = {"User-Agent": "Your Name you@example.com"} # SEC asks every client to declare who it is
OT = {"Authorization": f"Bearer {os.environ['OPENTWEET_API_KEY']}"}
FEED = "https://www.sec.gov/cgi-bin/browse-edgar?action=getcurrent&type=8-K&count=100&output=atom"
NS = {"a": "http://www.w3.org/2005/Atom"}
SEEN = Path("seen.json")
WATCH = { # 8-K items worth a post, in plain words
"1.01": "signed a material agreement",
"1.03": "filed for bankruptcy or receivership",
"2.01": "closed an acquisition or sale of assets",
"3.01": "got a delisting or listing-rule notice",
"4.02": "said past financials can no longer be relied on",
"5.01": "reported a change in control",
"5.02": "reported an executive or board change",
}
tickers = {}
for v in requests.get("https://www.sec.gov/files/company_tickers.json", headers=SEC, timeout=30).json().values():
tickers.setdefault(v["cik_str"], v["ticker"]) # first ticker is the common stock
seen = set(json.loads(SEEN.read_text())) if SEEN.exists() else set()
feed = ET.fromstring(requests.get(FEED, headers=SEC, timeout=30).content)
for e in feed.findall("a:entry", NS):
acc = e.find("a:id", NS).text.rsplit("=", 1)[1]
m = re.match(r"8-K - (.+) \((\d{10})\) \(Filer\)", e.find("a:title", NS).text)
if acc in seen or not m:
continue
seen.add(acc)
name, cik = m.group(1), int(m.group(2))
items = re.findall(r"Item (\d\.\d\d)", e.find("a:summary", NS).text or "")
hits = [WATCH[i] for i in items if i in WATCH]
if not hits or cik not in tickers: # listed companies only
continue
text = (f"${tickers[cik]} {name} {' and '.join(hits)}.\n\n"
f"8-K filed {e.find('a:updated', NS).text[:10]} (Items {', '.join(items)})")
requests.post("https://opentweet.io/api/v1/posts", headers=OT,
json={"text": text, "publish_now": True}).raise_for_status()
time.sleep(2)
SEEN.write_text(json.dumps(sorted(seen)))What it posted from the live feed
$GTCH GBT Technologies Inc. signed a material agreement and reported an executive or board change.
8-K filed 2026-11-05 (Items 1.01, 2.03, 3.02, 5.02, 7.01, 8.01, 9.01)The post has no URL, so it is a plain post. Adding the filing link makes it a link post, which counts toward your plan's link limit. Field reference: API docs.
Watch one company with no code
EDGAR's company feeds are Atom, which the OpenTweet RSS connector reads. Paste the feed for a CIK, pick template mode, and every new filing from that company becomes a post.
Connectors -> New connector -> Blog or newsletter (RSS)
Feed URL: https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany
&CIK=0000320193&type=8-K&count=10&output=atom
Mode: Template
Template: New SEC filing: {title}
{description}
Frequency: Every 15 minutes
X account: @yourfilingsbotUse template mode, not AI mode, for EDGAR feeds. The feed entry holds only the form type, company, date and item numbers, not what the filing says. A model asked to write a post from that will fill the gap with guesses. To summarize the filing itself, fetch the document in code and pass its text to the model.
Let an AI agent explain the filing
Connect Claude, ChatGPT or Cursor to the OpenTweet MCP server, give it the filing text, and ask for two sentences: what happened and the number that matters. Keep the cashtag, form type and date from code, let the model write only the words, and have it say "according to its 8-K".
Which plan fits your bot
Flat monthly price, no per-post fee. A busy market day brings a few hundred 8-Ks, so filter hard.
| Setup | Typical volume | Plan |
|---|---|---|
| A watchlist of tickers, or one form type with strict filters | Up to 20 posts a day | Pro, $19.99/mo |
| All key 8-K items, or 8-Ks plus Form 4 buys plus 13Ds on 3 accounts | Up to 100 posts a day, 3 X accounts | Advanced, $29/mo |
| One account per sector or per form | Up to 300 posts a day, 10 X accounts | Agency, $49/mo |
Posts with a URL count toward link posts: Pro 1 a day, Advanced 10, Agency 20, plus link credits. See pricing.
Declare yourself to the SEC. Put a name and a contact email in the User-Agent and stay under 10 requests a second. That is the SEC's fair access policy, and the reason it blocks some scrapers.
Report, don't advise. "Filed an 8-K reporting the CFO's departure" is news. "Sell before it drops" is advice. Put "not investment advice" in the bio.
Label the bot. Turn on X's Automated label and name the person who runs it. More in X automation rules.
Frequently asked questions
How do I build a bot that posts SEC filings to X?
Poll EDGAR's latest-filings Atom feed (https://www.sec.gov/cgi-bin/browse-edgar?action=getcurrent&type=8-K&count=100&output=atom) every few minutes with a User-Agent that names you and an email address. Keep the 8-K items you care about, map the company's CIK to a ticker with sec.gov/files/company_tickers.json, and post each new filing to POST https://opentweet.io/api/v1/posts. Store the accession numbers you have posted so nothing goes out twice. OpenTweet posts through a normal X login, so you need no X developer account.
Does EDGAR have an RSS feed for new filings?
Yes. The SEC documents the Latest Filings search as a feed you can subscribe to: add output=atom to a browse-edgar?action=getcurrent URL and filter with type= (8-K, 4, SCHEDULE 13D, S-1). For one company, use action=getcompany&CIK=...&type=8-K&output=atom. Every one of these returned a valid Atom feed when we tested them on November 6, 2026. The SEC says filings are often on sec.gov within 1 to 3 minutes of acceptance.
What are the SEC's rate limits for EDGAR?
The SEC's fair access policy allows at most 10 requests a second, and asks every automated client to declare a User-Agent such as "Sample Company Name AdminContact@samplecompany.com". Clients without one can get an "Undeclared Automated Tool" or "Access Denied" response. A bot that checks one feed every few minutes is far below the limit.
Which 8-K items should a filings bot post?
The ones a holder would want to hear about the same hour: 1.01 material agreements, 1.03 bankruptcy, 2.01 completed acquisitions, 3.01 delisting notices, 4.02 non-reliance on past financials, 5.01 change in control and 5.02 executive or director changes. Item 2.02 is earnings (see the earnings call bot). Items 7.01 (Reg FD) and 9.01 (exhibits) are attached to most 8-Ks and are noise on their own. In the 100 newest 8-Ks on November 6, 2026, 46 carried Item 2.02, 15 carried 5.02 and 15 carried 1.01.
Can a bot post Form 4 insider buys and sells?
Yes. type=4 on the latest-filings feed lists every Form 4 as it arrives. Each filing appears twice, once under the insider (Reporting) and once under the company (Issuer), so key on the accession number. The feed only says who filed; the share count, price and buy or sell code are in the filing's XML, so fetch that before you post. Open-market purchases (transaction code P) are the ones followers care about.
Is it legal to post SEC filings on X?
EDGAR filings are public records, and restating what a company filed is what financial news accounts do all day. Report the filing, not a trade idea: no "buy", no price targets. Say "according to its 8-K", label the account as automated, and if anyone pays you to cover a ticker, use X's Paid Partnership label. This is not legal advice.
Posting prices and market moves instead? See the stock market bot. Betting markets? See the prediction market odds bot.
Everything you can build on X with OpenTweet
Post to X from your code, a watcher, or an AI agent. Start anywhere in the cluster.
OpenTweet vs the X API
Post, schedule, and automate X without a developer account or the $200/mo minimum.
X DM outreach, human-approved
Find and qualify leads, AI-draft DMs, approve each one, and drip-send from your own account via API or MCP.
Post to X without an API
The clean, account-safe way to post to X from your code or an AI agent.
Twitter MCP Server
Give Claude, Cursor, and OpenClaw the ability to post to X. 44 tools included.
Developer docs
Quickstart, API keys, MCP setup, and the REST reference for posting to X from code or an agent.
Cross-posting reference
One call posts to X, Bluesky and LinkedIn. The platforms field, per-network results, and why a network gets skipped.
Social media API for AI agents
Three ways an agent can post to X, Bluesky and LinkedIn, and the trade-offs of each.
LinkedIn MCP server
Post and schedule to a LinkedIn profile from Claude or Cursor through the official LinkedIn API.
XMCP vs OpenTweet
X's official MCP server bills per API call and cannot schedule. Compare it with the flat-fee hosted MCP.
MCP for AI agents
Connect your AI client to X in under two minutes, no X developer account.
Developer API and keys
REST endpoints, one bearer key, and usage tracking. Build on OpenTweet.
OpenTweet for AI agents
The posting layer for autonomous agents and automations that live on X.
Build an AI Twitter persona
Give your AI agent its own X account. Setup, cadence, and the rules that keep it safe.
Best MCP servers for social media
The 2026 ranked list. How the hosted OpenTweet MCP compares with the official X MCP and others.
Best API to post to X
Seven options priced at real volumes, and why links decide the bill.
Cheapest way to post to X via code
Flat fee vs pay-per-use. Why the $0.20 per-link fee flips the math past ~145 link posts a month.
X API pricing 2026
Every pay-per-use X API endpoint price from docs.x.com in one searchable table.
Bluesky posting API
Post and schedule to Bluesky with one REST call and OAuth, and cross-post to X and LinkedIn in the same request.
Automate LinkedIn posts
Post to LinkedIn from an AI agent, n8n or a script through the official Posts API, with one REST or MCP call.
The filing posted minutes after it lands
Connect X, create a key, and run the script before the next 8-K hits EDGAR.