X / Twitter
Technical Schema
LATENCY
50-100ms
Twitter API & WebSocket
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.ioWebSocket Endpoints
Normal
wss://ws.normal.1322.io/ws/normalUltimate
wss://ws.ultimate.1322.io/ws/ultimateAuthentication
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 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.
tweet.mini.updatefirst event (fastest, includes full author profile) - 2.
tweet.updateenrichment (cards, subtweet chain, metrics, poll, grok) - 3.
tweet.update.expandeduntruncated text, full article body - 4.
tweet.fullfullchain: 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
subtweetchain - • 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.
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
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.
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.
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.
export interface DeletedTweet {
type: 'tweet.deleted';
tweet: TwitterTweet; // metrics may be outdated such as likes, replies, retweets, etc
deleted_at: number;
}
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
export interface ProfileUpdate {
type: 'profile.update';
user: TwitterUser; // The new profile information for this user
before: TwitterUser; // The old profile information for this user
}
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
}
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
// 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
};
}
// 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.
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; };
}
// 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
};
};
}
// 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
Get tracked accounts
GET /v1/trackedRetrieve all Twitter accounts you are currently tracking.
{
"success": true, "tier": "normal", "page": 1, "trackedAccounts": [
{
"createdAt": "2025-02-13T12:00:00Z", "twitterId": "44196397", "twitterUsername": "elonmusk"
}
]
}
Get all keys (Hybrid)
GET /v1/keysReturns all keys associated with your account. Essential for hybrid subscriptions to discover both Normal and Ultimate keys.
{
"plan": "hybrid", "keys": [
{
"tier": "normal", "key": "9121dc75-...", "trackedCount": 800, "totalLimit": 1500
}, {
"tier": "ultimate", "key": "a1b2c3d4-...", "trackedCount": 0, "totalLimit": 50
}
]
}
Add tracked accounts
POST /v1/trackedAdd one or more Twitter accounts. You can send multiple accounts as a comma-separated list. Usernames and IDs are resolved automatically.
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"}'
{
"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/trackedRemove one or more Twitter accounts from your tracking list.
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"}'
{
"success": true, "message": "processed identifiers", "tier": "normal", "results": {
"successful": [{ "identifier": "elonmusk,@twitter" }], "skipped": [], "failed": []
}
}
Fetch tweet by ID
GET /v1/data/tweet/:idFetch any tweet by its snowflake ID. Use the full or expanded boolean query parameters to request untruncated text. Returns the full TwitterTweet object.
curl "https://api.1322.io/v1/data/tweet/1234567890123456789?full=true" \
-H "X-API-Key: YOUR_API_KEY"
{
"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/:usernameResolve an X username to a Twitter ID. Returns the user's ID, display name, follower count, and account status.
curl "https://api.1322.io/v1/resolve/username/elonmusk" \
-H "X-API-Key: YOUR_API_KEY"
{
"username": "elonmusk", "twitterId": "44196397", "displayName": "Elon Musk", "followers": 210000000, "status": "active"
}
Get API health
GET /v1/healthReturns the health status of the API. No authentication required.
{ "status": "ok" }
Truth Social API & WebSocket
Direct monitoring of Truth Social posts, retruths, quotes, and media streams. Manage tracked accounts, check service health, and receive real-time events via WebSocket.
Quick links
Base URLs
REST API Base
https://truth.1322.ioWebSocket Endpoint
Format
wss://truth.1322.io/{path}?key={ws_key}Path and WS key are provided in your dashboard configuration.
Authentication
All endpoints except /health require the X-Api-Key header with your API key.
WebSocket: Connect with your WS key via the key= query parameter.
Rate limit
Rate limits are per-key and shown in the /v1/limits response. Standard HTTP status codes (401, 403, 429) are used for errors.
Management API
Health Check
GET /healthReturns the health status of the API. No authentication required.
curl "https://truth.1322.io/health"
{ "status": "ok" }
Service Status
GET /v1/statusReturns the current service status including post processing counts and error totals. Authentication required.
curl "https://truth.1322.io/v1/status" \
-H "X-Api-Key: YOUR_API_KEY"
{
"posts_processed": 1234, "errors_total": 0, "status": "running"
}
List Tracked
GET /v1/listList all Truth Social accounts currently being tracked for your server. Authentication required.
curl "https://truth.1322.io/v1/list" \
-H "X-Api-Key: YOUR_API_KEY"
[
{
"handle": "realDonaldTrump", "display_name": "Donald J. Trump", "added_by": "admin", "added_at": "2025-06-15T08:30:00Z"
}, {
"handle": "DanScavino", "display_name": "Dan Scavino", "added_by": "admin", "added_at": "2025-06-15T09:00:00Z"
}
]
Account Limits
GET /v1/limitsReturns your current tracking usage, maximum limits, and rate limits. Authentication required.
curl "https://truth.1322.io/v1/limits" \
-H "X-Api-Key: YOUR_API_KEY"
{
"current_tracked": 3, "max_tracked": 5, "rpm": 60, "tracked": ["danscavino", "elonmusk", "realdonaldtrump"]
}
Track Account
POST /v1/trackAdd a Truth Social account to your tracking list. Send the handle in the JSON body. Authentication required.
curl -X POST "https://truth.1322.io/v1/track" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{"handle": "realDonaldTrump"}'
{
"status": "ok", "account": "realDonaldTrump", "uid": "107780257626128497", "display_name": "Donald J. Trump", "tracked": ["danscavino", "elonmusk", "realdonaldtrump"], "current_tracked": 3, "max_tracked": 5
}
Untrack Account
POST /v1/untrackRemove a Truth Social account from your tracking list. Send the handle in the JSON body. Authentication required.
curl -X POST "https://truth.1322.io/v1/untrack" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{"handle": "realDonaldTrump"}'
{
"status": "ok", "account": "realDonaldTrump", "tracked": ["danscavino", "elonmusk"], "current_tracked": 2, "max_tracked": 5
}
WS Data Types
Complete data types delivered via the Truth Social WebSocket stream. Each post event contains the full payload below.
export interface TruthSocialMediaAttachment {
kind: 'image' | 'video' | 'gifv' | 'audio' | string;
url: string;
poster_url: string;
created_at: string;
source?: 'own' | 'quoted' | 'nested_quoted';
}
The source field indicates where the media attachment originates from:
- •
own: Media attached directly to this post. - •
quoted: Media from the post being quoted. - •
nested_quoted: Media from a quote-of-a-quote (the inner quoted post).
export interface TruthSocialAuthor {
id?: string; // original user_id, useful for dedupe
username: string; // handle (e.g. "realDonaldTrump")
display_name?: string; // display name
avatar?: string; // proxied avatar URL (same proxy as user_avatar)
}
export interface TruthSocialPost {
platform: 'truth';
username: string; // on retruths/quotes this is the outer actor
display_name: string;
user_avatar: string;
user_following: number;
user_followers: number;
user_id: string;
key: string;
timestamp: string;
seen_at: string;
text: string;
is_quote?: boolean;
quoted?: {
key: string;
text: string;
url?: string;
author?: TruthSocialAuthor; // NEW - original author of the quoted post
quoted?: {
key: string;
text: string;
url?: string;
author?: TruthSocialAuthor; // NEW - author of the nested quoted post
};
};
is_retruth?: boolean;
retruth_of_id?: string;
retruth_of?: TruthSocialAuthor; // NEW - original author of the retruthed post
card?: {
url: string;
title?: string;
description?: string;
image?: string;
};
media?: TruthSocialMediaAttachment[];
}
Field notes
- •
key: The unique post ID (Mastodon-style snowflake). Use this for deduplication. - •
seen_at: ISO-8601 timestamp of when 1322 first detected the post. - •
is_quote/quoted: Present when the post is quoting another post. Thequotedobject contains the referenced post's key, text, and URL. - •
quoted.quoted: Nested quote support (quote of a quote). The innerquotedobject follows the same shape, enabling two levels of quote resolution. - •
is_retruth/retruth_of_id: Present when the post is a retruth (boost). Theretruth_of_idreferences the original post's key. - •
card: Link preview card attached to the post, containing the URL, title, description, and preview image. - •
media: Array ofTruthSocialMediaAttachmentobjects. Thesourcefield on each item tells you whether the media is from the post itself, a quoted post, or a nested quoted post. - •
retruth_of: Original author of a retruth. The outerusernamestays the retruther. - •
quoted.author/quoted.quoted.author: Original author of the quoted post, and of a quote-of-a-quote. - • Author
avatarURLs are pre-proxied, use them directly in<img src>. A retruth of a quote returnsretruth_ofandquoted.authortogether, so the whole chain is available. - • Compatibility:
retruth_of,quoted.author, andquoted.quoted.authorare new optional fields. Existing clients are unaffected (non-breaking).
Instagram API & WebSocket
Monitor Instagram posts, reels, stories, and carousels in real-time. Manage tracked accounts, check service health, and receive events via WebSocket.
Quick links
Base URLs
REST API Base
https://1322.ioWebSocket Endpoint
wss://1322.io/IG?key={api_key}Authenticate with ?key=<api_key> on the connection URL.
Authentication
Send your API key via header Authorization: Bearer <key> or X-API-Key: <key>.
All endpoints except health require authentication.
Rate limit
Per-key RPM limit returned in the /v1/limits response. Standard HTTP status codes (401, 403, 429) are used for errors.
Management API
Health Check
GET /v1/healthReturns the health status of the API. Authentication required.
curl "https://1322.io/v1/health" \
-H "X-API-Key: YOUR_API_KEY"
{ "ok": true }
Account Limits
GET /v1/limitsReturns your current tracking usage, maximum limits, and request rate limits. Authentication required.
curl "https://1322.io/v1/limits" \
-H "X-API-Key: YOUR_API_KEY"
{
"status": "success", "max_tracked": 10, "current": 3, "rpm": 60
}
List Tracked
GET /v1/listList all Instagram accounts currently being tracked under your subscription. Authentication required.
curl "https://1322.io/v1/list" \
-H "X-API-Key: YOUR_API_KEY"
{
"status": "success", "tracked": ["elonmusk", "nike", "natgeo"], "current": 3, "max_tracked": 10
}
Track Account
POST /v1/trackAdd an Instagram account to tracking. Verifies the account exists before adding. Authentication required.
curl -X POST "https://1322.io/v1/track" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"username": "elonmusk"}'
{
"status": "success", "message": "Now tracking elonmusk", "tracked": ["elonmusk", "nike", "natgeo", "elonmusk"], "current": 4, "max_tracked": 10
}
Error codes
- •
list_full: Your tracking list is at capacity. - •
already_tracked: Account is already being tracked. - •
invalid_user: Account not found or invalid username format. - •
storage_error: Internal storage write failure.
Untrack Account
POST /v1/untrackRemove an Instagram account from your tracking list. Send the username in the JSON body. Authentication required.
curl -X POST "https://1322.io/v1/untrack" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"username": "elonmusk"}'
{
"status": "success", "message": "Stopped tracking elonmusk", "tracked": ["nike", "natgeo"], "current": 2, "max_tracked": 10
}
WS Data Types
Complete data types delivered via the Instagram WebSocket stream. Each post event contains the full payload below.
export interface InstagramPost {
platform: 'instagram';
username: string;
display_name: string;
user_avatar: string;
user_followers: number;
user_id: string;
key: string; // post id
timestamp: string;
seen_at: string;
text: string;
post_type: 'post' | 'reel' | 'story' | 'carousel';
media_count?: number;
hashtags?: string[];
mentions?: string[]; // includes coauthor usernames even when not @-mentioned
media?: InstagramMediaAttachment[];
is_collab?: boolean; // NEW - coauthor present, or owner != tracked account
collab_with?: string[]; // NEW - other accounts on the collab (excludes tracked)
is_pinned?: boolean; // NEW - pinned to the tracked account's profile
is_paid_partnership?: boolean; // NEW - paid / branded-content flag from IG
location?: { // NEW - place tag when the post has one
name: string;
lat?: number;
lng?: number;
};
}
export interface InstagramMediaAttachment {
// Backward-compatible type: 'image' | 'video'. Video COVER frames stay
// 'image' here so existing clients keep working.
kind: 'image' | 'video';
// Precise type + recommended discriminator (use media_role):
kind_v2?: 'image' | 'video_cover' | 'video';
media_role?: 'image' | 'video_cover' | 'video';
is_video_cover?: boolean; // true only for a video's preview/cover frame
media_index: number; // index within media[]
carousel_index?: number; // original IG carousel index (video + its cover share it)
video_index?: number; // ordinal among video items
cover_media_index?: number; // on a video: matching cover item in media[]
cover_url?: string; // on a video: URL of the matching cover image
covers_video_media_index?: number; // on a cover: matching video item in media[]
covers_video_url?: string; // on a cover: URL of the matching video file
url: string; // CDN/proxy URL (images via wsrv.nl; video via igmedia.1322.io)
width?: number;
height?: number;
created_at: string; // ISO-8601 UTC
}
Field notes
- •
is_collab/collab_with: Set when the post is a collab (a coauthor is present, or the owner differs from the tracked account).collab_withlists the other accounts, excluding the tracked one. - •
is_pinned: True when the tracked account has pinned this post to its profile. - •
is_paid_partnership: Paid / branded-content marker reported by Instagram. - •
location: Place tag from the post when present (name, optionallat/lng). Both mobile and web API shapes are supported. - •
mentionsnow also includes coauthor usernames even when they are not @-mentioned in the caption. - • Compatibility:
is_collab,collab_with,is_pinned,is_paid_partnership, andlocationare new optional fields. Existing clients are unaffected (non-breaking).
News Feed API & WebSocket
Real-time aggregation from 18 major news sources. Articles are processed immediately upon detection with full text extraction, media, and categorization. Delivered via per-server WebSocket streams.
Quick links
Base URLs
REST API Base
https://newsfeed.1322.ioWebSocket Endpoint
Format
wss://newsfeed.1322.io/{ws_path}?key={ws_key}Path and WS key are provided in your dashboard configuration (e.g. /news_459f182...).
Authentication
All endpoints require the X-Api-Key header with your API key.
WebSocket: Connect with your API key via the key= query parameter.
Rate limit
Per-key rate limits apply. Standard HTTP status codes (401, 403, 429) are used for errors.
Available Feeds (16)
Management API
Dashboard
GET /v1/dashboardReturns full dashboard data including subscribed feeds, service status, and WebSocket connection info. Authentication required.
curl "https://newsfeed.1322.io/v1/dashboard" \
-H "X-Api-Key: YOUR_API_KEY"
{
"status": "ok", "feeds": ["BBC News", "NYPost", "Bloomberg"], "current": 3, "max_feeds": 18, "ws_path": "/v1/ws", "ws_key": "your_ws_key"
}
Subscribe to Feed
POST /v1/subscribeSubscribe to a news feed to receive articles via WebSocket. Send the feed name in the JSON body. Authentication required.
curl -X POST "https://newsfeed.1322.io/v1/subscribe" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{"feed": "BBC News"}'
{
"status": "ok", "feed": "BBC News", "feeds": ["BBC News", "NYPost", "Bloomberg"], "current": 3, "max_feeds": 18
}
Unsubscribe from Feed
POST /v1/unsubscribeUnsubscribe from a news feed. Send the feed name in the JSON body. Authentication required.
curl -X POST "https://newsfeed.1322.io/v1/unsubscribe" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{"feed": "BBC News"}'
{
"status": "ok", "feed": "BBC News", "feeds": ["NYPost"], "current": 1, "max_feeds": 18
}
WebSocket Connection
WSS /{ws_path}Connect to the real-time article stream using your per-server WebSocket path and key (from your dashboard). Articles from all subscribed feeds are delivered as JSON messages.
// ws_path and ws_key are from your dashboard config (e.g. GET /v1/dashboard)
const ws = new WebSocket("wss://newsfeed.1322.io/{ws_path}?key={ws_key}");
ws.onopen = () => {
console.log("Connected to News Feed stream");
};
ws.onmessage = (event) => {
const article = JSON.parse(event.data);
console.log(`[${article.feed}] ${article.title}`);
};
ws.onclose = () => {
console.log("Disconnected, reconnecting...");
};
WS Data Types
Complete data types delivered via the News Feed WebSocket stream. Each article event contains the full payload below.
export interface WebSocketNewsFeedPayload {
feed: string; // Provider: "BBC News" | "NYPost" | "Fox News" | ...
guid: string; // Unique article ID (typically URL hash)
url: string; // Full article URL
title: string;
publish_time: string; // ISO-8601
modified_time?: string;
primary_category: string;
categories: string[];
author: string;
keywords: string[];
description: string;
summary: string;
media: NewsMediaAttachment[];
full_text: string;
language?: string;
copyright?: string | null;
_event_type: "LIVE_POST";
_sent_time: string; // Dispatch timestamp
}
export interface NewsMediaAttachment {
url: string; // Visual asset URL
type: "image" | "video";
caption?: string;
}
Field notes
- •
feed: The news source name (e.g. "BBC News", "NYPost"). Matches the feed names in the Available Feeds list. - •
guid: Unique article identifier. Use this for deduplication. - •
full_text: Complete extracted article body text. - •
_event_type: Always"LIVE_POST"for real-time article events. - •
_sent_time: ISO-8601 timestamp of when 1322 dispatched the article.
{
"feed": "BBC News", "guid": "https://www.bbc.com/news/videos/cg43xevpvw5o#0", "url": "https://www.bbc.com/news/videos/cg43xevpvw5o", "title": "Flooded streets and tangled power lines", "publish_time": "2025-10-29T04:52:35+00:00", "primary_category": "News", "categories": ["News", "World"], "author": "BBC", "keywords": ["hurricane", "caribbean", "damage"], "summary": "The strongest storm to hit the nation...", "media": [
{
"url": "https://ichef.bbci.co.uk/news/1024/...", "type": "image", "caption": "Flooded streets..."
}
], "full_text": "Full article body text here...", "_event_type": "LIVE_POST", "_sent_time": "2025-10-29T05:35:21.711178+00:00"
}
YouTube Events architecture
The 1322 YouTube tracker uses a multi-stage event model to provide initial speed signals followed by visual upgrades.
Event Lifecycle
New Upload (type: "upload")
Triggered immediately upon detection. Contains primary channel/video info and initial thumbnails.
Thumbnail Upgrade (type: "upgrade")
Sent when a higher quality thumbnail becomes available on YouTube servers. Replace the initial image with this URL.
Deletion (type: "deletion")
Sent when a previously detected video is removed or made private. Contains the video and channel info at time of deletion.
export type YouTubeTrackerMessage =
| UploadMessage
| UpgradeMessage
| DeletionMessage;
export interface UploadMessage {
type: "upload";
subtype: "video" | "short";
channel: {
id: string | null;
name: string;
url: string | null;
};
video: {
id: string;
url: string;
title: string | null;
metadata?: {
duration_seconds?: number;
category?: string;
};
};
images: {
seed: string | null;
chosen: string | null; // Best available thumb
};
}
export interface UpgradeMessage {
type: "upgrade";
upgrade: {
kind: "image";
video_id: string;
url: string; // New HQ thumbnail
};
}
export interface DeletionMessage {
type: "deletion";
video: {
id: string; // The deleted video's ID
url: string; // Original video URL
};
channel: {
id: string | null;
name: string;
url: string | null;
};
}
Binance Square API & WebSocket
Real-time tracking of Binance Square creators. Monitors posts, pin changes, polls, quotes, media, sentiment (bullish/bearish), coin pairs, and engagement metrics. Delivered via WebSocket with per-tenant isolation.
Quick links
Base URLs
REST API Base
https://binance.1322.ioWebSocket Endpoint
Format
wss://binance.1322.io/{ws_path}?key={ws_key}Path and WS key are provided in your dashboard configuration.
Authentication
All endpoints require the X-Api-Key header with your API key.
WebSocket: Connect with your API key via the key= query parameter.
Rate limit
Per-key rate limits apply. Standard HTTP status codes (401, 403, 429) are used for errors.
Management API
Dashboard
GET /v1/dashboardReturns full dashboard data including tracked accounts, service status, and WebSocket connection info. Authentication required.
curl "https://binance.1322.io/v1/dashboard" \
-H "X-Api-Key: YOUR_API_KEY"
{
"status": "ok", "tracked": ["CZ_Binance", "binaborz"], "current": 2, "max_tracked": 10, "ws_path": "/v1/ws", "ws_key": "your_ws_key"
}
Track Account
POST /v1/trackAdd a Binance Square user to your tracking list. Send the username in the JSON body. Authentication required.
curl -X POST "https://binance.1322.io/v1/track" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{"username": "CZ_Binance"}'
{
"status": "ok", "tracked": {
"username": "CZ_Binance", "square_uid": "123456789", "display_name": "CZ", "avatar_url": "https://...", "added_at": "2025-01-15T12:00:00Z"
}
}
Untrack Account
POST /v1/untrackRemove a Binance Square user from your tracking list. Send the username in the JSON body. Authentication required.
curl -X POST "https://binance.1322.io/v1/untrack" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{"username": "CZ_Binance"}'
{
"status": "ok", "account": "CZ_Binance", "tracked": ["binaborz"], "current": 1, "max_tracked": 10
}
WebSocket Connection
WSS /{ws_path}Connect to the real-time post stream using your per-server WebSocket path and key (from your dashboard). Posts and pin changes from all tracked accounts are delivered as JSON messages.
// ws_path and ws_key are from your dashboard config (e.g. GET /v1/dashboard)
const ws = new WebSocket("wss://binance.1322.io/{ws_path}?key={ws_key}");
ws.onopen = () => {
console.log("Connected to Binance Square stream");
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === "new_post") {
console.log(`[${data.post.username}] ${data.post.text}`);
} else if (data.type === "pin_change") {
console.log(`Pin change for ${data.pin.username}`);
}
};
ws.onclose = () => {
console.log("Disconnected, reconnecting...");
};
WS Data Types
Complete data types delivered via the Binance Square WebSocket stream. Each event contains the full payload below.
export interface BinancePost {
id: string;
username: string;
display_name?: string;
avatar_url?: string;
square_uid?: string;
content_type?: string; // "post" | "video" | "space" | "article"
title?: string;
text?: string;
web_link?: string;
share_link?: string;
is_reply: boolean;
parent_id?: string;
// Engagement
reply_count?: number;
like_count?: number;
comment_count?: number;
share_count?: number;
view_count?: number;
// Sentiment
tendency?: string; // "bullish" | "bearish" | ""
bullish_ratio?: number;
bearish_ratio?: number;
coin_pairs?: string[]; // ["BTCUSDT", "ETHUSDT"]
hashtags?: string[];
mentions?: string[];
// Rich content
media?: MediaItem[];
poll?: PostPoll;
quote?: PostQuote; // Embedded quote/repost
reply_to?: PostQuote; // Parent post context
translation?: PostTranslation;
live_replay?: SpaceLiveReplay;
resolved_links?: PostResolvedLink[];
published_at: string; // ISO 8601
detected_at: string; // ISO 8601
}
// Every WS frame is { type, data }. Branch on type.
export type WsEventType = "binance.post" | "binance.pin.update";
export interface WsEnvelope {
type: WsEventType;
data: BinancePost | PinUpdate;
}
export interface PinUpdate {
username: string;
display_name?: string;
avatar_url?: string;
square_uid?: string;
added?: BinancePost[]; // newly pinned posts
removed?: BinancePost[]; // unpinned posts
removed_ids?: string[];
note?: string; // hint only; confirm on Square if needed
detected_at: string; // RFC3339 event time
}
Field notes
- •
content_type: The type of post,"post","video","space", or"article". - •
tendency: Sentiment indicator,"bullish","bearish", or empty string. - •
coin_pairs: Array of trading pairs mentioned (e.g.["BTCUSDT", "ETHUSDT"]). - •
pin: Present onpin_changeevents. Contains arrays of added/removed pinned posts. - •
detected_at: ISO-8601 timestamp of when 1322 first detected the post.