Build guide

Build an earnings call summary bot for X
8-K in, earnings thread out

A 40-line script watches SEC EDGAR for results filings, an AI model turns the press release into a 4-post thread with revenue, EPS and guidance, and one OpenTweet call posts it. No X developer account, no per-post billing.

Card required, cancel any time.

The short answer

Poll https://data.sec.gov/submissions/CIK##########.json for each company, pick new 8-K filings whose items include 2.02, download the exhibit 99.1 press release, have an AI model extract revenue, EPS and guidance into a thread, check every number against the text, and send it to POST https://opentweet.io/api/v1/posts with is_thread: true. Add the call transcript as a reply when a transcript API has it.

Q3 2026 season is on now. Per one earnings tracker (October 23), Microsoft and Alphabet report after the close on Wednesday, October 28, Amazon on Thursday, October 29, and Apple on Monday, November 2; Nvidia had not set a date. Confirm on each investor relations page. The script below already watches those four.

Six post types for an earnings account

Speed gets the first follow. Getting the numbers right every time keeps it.

Results drop

Event-driven

The 4-post thread, seconds after the 8-K hits EDGAR. The post people turn notifications on for.

Guidance line

Event-driven

The one sentence that moves the stock after hours, quoted from the release.

Call highlights

After the call

A reply to the thread once the transcript is out: the 3 answers from Q&A that matter.

Week ahead

Scheduled

Sunday: who reports this week, with dates and before or after the bell.

Scorecard

Scheduled

Friday: the week's reports in one thread, revenue growth sorted high to low.

Non-US filers

Event-driven

Foreign issuers file results as 6-K, not 8-K. Add form 6-K to the filter for ADRs.

The 8-K watcher

Run it every 2 minutes from 4:00 to 6:00 pm New York time on report days, and every 15 minutes the rest of the season. It finds the newest Item 2.02 filing per company, reads the attached press release and posts once per filing. Mark the filings already on EDGAR as posted before your first live run, or it will post last quarter.

Python

import json, pathlib, re, time, requests

OT_KEY = "ot_your_key"
SEC = {"User-Agent": "Your Name you@example.com"}   # the SEC requires a contact
WATCH = {"MSFT": 789019, "GOOGL": 1652044, "AMZN": 1018724, "AAPL": 320193}
POSTED = pathlib.Path("posted_8k.json")
seen = set(json.loads(POSTED.read_text())) if POSTED.exists() else set()

def earnings_8ks(cik):
    r = requests.get(f"https://data.sec.gov/submissions/CIK{cik:010d}.json", headers=SEC, timeout=20).json()["filings"]["recent"]
    for form, items, acc, when in zip(r["form"], r["items"], r["accessionNumber"], r["acceptanceDateTime"]):
        if form == "8-K" and "2.02" in items.split(","):
            yield acc, when

def press_release(cik, acc):
    base = f"https://www.sec.gov/Archives/edgar/data/{cik}/{acc.replace('-', '')}"
    files = requests.get(f"{base}/index.json", headers=SEC, timeout=20).json()["directory"]["item"]
    ex99 = next(f["name"] for f in files if re.search(r"ex-?99", f["name"], re.I))
    html = requests.get(f"{base}/{ex99}", headers=SEC, timeout=30).text
    return re.sub(r"<[^>]+>", " ", html), f"{base}/{ex99}"

for ticker, cik in WATCH.items():
    for acc, when in list(earnings_8ks(cik))[:1]:          # newest earnings 8-K only
        if acc in seen:
            continue
        text, link = press_release(cik, acc)
        thread = summarize(ticker, text)                    # your model, see below
        thread[-1] += f"\n\nRelease: {link}"              # one link, last post only
        requests.post(
            "https://opentweet.io/api/v1/posts",
            headers={"Authorization": f"Bearer {OT_KEY}"},
            json={"is_thread": True, "thread_tweets": thread, "publish_now": True},
        )
        seen.add(acc)
    time.sleep(0.2)                                         # stay far below 10 req/s

POSTED.write_text(json.dumps(sorted(seen)))

The summary, with a number check

Any model works. The check at the end is the part that matters: a draft with a number that is not in the release never posts.

def summarize(ticker, release_text):
    """Return 3-4 posts. Extract from the text, never from memory."""
    prompt = f"""From this {ticker} earnings press release, write an X thread
of 4 posts, each under 280 characters:
1. ${ticker} headline: revenue, EPS, and year-over-year change.
2. The segment that moved the most, with its number.
3. Guidance for next quarter, quoted, or "No guidance given".
4. One line on what to watch on the call.
Use only numbers that appear in the text. No emoji, no "BREAKING",
no investment advice. Return JSON: {{"posts": [...]}}

{release_text[:30000]}"""
    posts = call_your_model(prompt)["posts"]
    # Reject the draft if any number in it is not in the release.
    for n in re.findall(r"\d[\d,.]*", " ".join(posts)):
        if n.rstrip(".,") not in release_text:
            raise ValueError(f"{n} not in source")
    return posts

EDGAR data checked October 28, 2026: Microsoft's July 29 results 8-K lists items 2.02 and 9.01, and its press release is the file msft-ex99_1.htm in the filing folder. Every OpenTweet field is in the API reference.

The no-code version: a filing alert

EDGAR publishes an Atom feed of each company's 8-Ks, and the OpenTweet RSS connector reads it. You get a fast "Microsoft just filed" alert, but not the numbers, and every 8-K type posts, not only results.

Connectors  ->  New connector  ->  Blog or newsletter (RSS)

  Feed URL:   https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany
              &CIK=0000789019&type=8-K&dateb=&owner=include&count=10
              &output=atom
  Prompt:     One line: which company filed, and the 8-K items.
  Frequency:  Every 5 minutes
  X account:  @yourearningsfeed

Or let your AI agent do earnings night

Connect Claude Code, Cursor or ChatGPT to the OpenTweet MCP server, paste the release or point the agent at the filing, and ask for the thread as a draft. You read it, fix it, and post it from your queue. Slower than the script, but a human checks every number.

Which plan fits your account

Flat monthly price. Earnings accounts are bursty: quiet for weeks, then 20 reports in a night.

Account typeBusiest nightPlan
A watchlist of 10-20 names, threads without linksUp to 20 posts a dayPro, $19.99/mo
A sector account with the release link on each threadUp to 10 link posts a dayAdvanced, $29/mo
The whole S&P 500, or one account per sector100+ posts on peak daysAgency, $49/mo, 300 posts a day

Each post in a thread counts as a post. Link posts: Pro 1 a day, Advanced 10, Agency 20, plus link credits. See pricing.

Numbers from the filing. Revenue, EPS and guidance come from the release text, checked in code. A wrong EPS figure after hours is the fastest way to lose a finance audience.

No advice. Report what was filed. Skip "buy", "sell" and price targets unless you are licensed to give them.

Label it. Turn on the Automated label in your X settings and do not auto-tag the company or reply to its posts. More in X automation rules.

Frequently asked questions

Where do earnings results appear first?

In the company's press release, which US-listed companies also file with the SEC as an 8-K under Item 2.02, "Results of Operations and Financial Condition", with the release attached as exhibit 99.1. Microsoft's last one was accepted by EDGAR at 20:04 UTC on July 29, 2026, four minutes after the US market close. The call itself usually starts 30 to 90 minutes later.

Is the SEC EDGAR API free?

Yes. https://data.sec.gov/submissions/CIK##########.json (the CIK padded to 10 digits) lists every recent filing with its form, filing time and 8-K item numbers, with no key. The SEC asks for a User-Agent that names you and gives a contact email, and no more than 10 requests per second. Watching 50 companies every 2 minutes is well under that.

How do I tell an earnings 8-K from other 8-Ks?

Check the items field. Earnings filings list 2.02 (usually "2.02,9.01"). Other 8-Ks cover executive changes (5.02), Regulation FD material (7.01) and more. Microsoft filed 8-Ks with items 5.02 in June and 7.01 in September 2026; only the 2.02 ones in April and July were results.

How do I get the earnings call transcript?

From a transcript API, after the call ends. API Ninjas has an earningstranscript endpoint (ticker, year and quarter, X-Api-Key header) on its premium tiers; Financial Modeling Prep, Finnhub and others sell transcripts on paid plans. Check each vendor's current pricing and whether its license allows republishing quotes. The press release is free and arrives first, so post that thread at once and add a transcript reply later.

Can an AI write the summary without making numbers up?

Make it extract, not recall. Give the model the press release text and ask for revenue, EPS, the year-over-year change and guidance, each with the sentence it came from. Check that every number in the draft appears in the source before you post, and never let it fill in analyst estimates it was not given.

Does the filing link count as a link post?

Yes. Any URL makes it a link post: $0.20 on the X API, and it counts toward your OpenTweet link allowance (1 a day on Pro, 10 on Advanced, 20 on Agency). Put the link only in the last post of the thread, or leave it out and let the cashtag carry discovery.

Can I post earnings without writing code?

Partly. EDGAR has an Atom feed of each company's 8-Ks (browse-edgar with type=8-K and output=atom), and it works in the OpenTweet RSS connector. But it includes every 8-K, not just results, and the connector does not read the attached press release, so you get "Microsoft filed an 8-K" rather than the numbers. For the real summary, use the script.

Posting prices, market-close recaps and charts as well? See the stock market bot. Covering coins instead of companies? See the crypto news bot, or the alert bot for any other trigger.

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.

Be first with the numbers tonight

Connect X, create a key, and your next earnings thread posts minutes after the filing.