Skip to main content

X / Twitter

Technical Schema

Twitter API & WebSocket

Managed Infrastructure

Integrate Twitter/X tracking, real-time events, and managed accounts via our high-speed global nodes.

Quick links

Base URLs

REST API Base

https://api.1322.io

WebSocket Endpoints

Normal

wss://ws.normal.1322.io/ws/normal

Ultimate

wss://ws.ultimate.1322.io/ws/ultimate

Authentication

REST API: Send your API key via query key=, header X-API-Key, or Authorization: Bearer <key>.

WebSocket: Same headers, or query token=<key>. Use the key that matches the stream (normal key for normal URL, ultimate key for ultimate URL).

Rate limit

Buckets are keyed on (client IP, API key). Reads: 1200/min (20/s), GET list, health, keys, tweet lookup, resolve. Writes: 600/min (10/s), POST / DELETE add, remove, admin mutations. Errors use 401 / 403 / 429. Bulk add/remove accept up to 200 identifiers per request; more than 200 returns 400.

WebSocket Guide

Connection & Usage

Connection Behavior

  • Server → client: Text frames only; each frame is one JSON object (UTF-8).
  • One-way for events: You only need to handle incoming messages. Server sends periodic pings; respond to pongs to avoid timeouts.
  • Filtered: You only receive events for Twitter user IDs in your tracked list for the key you used. Manage tracked accounts via the REST API or Discord; the stream updates automatically.

Event Flow (Tweets)

Tweets arrive progressively across stages, each enriches the previous:

  1. 1.tweet.mini.update first event (fastest, includes full author profile)
  2. 2.tweet.update enrichment (cards, subtweet chain, metrics, poll, grok)
  3. 3.tweet.update.expanded untruncated text, full article body
  4. 4.tweet.full fullchain: post with entire reply/quote chain resolved recursively

Other events: tweet.deleted, profile.update, profile.pinned.update, profile.unpinned.update, following.update.

Additive Merge (Recommended)

For the best display, merge stages by tweet.id (snowflake):

  • Use the longest body.text
  • Union all media arrays
  • Keep the deepest subtweet chain
  • Take the highest metric values
  • Never overwrite a populated field with null/empty. A later stage may lack data that an earlier stage had

Hybrid Clients

Hybrid accounts should connect to both endpoints simultaneously:

  • Normal stream: tweet events + profile events + following events
  • Ultimate stream: tweet events (profile/following events may only arrive on normal)

Deduplicate by tweet.id across both streams. Merge stages from both feeds additively for the richest card.

Reconnection

  • On disconnect, reconnect with exponential backoff (1s, 2s, 4s, 8s… capped at 30s).
  • Respond to server pings with pongs to keep the connection alive.
  • No events are queued during disconnection, you may miss events while offline.

WS Data Types & Events

All data types the 1322 WebSocket sends you.

Base Message Format
typescript
export interface WebsocketWorkerEvent {
    id: string; // Unique ID for this event (Can be used for debouncing and deduplication across multiple connections)
    type: string; // The type of event being sent
    source: "1322"; // Always "1322", identifies the event origin
}

Tweet Events

tweet.mini.update
typescript
export interface MiniTweetUpdate {
    type: 'tweet.mini.update';
    tweet: TwitterMiniTweet;
}

This is the main event for tweets, this will be the first event for ANY tweet. Meant to be brief information for speed. If the tweet is quote/retweet etc it won't yet contain subtweet information.

tweet.update
typescript
export interface TweetUpdate {
    type: 'tweet.update';
    tweet: TwitterTweet;
}

Used to provide full information on a tweet. Sent ~60ms after tweet.mini.update if the tweet is a quote, reply, retweet, or contains a URL with a card.

tweet.update.expanded
typescript
export interface TweetUpdateExpanded {
    type: 'tweet.update.expanded';
    tweet: TwitterTweet;
}

Includes FULL text of any tweet (tweet.update truncates it) and contains info about articles. Only sent if there's an article or truncated text.

tweet.deleted
typescript
export interface DeletedTweet {
    type: 'tweet.deleted';
    tweet: TwitterTweet; // metrics may be outdated such as likes, replies, retweets, etc
    deleted_at: number;
}
tweet.full
typescript
export interface TweetFull {
    type: 'tweet.full';
    tweet: TwitterTweet; // Fullchain: subtweet forms a recursive chain of full tweets
}

Fullchain, entire reply or quote thread resolved in one payload. The root tweet's subtweet is a full TwitterTweet (not null) that links down the chain. Each node has its own subtweet for the next level.

Reply chain:   Root → subtweet → Level 2 → subtweet → Level 3 → null
Quote chain:   Root → subtweet → Quoted → subtweet → Quoted's quote → null

Walk subtweet recursively to traverse the full thread.
Each node has: author, body, media, metrics, card, poll, article, grok.

Profile & Misc Events

profile.update
typescript
export interface ProfileUpdate {
    type: 'profile.update';
    user: TwitterUser; // The new profile information for this user
    before: TwitterUser; // The old profile information for this user
}
following.update
typescript
export interface FollowingUpdate {
    type: 'following.update';
    change: "unfollowed" | "followed";
    following: TwitterUser; // The target user who was followed/unfollowed
    user: TwitterUser; // The watched user who was detected to have followed the target user
}
Pinned Tweet Updates
typescript
export interface WorkerProfilePinnedUpdateEvent extends WebsocketWorkerEvent {
    type: 'profile.pinned.update';
    user: TwitterUser; // The user who pinned their tweet(s)
    pinned: TwitterTweet[]; // The expanded pinned tweet(s) for this user
}
export interface WorkerProfileUnpinnedUpdateEvent extends WebsocketWorkerEvent {
    type: 'profile.unpinned.update';
    user: TwitterUser; // The user who pinned their tweet(s)
    pinned: TwitterTweet[]; // The expanded pinned tweet(s) for this user
}

Types

TwitterUser (Full Profile)
typescript
// Represents a twitter user's account information in complete format
// The TwitterUser interface represents a complete / detailed version of a Twitter / X user's profile.
export interface TwitterUser {
    id: string; // The user's account ID
    handle: string; // The user's account handle (Without @)
    private: boolean; // If the user's account is currently private or not
    verified: boolean | VerificationBadge; // Blue check, gold org badge, or boolean shorthand
    sensitive: boolean; // If the user's account is marked to contain sensitive information or not
    restricted: boolean; // If the user's account is currently restricted for unusual activity or not
    joined_at: number; // The UNIX timestamp of when the user joined Twitter in milliseconds

    // Contains the user's profile information
    profile: {
        name: string; // The user's profile display name
        location: null | string; // The user's profile location (if one is set)
        avatar: null | string; // The user's custom profile avatar url (if one is set)
        banner: null | string; // The user's custom profile banner url (if one is set)
        pinned: string[]; // The list of pinned tweet IDs (if any are pinned) on the user's profile

        // Contains the user's profile custom link information (if one is set)
        url: null | {
            name: string; // The display name of the link
            url: string; // The original URL of the link
            tco: string; // The Twitter t.co wrapped URL variant of the link
        };

        // Contains the user's profile description information
        description: {
            text: string; // The plain text of the description

            // The list of clickable URLs contained in the description
            urls: {
                name: string; // The display name of the URL
                url: string; // The original URL value of the URL
                tco: string; // The Twitter t.co wrapped URL variant of the URL
            }[];
        };
    };

    // Contains the user's profile metrics information
    metrics: {
        likes: number; // The number of liked tweets by the user
        media: number; // The number of media (images, videos, gifs) posted by the user
        tweets: number; // The number of tweets posted by the user
        friends: number; // The number of friends of the user (People who follow the user and the user follows them back)
        followers: number; // The number of followers of the user
        following: number; // The number of accounts followed by the user
    };
}
VerificationBadge
typescript
// When verified is an object (instead of boolean), it carries badge tier and optional org linkage
interface VerificationBadge {
  type: 'none' | 'blue' | 'gold'; // none=unverified, blue=standard checkmark, gold=organization
  label: null | {
    description: string;   // Affiliated org or business name
    badge: string | null;  // Badge image URL
    url: string | null;    // Link to org profile
  };
}
// Treat verified: true or type !== 'none' as having a checkmark.
// Use label only when showing org-linked badges.
TwitterMiniUser
typescript
interface TwitterMiniUser {
  id: string;
  handle: string;
  name?: string;
  avatar?: string;
  verified?: boolean | VerificationBadge; // boolean for simple check, or object for org badges
  profile?: { name: string; avatar: string | null; };
  metrics?: { following: number; followers: number; };
}
TwitterMiniTweet
typescript
// Represents a twitter tweet's information in a minimal format
// The TwitterMiniTweet interface represents a brief / compressed version of a Twitter / X post.
export interface TwitterMiniTweet {
    id: string; // The tweet's snowflake ID
    type: 'TWEET' | 'RETWEET' | 'QUOTE' | 'REPLY'; // The type of the tweet
    created_at: number; // The UNIX timestamp of when the tweet was created on Twitter's servers in milliseconds

    // The account information of the tweet's author
    author: TwitterMiniUser;

    // The subtweet (reply, quote, retweet) referenced by this tweet (if any)
    subtweet: null | TwitterMiniTweet;

    // Contains information about who the tweet is replying to (if any)
    reply: null | {
        id: string; // The account ID of the user who was replied to
        handle: string; // The account handle (Without @) of the user who was replied to
    };

    // Contains information about who the tweet is quoting (if any)
    quoted: null | {
        id: string; // The account ID of the user who was quoted
        handle: string; // The account handle (Without @) of the user who was quoted
    };

    // Contains the tweet's body information
    body: {
        text: string; // The plain text of the tweet body

        // The list of clickable URLs contained in the tweet
        urls: {
            name: string; // The display name of the URL
            url: string; // The original URL value of the URL
            tco: string; // The Twitter t.co wrapped URL variant of the URL
        }[];

        // The list of mentioned users in the tweet
        mentions: {
            id: string; // The mentioned user's account ID
            name: string; // The mentioned user's display name
            handle: string; // The mentioned user's account handle (Without @)
        }[];
    };

    // Contains information about the tweet's media
    media: {
        images: string[]; // The list of image URLs in the tweet
        videos: string[]; // The list of video URLs in the tweet
        thumbnails: string[];
        // Note! Proxied media will only be available in certain scenarios
        // Fall back to using normal media URLs if proxied URLs are not available
        proxied: null | {
            images: string[]; // The list of proxied image URLs in the tweet
        };
    };

}
TwitterTweet
typescript
// Represents a twitter tweet's information in complete format
// The TwitterTweet interface represents a complete / detailed / rich version of a Twitter / X post.
export interface TwitterTweet {
    id: string; // The tweet's snowflake ID
    type: 'TWEET' | 'RETWEET' | 'QUOTE' | 'REPLY'; // The type of the tweet
    created_at: number; // The UNIX timestamp of when the tweet was created on Twitter's servers in milliseconds

    // The account information of the tweet's author
    author: TwitterUser;

    // The subtweet (reply, quote, retweet) referenced by this tweet (if any)
    subtweet: null | TwitterTweet;

    // Contains information about who the tweet is replying to (if any)
    reply: null | {
        id: string; // The account ID of the user who was replied to
        handle: string; // The account handle (Without @) of the user who was replied to
    };

    // Contains information about who the tweet is quoting (if any)
    quoted: null | {
        id: string; // The account ID of the user who was quoted
        handle: string; // The account handle (Without @) of the user who was quoted
    };

    // Contains the tweet's body information
    body: {
        text: string; // The plain text of the tweet body

        // The list of clickable URLs contained in the tweet
        urls: {
            name: string; // The display name of the URL
            url: string; // The original URL value of the URL
            tco: string; // The Twitter t.co wrapped URL variant of the URL
        }[];

        // The list of mentioned users in the tweet
        mentions: {
            id: string; // The mentioned user's account ID
            name: string; // The mentioned user's display name
            handle: string; // The mentioned user's account handle (Without @)
        }[];

        // The list of structured components contained in the tweet body for expanded rich / long tweets (if any)
        components: (
            | {
            // The `text` component represents represents a text part of a long tweet
            type: 'text';
            text: string; // The plain text of the component
            bold: boolean; // If the text is bold or not
            italics: boolean; // If the text is italics or not
        }
            | {
            // The `image` component represents represents an image part of a long tweet
            type: 'image';
            url: string;
        }
            | {
            // The `video` component represents represents a video part of a long tweet
            type: 'video';
            url: string;
        }
            )[];
    };

    // Contains information about the tweet's media
    media: {
        images: string[]; // The list of image URLs in the tweet
        videos: string[]; // The list of video URLs in the tweet
        thumbnails: string[]; // The list of video thumbnail URLs in the tweet

        // Note! Proxied media will only be available in certain scenarios
        // Fall back to using normal media URLs if proxied URLs are not available
        proxied: null | {
            images: string[]; // The list of proxied image URLs in the tweet
            thumbnails: string[]; // The list of proxied thumbnail URLs in the tweet
        };
    };

    // Contains the embedded Grok xAI conversation preview in the tweet (if any)
    grok: null | {
        id: string; // The ID of the Grok conversation

        // The preview information of the Grok conversation (Supports either an answer or generated images)
        conversation: {
            from: 'USER' | 'AGENT'; // Who is the sender of the message
            message: string; // The text of the message
            images: string[]; // The list of image URLs in the message
        }[];
    };

    // Contains information about an embedded card within the tweet (if any)
    card: null | {
        url: string; // The original URL of the card
        image: string; // The thumbnail image URL of the card
        title: string; // The title text of the card
        description: string; // The description text of the card
    };

    // Contains information about a poll within the tweet (if any)
    poll: null | {
        ends_at: number; // The UNIX timestamp of when the poll ends in milliseconds
        updated_at: number; // The UNIX timestamp of when the poll was last updated in milliseconds

        // The list of poll choices
        choices: {
            label: string; // The label text of the poll choice
            count: number; // The number of votes for the poll choice
        }[];
    };

    // Contains information about an article within the tweet (if any)
    article: null | {
        id: string; // The article's snowflake ID
        title: string; // The title text of the article
        thumbnail: null | string; // The thumbnail image URL of the article
        created_at: number; // The UNIX timestamp of when the article was created in milliseconds
        updated_at: number; // The UNIX timestamp of when the article was last updated in milliseconds

        // Contains the article's body information
        body: {
            text: string; // The plain text of the article body

            // The list of components represents the rich structured component within the article
            // RENDERING: Each component should be rendered as a separate section with double line vertical spacing
            components: (
                | {
                // The `divider` component represents a divider between article sections
                // Twitter / X user interface renders this divider as a horizontal gray line
                type: 'divider';
            }

                // The `text` component represents some textual component within the article
                | {
                type: 'text';

                // The `header-one` variant is a large title which separates the article into sections
                // The `header-two` variant is a smaller title which separates the article into subsections
                // The `paragraph` variant is just regular paragraph text
                // The `blockquote` variant is just paragraph text idented by a line to form a quoted block of text
                // The `ordered-list` variant is an ordered list with numbering for each line
                // The `unordered-list` variant is an unordered list with bullet points for each line
                // The `latex-box` variant is a LaTeX equation box used to render mathematical equations (Ex: `$$a^2 + b^2 = c^2$$`)
                // The `markdown-box` variant is a Markdown code block used to render code snippets (Ex: `\\`\\`js\nconsole.log('Hello World!');\n\\`\\`\\`)
                variant:
                    | 'header-one'
                    | 'header-two'
                    | 'paragraph'
                    | 'blockquote'
                    | 'ordered-list'
                    | 'unordered-list'
                    | 'latex-box'
                    | 'markdown-box';

                // The list of lines represents the list items of this component
                // RENDERING: Each line should be rendered as a separate line with single line vertical spacing
                lines: {
                    // The plain text of this line
                    // The `styles` array contains unique styling information for parts of the text
                    // The `urls` array contains unique URLs for parts of the text
                    text: string;

                    // The list of styling applied to parts of the text identified by the `from` and `to` indexes
                    styles: {
                        from: number; // The starting index of the text which is styled
                        to: number; // The ending index of the text which is styled
                        text: 'bold' | 'italics' | 'strikethrough'; // The type of text styling applied
                    }[];

                    // The list of clickable hyperlink URLs identified by the `from` and `to` indexes
                    urls: {
                        from: number; // The starting index of the text which is a URL
                        to: number; // The ending index of the text which is a URL
                        url: string; // The clickable URL link of the text
                    }[];
                }[];
            }

                // The `media` component represents some visual media within the article
                | {
                type: 'media';

                // The `image` variant is an image media type
                // The `gif` variant is a GIF media type
                // The `video` variant is a video media type
                variant: 'image' | 'gif' | 'video';
                url: string; // The media URL for this variant of the media
                thumbnail: string; // The media thumbnail URL for this variant of the media
                caption: null | string; // The associated caption text (if any)
            }

                // The `tweet` component represents an embedded tweet within the article
                | {
                type: 'tweet';
                tweet: {
                    id: string; // The tweet's snowflake ID
                    url: string; // The tweet's URL
                    object: null | TwitterTweet; // The tweet object (May need to be fetched separately if null)
                };
            }
                )[];
        };
    };

    // Contains information about the tweet's metrics
    metrics: {
        likes: number; // The number of likes on the tweet
        quotes: number; // The number of quotes on the tweet
        replies: number; // The number of replies on the tweet
        retweets: number; // The number of retweets on the tweet

        // Contains information about the tweet's advanced metrics
        // If this is null, then you need to fetch the expanded version of the tweet to get the advanced metrics
        advanced: null | {
            views: number; // The number of views on the tweet
        };
    };

    // Community block, present when the tweet belongs to a community (fetched with ?full=true)
    community?: {
        id: string;    // Community snowflake ID
        name: string;  // Community display name
        url: string;   // Community URL
    };
}

Management API

X-Specific

Get tracked accounts

GET /v1/tracked

Retrieve all Twitter accounts you are currently tracking.

Response Example (200 OK)
typescript
{
  "success": true, "tier": "normal", "page": 1, "trackedAccounts": [
    {
      "createdAt": "2025-02-13T12:00:00Z", "twitterId": "44196397", "twitterUsername": "elonmusk"
    }
  ]
}

Get all keys (Hybrid)

GET /v1/keys

Returns all keys associated with your account. Essential for hybrid subscriptions to discover both Normal and Ultimate keys.

Response Example (200 OK)
typescript
{
  "plan": "hybrid", "keys": [
    {
      "tier": "normal", "key": "9121dc75-...", "trackedCount": 800, "totalLimit": 1500
    }, {
      "tier": "ultimate", "key": "a1b2c3d4-...", "trackedCount": 0, "totalLimit": 50
    }
  ]
}

Add tracked accounts

POST /v1/tracked

Add one or more Twitter accounts. You can send multiple accounts as a comma-separated list. Usernames and IDs are resolved automatically.

Request Example
bash
curl -X POST "https://api.1322.io/v1/tracked" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"identifiers": "elonmusk,@twitter,44196397", "type": "username"}'
Response Example (200 OK)
typescript
{
  "success": true, "message": "processed identifiers", "tier": "normal", "results": {
    "successful": [
      {
        "identifier": "elonmusk", "twitterUsername": "elonmusk", "twitterId": "44196397", "trackedAccount": {
          "createdAt": "2025-02-13T12:00:00Z", "twitterId": "44196397", "twitterUsername": "elonmusk"
        }
      }
    ], "skipped": [], "failed": []
  }
}

Remove tracked accounts

DELETE /v1/tracked

Remove one or more Twitter accounts from your tracking list.

Request Example
bash
curl -X DELETE "https://api.1322.io/v1/tracked" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"identifiers": "elonmusk,@twitter", "type": "username"}'
Response Example (200 OK)
typescript
{
  "success": true, "message": "processed identifiers", "tier": "normal", "results": {
    "successful": [{ "identifier": "elonmusk,@twitter" }], "skipped": [], "failed": []
  }
}

Fetch tweet by ID

GET /v1/data/tweet/:id

Fetch any tweet by its snowflake ID. Use the full or expanded boolean query parameters to request untruncated text. Returns the full TwitterTweet object.

Request Example
bash
curl "https://api.1322.io/v1/data/tweet/1234567890123456789?full=true" \
  -H "X-API-Key: YOUR_API_KEY"
Response Example (200 OK)
typescript
{
  "success": true, "tweet": {
    "id": "1234567890123456789", "type": "TWEET", "created_at": 1700000000000, "author": {
      "id": "44196397", "handle": "elonmusk", "name": "Elon Musk", "avatar": "https://pbs.twimg.com/profile_images/..."
    }, "body": {
      "text": "Full untruncated tweet text here...", "urls": [], "mentions": []
    }, "media": { "images": [], "videos": [], "thumbnails": [] }, "metrics": { "likes": 15200, "quotes": 340, "replies": 2100, "retweets": 4500 }
  }
}

Resolve username

GET /v1/resolve/username/:username

Resolve an X username to a Twitter ID. Returns the user's ID, display name, follower count, and account status.

Request Example
bash
curl "https://api.1322.io/v1/resolve/username/elonmusk" \
  -H "X-API-Key: YOUR_API_KEY"
Response Example (200 OK)
typescript
{
  "username": "elonmusk", "twitterId": "44196397", "displayName": "Elon Musk", "followers": 210000000, "status": "active"
}

Get API health

GET /v1/health

Returns the health status of the API. No authentication required.

Response Example
typescript
{ "status": "ok" }