Build a joke of the day bot for X
dad jokes, quotes, on this day
One post a day, at the same time, forever. Pull it from a free API with a 20-line script, schedule a month from one CSV, or let an AI agent write originals. No X developer account, no per-post billing.
Card required, cancel any time.
The short answer
Fetch a joke from https://icanhazdadjoke.com/ with Accept: application/json (free, no key), skip any ID you have posted, and send it to POST https://opentweet.io/api/v1/posts from a daily cron job. To schedule a month at once, send up to 50 posts per request with scheduled_date, or import a CSV with a date column. For history, use Wikimedia's free On this day feed.
Six formats for a daily account
Daily accounts win on habit. Same format, same time, every day, and followers start expecting the post.
Dad joke of the day
DailyOne joke, same time every day. The format people follow precisely because it never changes.
Quote of the day
DailyA short quote and its author. Best in the morning, in the time zone of your audience.
On this day
DailyOne historical event for today's date, with the year first. Works for any niche: sports, science, music.
Niche puns
DailyProgramming, chemistry, cat or finance jokes. A narrow joke account grows faster than a general one.
Riddle and answer
Twice a dayThe riddle in the morning, the answer as a scheduled post in the evening. Replies are the point.
Holiday specials
ScheduledHalloween, Thanksgiving and New Year jokes, written weeks ahead and scheduled for the day.
The dad joke bot in 20 lines
icanhazdadjoke returns a random joke, so the script remembers what it posted and tries again on a repeat. No link in the post, so it never counts as a link post.
Python
import json, pathlib, requests
OT_KEY = "ot_your_key"
POSTED = pathlib.Path("posted_jokes.json")
seen = set(json.loads(POSTED.read_text())) if POSTED.exists() else set()
for _ in range(5): # random endpoint, so skip repeats
joke = requests.get(
"https://icanhazdadjoke.com/",
headers={"Accept": "application/json",
"User-Agent": "dadjokebot (https://x.com/yourhandle)"},
).json()
if joke["id"] not in seen:
break
else:
raise SystemExit("only repeats today")
requests.post(
"https://opentweet.io/api/v1/posts",
headers={"Authorization": f"Bearer {OT_KEY}"},
json={"text": f"Dad joke of the day:\n\n{joke['joke']}", "publish_now": True},
)
seen.add(joke["id"])
POSTED.write_text(json.dumps(sorted(seen)))# every day at 13:00 UTC
0 13 * * * /usr/bin/python3 /home/you/dadjoke.pyOn this day, from Wikimedia
Same script, different source. Wikimedia's feed API is free and needs only a User-Agent. Post text the same way as the joke.
import datetime, requests
d = datetime.date.today()
events = requests.get(
f"https://api.wikimedia.org/feed/v1/wikipedia/en/onthisday/selected/{d:%m}/{d:%d}",
headers={"User-Agent": "onthisdaybot (https://x.com/yourhandle)"},
).json()["selected"]
e = min(events, key=lambda e: e["year"]) # the oldest one is usually the best story
text = f"On this day in {e['year']}: {e['text']}"Every OpenTweet field is in the API reference.
No code: a month from one request or one CSV
Write 30 jokes, give each a date, and send them in one request. Or keep them in a spreadsheet with a date column, export it, and click Import CSV in the queue. Tell the importer to post the joke column exactly as written, and every row is scheduled for its date.
POST https://opentweet.io/api/v1/posts
{
"posts": [
{ "text": "I only know 25 letters of the alphabet. I don't know y.", "scheduled_date": "2026-11-01T13:00:00Z" },
{ "text": "What do you call a fake noodle? An impasta.", "scheduled_date": "2026-11-02T13:00:00Z" },
{ "text": "I'm reading a book about anti-gravity. It's impossible to put down.", "scheduled_date": "2026-11-03T13:00:00Z" }
]
}Originals from an AI agent
API jokes are the same jokes every other bot posts. Connect Claude, ChatGPT or Cursor to the OpenTweet MCP server and ask for 20 new jokes in your niche. Keep the five that made you laugh and have it schedule them a day apart. Original posts are also the only kind that can earn from X Original Content Rewards.
Which plan fits your account
Flat monthly price. A daily account is a few posts a day, so the deciding number is how many accounts you run.
| Setup | Typical volume | Plan |
|---|---|---|
| One daily account | 1-5 posts a day | Pro, $19.99/mo, 20 posts a day |
| Jokes, quotes and history on separate accounts | 3 accounts | Advanced, $29/mo |
| A network of niche daily accounts | Up to 10 accounts | Agency, $49/mo |
Posts with a URL count toward link posts: Pro 1 a day, Advanced 10, Agency 20, plus link credits. A joke needs no link. See pricing.
Never repeat word for word. X rejects duplicate posts, and repeats are what make a daily account feel automated. Keep a list of what you posted.
Respect the source. Follow each API's terms: ZenQuotes requires attribution with a link, Wikipedia text is CC BY-SA. Credit or rewrite.
Label it. Turn on the Automated label in your X settings, and never auto-reply jokes under other people's posts. More in X automation rules.
Frequently asked questions
How do I make a joke of the day bot for X?
Pick where the jokes come from (a free API such as icanhazdadjoke, your own list, or an AI agent), then post one a day to https://opentweet.io/api/v1/posts from a cron job, or schedule a month at once with scheduled_date. OpenTweet posts it to your X account through a normal login, so you never create an X developer app.
Is there a free dad joke API?
Yes. icanhazdadjoke.com returns a random joke as JSON when you send the header Accept: application/json, with no key. Its docs ask you to set a User-Agent with your app name and a contact URL or email. Keep a list of the joke IDs you have posted, because a random endpoint repeats.
Is there a free quote of the day API?
ZenQuotes has a free endpoint, https://zenquotes.io/api/today, that returns the same quote of the day for everyone, with the author. Its free tier is limited to 5 requests per 30 seconds per IP and requires attribution with a link back to zenquotes.io. On X that makes each quote a link post, so check the terms or use your own quote list.
How do I post "on this day" facts?
Wikimedia's feed API returns selected events for any date: https://api.wikimedia.org/feed/v1/wikipedia/en/onthisday/selected/10/23 for October 23. Each event has a year and a one-line text. The text is Wikipedia content under CC BY-SA, so rewrite it in your words or credit Wikipedia.
Can I schedule a month of jokes at once?
Yes. Send up to 50 posts per request to the API, each with its own scheduled_date. Or put the jokes in a spreadsheet with a date column, export it as CSV, and use Import CSV in the queue. Tell the importer "post the joke column exactly as written" and it schedules every row from its date.
Will X let me post the same joke twice?
No. X rejects a post that duplicates one of your recent posts word for word, and repeating jokes is what makes a daily account feel like a bot. Remember what you posted, and if you rerun old favorites, change the wording.
Can a joke account earn money on X?
Only with original posts. X replaced Creator Revenue Sharing with Original Content Rewards on September 8, 2026, and it requires 500 verified followers and 500K verified impressions in 90 days. Jokes pulled from a public API are not original, so accounts that want payouts write their own, often with an AI agent drafting and a human picking the funny ones.
Want a character instead of a format? See the AI Twitter persona. Posting trivia and records for a sport? See the sports stats 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.
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.
Tomorrow's joke, already scheduled
Connect X, create a key, and schedule the next 30 days in one request.