Build guide

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.

FormWhat it tells followersFeed parametersNote
8-KMaterial events: deals, bankruptcies, CEO exits, delisting notices, earningsaction=getcurrent&type=8-KThe summary lists item numbers, so you can filter without opening the filing
Form 4Insider buys, sells, grants and option exercisesaction=getcurrent&type=4Listed twice (Reporting and Issuer); shares and price are in the filing XML
Schedule 13DA holder crossed 5% with intent to influence: activists, takeoversaction=getcurrent&type=SCHEDULE%2013Dtype=SC 13D returned nothing on Nov 6, 2026; use the new name
S-1IPO registrations and amendmentsaction=getcurrent&type=S-1Few a day; amendments (S-1/A) show pricing getting close
One companyEvery filing of one issuer, by CIKaction=getcompany&CIK=...&type=8-KWorks in the OpenTweet RSS connector with no code
SEC press releasesEnforcement actions, rule proposals, statementssec.gov/news/pressreleases.rssFor 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.01

A big contract, credit line or merger agreement.

Bankruptcy or receivership

Item 1.03

Rare, and always news.

Acquisition or sale closed

Item 2.01

The deal is done, not just announced.

Delisting notice

Item 3.01

The exchange says the company missed a listing rule. Reverse splits often follow.

Non-reliance

Item 4.02

Past financials can no longer be relied on: a restatement is coming.

Executive or board change

Item 5.02

CEO, 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:  @yourfilingsbot

Use 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.

SetupTypical volumePlan
A watchlist of tickers, or one form type with strict filtersUp to 20 posts a dayPro, $19.99/mo
All key 8-K items, or 8-Ks plus Form 4 buys plus 13Ds on 3 accountsUp to 100 posts a day, 3 X accountsAdvanced, $29/mo
One account per sector or per formUp to 300 posts a day, 10 X accountsAgency, $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.