CONTENTS

    How to Use the Twitter Timeline API to Display Tweets on Your Website

    avatar
    KeyApi
    ·July 28, 2026
    ·8 min read

    If you only want to show a public Twitter profile on a website, you may not need to build a complete API integration. An official embedded timeline is usually enough.

    You need the Twitter Timeline API when you want more control over the result. For example, you may want to display only the latest five posts, remove replies, create your own card layout, show media separately, or combine Twitter data with content from other platforms.

    The current X API endpoint for retrieving a user’s recent posts is:

    GET /2/users/{id}/tweets

    The endpoint returns structured JSON rather than ready-made HTML. Your server should request the data, prepare the fields your website needs, and then send a safe response to the browser. The bearer token should never be exposed in front-end JavaScript.

    For a multi-platform workflow, you can also compare the available options through KeyAPI’s Twitter API.

    Choose the Right Way to Display Tweets

    There are three practical ways to place Twitter content on a website.

    Method

    Best for

    Development work

    Layout control

    API credentials

    Official embedded timeline

    A simple public profile feed

    Low

    Limited

    Usually not handled by your server

    Direct X API integration

    Custom feed and application logic

    Medium to high

    High

    Required

    Unified social media API

    Websites that also use other platforms

    Medium

    High

    Managed through the provider

    Use an embedded timeline for a simple feed

    An embedded timeline is usually the fastest option if your requirement is simply:

    • Show a public account

    • Keep the standard Twitter/X appearance

    • Avoid building a custom data pipeline

    • Display the feed without storing posts in your database

    This approach is suitable for a company website, author page, event page, or documentation site.

    The disadvantage is control. You normally cannot treat each post as a normal content object in your own system. Filtering, custom sorting, media processing, and cross-platform reporting are also limited.

    Use the API for a custom website feed

    The API is a better fit when the website needs to control the output.

    Typical examples include:

    • A developer portal showing product announcements

    • A news page displaying only posts with images

    • A campaign page showing posts from a selected account

    • A dashboard combining Twitter, TikTok, Instagram, and YouTube data

    • A product page with a custom “latest updates” section

    This is the use case covered by this article.

    Use a unified API when Twitter is one part of the system

    If your website only needs Twitter, a direct X API integration may be enough.

    If the same page also needs TikTok videos, Instagram posts, YouTube data, or Threads content, maintaining separate authentication rules and response formats becomes more expensive. A unified provider can reduce the amount of platform-specific code, but you should still check:

    • Which fields are returned

    • How often data is refreshed

    • Whether media URLs are included

    • How deleted posts are handled

    • How usage and billing are measured

    The Data Flow You Should Build

    A reliable Twitter feed normally follows this path:

    X API
      ↓
    Your server
      ↓
    Data filtering and normalization
      ↓
    Cache or database
      ↓
    Website frontend

    The browser should not call the X API with your private bearer token. If the token is placed in client-side JavaScript, anyone can inspect it through browser developer tools.

    A safer structure is:

    Website browser → /api/twitter-feed on your server → X API

    Your server keeps the credentials private and returns only the fields that the page needs.

    Request the User Timeline

    The official endpoint requires a numeric X user ID. It does not use the username directly in the URL.

    A typical request looks like this:

    curl "https://api.twitter.com/2/users/2244994945/tweets?max_results=10&tweet.fields=created_at,public_metrics,attachments&expansions=attachments.media_keys&media.fields=url,preview_image_url,type" \
      -H "Authorization: Bearer $BEARER_TOKEN"

    The official X API reference documents GET /2/users/{id}/tweets and supports tweet fields, expansions, and media fields through query parameters. View the official endpoint reference.

    The important point is that the response contains data, not a finished website component.

    Fields worth requesting

    Field

    Why it matters on a website

    id

    Creates a stable link to the original post

    text

    Displays the post content

    created_at

    Shows publication time

    public_metrics

    Displays likes, replies, reposts, and quotes

    attachments

    Connects a post with its media

    media.fields

    Retrieves image or video metadata

    next_token

    Loads older posts when pagination is required

    Do not request every available field by default. Smaller responses are easier to cache, faster to process, and simpler to maintain.

    Build a Server-Side Feed Endpoint

    The following Node.js example shows the basic server-side pattern:

    import express from "express";
    
    const app = express();
    
    app.get("/api/twitter-feed", async (req, res) => {
      try {
        const url = new URL(
          "https://api.twitter.com/2/users/2244994945/tweets"
        );
    
        url.searchParams.set("max_results", "10");
        url.searchParams.set(
          "tweet.fields",
          "created_at,public_metrics,attachments"
        );
        url.searchParams.set(
          "expansions",
          "attachments.media_keys"
        );
        url.searchParams.set(
          "media.fields",
          "url,preview_image_url,type"
        );
    
        const response = await fetch(url, {
          headers: {
            Authorization: `Bearer ${process.env.X_BEARER_TOKEN}`
          }
        });
    
        const data = await response.json();
    
        if (!response.ok) {
          return res.status(response.status).json({
            error: "Twitter timeline request failed"
          });
        }
    
        res.json({
          posts: data.data || [],
          media: data.includes?.media || [],
          nextToken: data.meta?.next_token || null
        });
      } catch {
        res.status(500).json({
          error: "Unable to load Twitter timeline"
        });
      }
    });
    
    app.listen(3000);

    This example deliberately does not expose the bearer token to the browser.

    The front end can then request your own endpoint:

    const response = await fetch("/api/twitter-feed");
    const feed = await response.json();
    
    feed.posts.forEach((post) => {
      console.log(post.text);
    });

    The browser only sees the response created by your server.

    Normalize the Response Before Rendering

    A common mistake is sending the complete X API response directly to the page. That makes the front-end code depend too closely on the provider’s response structure.

    A better approach is to convert the response into a smaller internal format:

    {
      "id": "1780000000000000000",
      "text": "Example post text",
      "publishedAt": "2026-07-28T08:30:00.000Z",
      "url": "https://x.com/example/status/1780000000000000000",
      "imageUrl": null,
      "metrics": {
        "likes": 12,
        "replies": 3,
        "reposts": 5
      }
    }

    Your front end then works with your own fields instead of depending on every detail returned by X.

    This becomes especially useful if you later replace a direct integration with a unified provider. The page does not need to change as long as the server continues returning the same internal format.

    Handle Images Correctly

    Text-only feeds are simple. Media makes the implementation more complicated.

    The post may contain:

    • An image

    • Multiple images

    • A video

    • A GIF

    • No media at all

    Do not assume that every post has a direct image URL. The post may only contain media keys, while the actual media objects appear under the includes.media section of the response.

    Your server should:

    1. Read the post’s media keys.

    2. Match them with the objects in includes.media.

    3. Select the correct URL or preview image.

    4. Return one normalized media object to the front end.

    5. Display a text-only card when no media is available.

    Always include a fallback. A feed that shows blank cards when a post has no image looks broken even when the API request succeeded.

    Add Caching Before You Publish

    A website should not request the timeline from X every time a visitor opens the page.

    A practical starting setup is:

    • Cache the response for 5 to 15 minutes.

    • Store the last successful response.

    • Serve the cached response if the new request fails.

    • Refresh the cache in the background when possible.

    • Request only the number of posts displayed on the page.

    For example, if the website displays five posts, requesting 100 posts on every page view creates unnecessary API usage.

    Caching also improves page speed. Visitors receive the latest successful response from your server instead of waiting for a third-party API request.

    Common Errors and What They Usually Mean

    Error

    Likely cause

    What to check

    401

    Invalid or missing credentials

    Bearer token, header format, environment variable

    403

    Access or permission problem

    Account access, endpoint availability, token permissions

    404

    User or resource not found

    Correct numeric user ID and account status

    410

    Retired endpoint

    Old v1.1 URL or outdated library

    429

    Rate limit or usage limit

    Request volume, plan limits, caching

    Empty data

    No accessible posts or wrong filters

    Account visibility, filters, request parameters

    X’s official troubleshooting documentation lists authentication, endpoint access, request parameters, package limits, and response parsing as common areas to inspect. It also documents 401, 403, 404, 410, and 429 error conditions. Read the official error troubleshooting guide.

    If the same request works in cURL or Postman but fails in your application, the problem is probably in your server code, token loading, or response parsing.

    A Simple Production Test

    Before placing the feed on the homepage, test it with a small acceptance checklist.

    Test one account

    Confirm that the numeric user ID resolves to the account you intend to display. Do not rely only on the username stored in a form field.

    Test ten recent posts

    Use a small response first. Confirm that the feed displays:

    • Text-only posts

    • Image posts

    • Posts with links

    • Long text

    • Deleted or unavailable content

    • Posts with missing metrics

    Test the failure path

    Temporarily use an invalid token and verify that the website:

    • Does not expose credentials

    • Shows the cached response or a fallback message

    • Does not render an empty page

    • Logs the error on the server

    • Returns a useful HTTP status

    Test refresh behavior

    Check that repeated page views use the cache instead of generating a new API request every time. This is one of the easiest ways to reduce unnecessary usage.

    When the Twitter Timeline API Is Not the Best Choice

    The API is not automatically the right answer.

    Use an official embedded timeline when the requirement is only to show a standard public profile feed.

    Use the API when you need custom cards, filtering, media processing, your own caching, or data from multiple accounts.

    Use a unified social media API when the page needs Twitter alongside several other platforms and the team wants one normalized data layer.

    The right choice depends less on the word “API” and more on how much control the website actually needs.

    FAQ

    Can I call the Twitter Timeline API directly from browser JavaScript?

    You should not place a private bearer token in browser code. Use a server-side endpoint or a trusted API provider.

    What endpoint displays a user’s recent tweets?

    The current X API v2 endpoint is GET /2/users/{id}/tweets. It returns structured post data for the specified user ID.

    Can I use a username instead of a user ID?

    The timeline endpoint uses a numeric user ID. If your application starts with a username, resolve it to an ID before requesting the timeline.

    How often should the website refresh the feed?

    For a normal company or documentation website, a cache window of several minutes is usually more practical than requesting fresh data for every visitor. The exact interval depends on how time-sensitive the content is.

    Can I show tweets from a private account?

    Only data that the authenticated request is allowed to access can be returned. A website should not assume that a private account can be displayed as a public feed.

    Should I use the official API or KeyAPI?

    Use the official API if the website only needs one focused X workflow and the team is comfortable managing authentication and response handling.

    Use KeyAPI’s Twitter API when Twitter is part of a larger data workflow involving several social platforms or when you want to keep your application’s data layer more consistent.