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

240 requests per minute per IP (and per key when provided). Responses use standard HTTP status codes (401, 403, 429).

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" }