How do I create a Twitter API?

To build a Twitter style API, start with four resources: users, tweets, follows, and timelines. Give each one a small set of REST endpoints. Use cursor pagination for anything that scrolls. Then decide early whether the home timeline is built on write or on read. That last choice shapes the whole system.

If you came here looking for the official X API to pull tweets from, that is a different thing. This answer is about designing your own service, which is also one of the most common API design interview questions.

The core resources

ResourceWhat it holdsMain operations
UserProfile, handle, countsCreate, read, update
TweetText, media, author, timestampCreate, read, delete
FollowAn edge from one user to anotherCreate, delete, list
TimelineAn ordered list of tweets for a readerRead only
EngagementLikes, retweets, repliesCreate, delete, list

Notice that a timeline has no create operation. It is a view the system builds, not something a client writes. Getting that right in an interview signals that you separated reads from writes.

The endpoints

POST   /v1/tweets                  Create a tweet
GET    /v1/tweets/{id}             Read one tweet
DELETE /v1/tweets/{id}             Delete your own tweet

GET    /v1/users/{id}              Read a profile
GET    /v1/users/{id}/tweets       That user's own tweets
POST   /v1/users/{id}/follow       Follow that user
DELETE /v1/users/{id}/follow       Unfollow

GET    /v1/timelines/home          Tweets from people you follow
GET    /v1/timelines/user/{id}     One user's public tweets

POST   /v1/tweets/{id}/likes       Like a tweet
DELETE /v1/tweets/{id}/likes       Remove your like
POST   /v1/tweets/{id}/retweets    Retweet

Two habits are being graded here. Collections are plural nouns, and actions are HTTP methods rather than words in the path. POST /v1/tweets reads better than POST /v1/createTweet, and it means every resource behaves the same way.

Follow is modelled as a sub resource with POST and DELETE instead of a /follow and /unfollow pair. One relationship, one path, two methods.

The timeline decision

This is the question behind the question. There are two ways to build a home timeline.

Fan out on write. When someone tweets, the system pushes the tweet id into a precomputed list for each follower. Reads are then very fast, because the list already exists. Writes get expensive, because a user with ten million followers triggers ten million list writes.

Fan out on read. The system stores the tweet once. When a reader asks for their timeline, it fetches the recent tweets of everyone they follow and merges them. Writes are cheap, reads are expensive, and the cost grows with how many accounts a person follows.

Real systems use both. Fan out on write for ordinary accounts, fan out on read for accounts with very large follower counts, then merge the two at read time. Saying that hybrid out loud is usually what the interviewer is waiting for.

Pagination that survives a live feed

A timeline changes while people read it. Page numbers break under that, because a new tweet shifts every item down and the reader sees duplicates.

Use cursor pagination. The client sends the pointer it got last time and receives the items after it.

GET /v1/timelines/home?limit=20&cursor=eyJpZCI6MTczNH0

{
  "data": [ ... ],
  "next_cursor": "eyJpZCI6MTcxNH0",
  "has_more": true
}

Leave the total count out. Counting a timeline is expensive and no client needs it.

Writes that are safe to retry

A phone on a weak connection will send the same tweet twice. The first request succeeded, the response was lost, and the app retried.

Accept an idempotency key on every create. The client generates a unique value and sends it as a header. The server stores it with the result. If the same key arrives again, it returns the original result rather than creating a second tweet.

POST /v1/tweets
Idempotency-Key: 8f14e45f-ea6a-4c1b-9f2b-2a1d4f3c9b77

Likes and follows do not need a key. They are naturally idempotent, because liking twice leaves the same end state.

Rate limits in the contract

Rate limiting protects the service, but it only helps clients if they can see it. Put the limits in the response.

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 12
X-RateLimit-Reset: 1723300000

Return 429 Too Many Requests when a caller goes over, with a Retry-After header. A client that knows when to try again stops hammering you.

Set different limits per endpoint. Reading a timeline and posting a tweet do not deserve the same budget.

Authentication

Use OAuth 2.0 for anything acting on behalf of a user, and scoped tokens so a client only gets what it needs. A read only analytics tool should not hold a token that can post.

Never accept a password on a normal endpoint. Never put a token in a query string either. Query strings end up in logs and browser history.

Search and hashtags

Search does not belong in the same store as the timeline. Tweets go into a search index, which is a data structure built for matching text rather than fetching by id.

GET /v1/search/tweets?q=system%20design&limit=20&cursor=...
GET /v1/hashtags/{tag}/tweets?limit=20&cursor=...

Indexing happens asynchronously. A tweet is written, an event goes on a queue, and the indexer picks it up. That means search results lag writes by a short window. Say so in the design, and say how long the lag is allowed to be.

Treat a hashtag as a resource with its own path. It keeps the URL readable and lets you add hashtag metadata later without a new endpoint.

What the interviewer is grading

The endpoint list is the easy part. Four things carry most of the score.

  • Resource modelling. Are the nouns right, and is the same pattern used everywhere?
  • The read path. Did you name the fan out choice and its cost, or skip it?
  • Failure behaviour. What happens on a retry, a partial write, or a deleted tweet still sitting in a timeline?
  • Client experience. Can a developer guess the next endpoint after seeing two of them?

Say which one you are working on as you move. An interviewer who can follow your order will forgive a detail you miss.

The pieces people forget

  • Media. Upload separately, get an id back, then attach the id to the tweet. Do not send a video inside a JSON body.
  • Replies and threads. A reply is a tweet with a parent id. Decide whether a thread is fetched flat or as a tree.
  • Notifications. Write them asynchronously through a queue, not inside the tweet request.
  • Deletes. Soft delete first, so a timeline holding the id does not break.
  • Errors. Return a machine readable code plus a human readable message, not just 400 Bad Request.

Frequently asked questions

How do you design a Twitter like API?

Start with users, tweets, follows, and timelines. Give each a small set of REST endpoints using plural nouns and HTTP methods. Then handle the three hard parts: timeline fan out, cursor pagination, and idempotent writes.

Should a timeline be built on write or on read?

Both. Precompute timelines for ordinary accounts so reads are fast, and compute on read for accounts with huge follower counts so writes stay cheap. Merge the two when the reader asks.

Why use cursor pagination for a timeline?

Because the list grows while people read it. Page numbers shift when new tweets arrive, so readers see duplicates or miss items. A cursor anchors on a value instead of a position.

How do you stop duplicate tweets from retries?

Accept an idempotency key on the create request. Store the key with the result, and return the original result if the same key arrives again.

What rate limits should a social API have?

Different budgets per endpoint, with the limit, the remaining count, and the reset time returned in headers. Send 429 with Retry-After when a caller goes over.

Is this the same as using the official X API?

No. This describes designing your own service. The official X API is a commercial product with its own access tiers and terms.

How to prepare

Work the whole question end to end. Designing the Twitter API is a standard interview question. The grade comes from the order you cover things in. Grokking Modern API Design Interview works it as a full capstone, from requirements through the timeline endpoints and the pagination model.

Learn the pieces underneath. Grokking the System Design Interview covers the caching, sharding, and queueing that a timeline at this scale depends on.

TAGS
System Design Interview
CONTRIBUTOR
Arslan Ahmad
Arslan Ahmad
ex-FAANG engineering manager and author or Grokking series.
-

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Explore Answers
What is Apple rejection rate?
What is AI in simple words?
Which IT field is best without coding?
What is industry specification?
Is 25 too late to become a software engineer?
What is Event-Driven Architecture vs Request-Driven Architecture?
Related Courses
New
Grokking the AI System Design Interview course cover
Grokking the AI System Design Interview
Learn to design AI systems the way interviewers expect: classic ML products, LLM and RAG architectures, and agentic systems, all through the lens of the system design interview.
4.6
(3,192 learners)
Discounted price for Your Region

$123

Grokking the Coding Interview: Patterns for Coding Questions course cover
Grokking the Coding Interview: Patterns for Coding Questions
The 24 essential patterns behind every coding interview question. Available in Java, Python, JavaScript, C++, C#, and Go. The most comprehensive coding interview course with 543 lessons. A smarter alternative to grinding LeetCode.
4.6
Discounted price for Your Region

$197

Grokking Modern AI Fundamentals course cover
Grokking Modern AI Fundamentals
Master the fundamentals of AI today to lead the tech revolution of tomorrow.
4.1
Discounted price for Your Region

$72

Design Gurus logo
One-Stop Portal For Tech Interviews.
Copyright © 2026 Design Gurus, LLC. All rights reserved.