Each user connects their own account. Every call carries both identities — the agent and the person it is acting for — so the agent can never reach past what that individual can already do.
Tokens live in the vault and attach server-side at call time. The agent holds a session, not a secret, and revoking access does not mean rotating a key.
Who asked, which agent acted, which action ran, and the verdict that let it through — one audit trail across every integration, not one per vendor.
Each action is granted on its own. An agent allowed to read is not thereby allowed to write, and the scope beside each row is what the acting user must have connected for it to run at all.
twitter_add_list_memberWRITEAdd one account to a list the connected account owns. Reversible by 'Remove an account from a list'. Being added to a PUBLIC list is visible to the account added, which is why creating a list defaults to private.
twitter_append_media_uploadWRITESend one chunk of a chunked upload — step 2 of 5, repeated once per chunk. Chunks are base64-encoded (a tool call is JSON, so there is no other way to carry bytes) and must start at segment_index 0 and be consecutive; X assembles them in index order at finalize, so a gap is discovered there rather than here. Each chunk may decode to at most 4 MB and segment_index caps at 999. Agentic Fabriq checks the DECODED size, not the base64 string, because base64 is a third larger and a check on the string would let an over-limit file through.
twitter_create_bookmarkWRITEBookmark one post for the connected account. PRIVATE — a bookmark is visible to nobody but the account owner — reversible by 'Remove a bookmark', and about $0.005. This is the private alternative to a public like, and it is what to use for 'monitor this topic and keep the good ones'.
twitter_create_bookmark_folderWRITECreate a bookmark folder on the connected account. Private: a folder is not published and nobody else can see it. X publishes NO delete for folders, which is worth knowing before creating one — a folder made by mistake has to be removed by a person in the X app.
twitter_create_draft_articleWRITEWrite a long-form X Article DRAFT. A draft is visible only to the account owner and publishes nothing, which is what makes it the safe half of the pair: an agent that writes and a human that publishes is the right division of labour for something with no character ceiling.
twitter_create_listWRITECreate a list owned by the connected account, at about $0.010. PRIVATE BY DEFAULT, which is not X's own default: a public list publishes its name, its description and every account in it, and 'accounts our agent is monitoring' is not something to publish by accident.
twitter_create_media_subtitlesWRITEAttach an uploaded subtitle track to an uploaded video. TWO uploads are involved and confusing them is the usual mistake: media_id is the VIDEO, subtitle_media_id is the .srt or .vtt file uploaded separately with media_category=subtitles. The video's category is spelled differently here than on the upload endpoints — TweetVideo and AmplifyVideo, not tweet_video. Reversible by Remove subtitles from a video, which ships alongside it.
twitter_create_postWRITEDESTRUCTIVE — publish a post to X as the connected account. The post is public the moment it is created and can be seen, screenshotted and reposted by anyone; deleting it afterwards does not retract those copies. X bills the app owner about $0.015 per post, or $0.20 if the post contains a link. Quote posting, promoted-only (nullcast) posting and media attachments are not available.
twitter_delete_bookmarkWRITERemove one bookmark from the connected account. The inverse of 'Bookmark a post'. Private and reversible, so it is not marked destructive.
twitter_delete_listWRITEDESTRUCTIVE — delete one list the connected account owns. X publishes no restore endpoint, so this is a one-way door. It is bounded to a single owned list and rebuildable from a prior 'Read a list's members' call, which is the same reasoning that lets deleting a post exist as the remedy for publishing one. Read the members first if the set matters.
twitter_delete_media_subtitlesWRITERemove one subtitle track, by language, from an uploaded video. The inverse of Add subtitles to a video, so a track attached under the wrong language code can be corrected without re-uploading the video. Not marked destructive: the subtitle file itself is untouched and can be re-attached.
twitter_delete_postWRITEDESTRUCTIVE — delete one post published by the connected account. There is no undo, and deleting does not retract screenshots, reposts or anything already scraped. X uses the same tweet.write permission for publishing and deleting, so granting this action separately is the only separation Agentic Fabriq can offer.
twitter_finalize_media_uploadWRITEClose a chunked upload and ask X to assemble it — step 3 of 5. READ THE ANSWER CAREFULLY, because the rule is easy to get backwards: if the response has NO processing_info the media is ready and must not be polled. If it has one, wait check_after_secs and call Check media upload status. Attaching a media id before its state is succeeded publishes a post whose media will not play, and the post is public by then.
twitter_follow_listWRITEFollow a list as the connected account. This takes the list permission, NOT the follows permission — X's 2026-04-20 removal took following ACCOUNTS off every self-serve tier, and following a LIST is a different capability, which is why this is available and following an account is not.
twitter_get_activity_subscriptionsREADList the activity webhook subscriptions registered on this X app — a POSTURE READ, and the only member of the Activity family Agentic Fabriq ships. It lets an agent report that the app is already streaming this account's activity somewhere, and to where, without being able to add or remove a destination: creating and deleting a subscription designates a caller-chosen callback URL that keeps delivering after the agent stops, and is excluded. The same asymmetry as blocked accounts — the read ships so an agent can see the state, the write does not so it cannot set it.
twitter_get_blocked_usersREADList the accounts the connected account has blocked, so an agent can avoid engaging with them. READ ONLY: nothing in Agentic Fabriq can block or unblock, because unblocking re-opens a channel a human closed deliberately for a reason the API cannot report.
twitter_get_bookmark_foldersREADThe connected account's bookmark folders. Bookmarks and their folders are PRIVATE — visible to nobody but the account owner, and invisible to the accounts whose posts are saved.
twitter_get_bookmarksREADList the connected account's bookmarks. Bookmarks are PRIVATE — visible to nobody but the account owner — and X refuses this call for any account other than the connected one. About $0.005 per post.
twitter_get_bookmarks_by_folderREADThe posts saved in one bookmark folder, by folder id from List bookmark folders. Private to the connected account.
twitter_get_communityREADRead one X Community by id. About $0.005.
twitter_get_followed_listsREADList the lists one account follows. About $0.005 per list.
twitter_get_followersREADList the accounts following one account. EXPENSIVE: X bills about $0.010 per account returned and this paginates over the whole follower graph, so walking a 50,000-follower account to the end costs about $500. The page size is clamped to 100 and defaults to 25; the number of pages is the caller's choice.
twitter_get_followingREADList the accounts one account follows. Same $0.010-per-account cost and the same clamps as reading followers. FOLLOWING and UNFOLLOWING are not available: X removed them from every self-serve tier on 2026-04-20, and a follow is a public statement of affiliation Agentic Fabriq will not make for a customer.
twitter_get_home_timelineREADRead the connected account's own reverse-chronological home timeline — the feed its owner sees. This is OWNED data, so X prices it at about $0.001 per post instead of $0.005. It is the basis of every digest and briefing workflow, and X refuses the call for any account other than the connected one.
twitter_get_liked_postsREADList the posts one account has liked, at about $0.001 each. Availability is unconfirmed for the same reason as 'Read who liked a post'.
twitter_get_liking_usersREADList the accounts that liked one post, at about $0.001 each. AVAILABILITY IS UNCONFIRMED: X removed like WRITES from every self-serve tier on 2026-04-20 and its wording ("Likes ... via the API") did not clearly distinguish reads. Its pricing page still lists a Likes read price, but there are open reports of this endpoint returning an empty list for posts with confirmed likes — so an empty answer may be the endpoint rather than the post.
twitter_get_listREADRead one list's name, description, owner, visibility and member and follower counts. About $0.005.
twitter_get_list_followersREADList the accounts following one list. About $0.010 per account.
twitter_get_list_membersREADList the accounts in one list. Also the only way to reconstruct a list after it is deleted, because X publishes no restore endpoint — read this before deleting anything. About $0.010 per account.
twitter_get_list_membershipsREADList the lists one account is a member of. About $0.005 per list.
twitter_get_list_postsREADRead the posts in one list — a curated feed the customer already maintains, at about $0.005 per post with NO search cost. Strictly cheaper and more precise than paying search to approximate the same set.
twitter_get_meREADReturn the X account this connection authenticates as, with its numeric id, handle, display name, creation date and public metrics. START HERE: the numeric id is what most other actions require; they do not accept an @handle. Cheapest call X offers, but still billed at about $0.005.
twitter_get_mediaREADRead one uploaded media object by its media KEY — the 13_1880... form from an upload response or a post lookup, not the numeric media id. Reads take tweet.read rather than media.write, so an agent can be allowed to inspect media without being able to upload any.
twitter_get_media_by_keysREADRead up to 100 media objects in ONE request. Same reasoning as the batch post and account lookups: X bills per resource rather than per request, so a hundred keys in one call cost what a hundred calls would and consume one unit of the 900-per-15-minute window every connection on the app shares, instead of a hundred.
twitter_get_media_upload_statusREADPoll a finalized upload until X reports succeeded or failed — step 4 of 5, and only when finalize returned a processing_info. Wait the check_after_secs X gives between calls: video and GIF assembly usually takes 30-120 seconds, and polling faster earns a 429 shared by every connection on the same X app. failed is terminal — the media id cannot be revived and the file has to be uploaded again from the start.
twitter_get_mentionsREADList posts mentioning one account, newest first. Billed at about $0.005 per post read.
twitter_get_muted_usersREADList the accounts the connected account has muted. A mute is private and invisible to the muted account, which is what makes reading the list safe. About $0.001 per account.
twitter_get_newsREADRead one news story X surfaces, by id.
twitter_get_notes_writtenREADList the Community Notes the connected account has written. READ ONLY, and deliberately so: WRITING a Community Note is a public assertion that somebody else's post is misleading, permanently attached to their post and fed into X's ranking, with no bounded remedy. Agentic Fabriq exposes no action that writes one.
twitter_get_owned_listsREADList the lists one account owns. This is the read that produces the list id every other list action needs — without it the list family is unreachable for anyone who does not already know an id. About $0.005 per list.
twitter_get_personalized_trendsREADRead the trends X personalises for the connected account. Owned data — X resolves the account from the token, so this cannot be pointed at anybody else.
twitter_get_pinned_listsREADList the lists the connected account has pinned to its profile. X returns the whole set; there is no pagination on this endpoint.
twitter_get_postREADRead one post by its numeric id, including text, author, language, referenced posts and public metrics. To read MORE than one, use 'Read posts by id (batch)' — it reads up to 100 in a single request at the same per-post price. Billed at about $0.005.
twitter_get_post_counts_recentREADCount how many posts from the last seven days match a search, WITHOUT reading any of them. Flat $0.005 per request rather than $0.005 per post, so it prices a query before it is paid for: a search matching 4,000 posts costs about $20 to read and $0.005 to count. Run this before a broad search.
twitter_get_posts_by_idsREADRead up to 100 posts in ONE request. Identical $0.005 per post, but one request instead of a hundred against the 900-per-15-minute window every connection on the same X app shares. Unreadable ids (deleted, protected) come back in an errors array while the rest still return — a partial answer, not a failure.
twitter_get_posts_eligible_for_notesREADList the posts X considers eligible for a Community Note. Read-only for the same reason as reading notes written.
twitter_get_quoted_postsREADList the posts that quote one post — the half of amplification that carries commentary. Quote POSTING was removed from every self-serve tier on 2026-04-20, which makes quote READING the only way to see what people said when they amplified something. Billed at about $0.005 per post.
twitter_get_reposted_byREADList the accounts that reposted one post. This is not reachable any other way: X's 2026-05-04 search reindex stopped returning retweets in keyword search results, so no search query can answer it. Billed at about $0.010 per account returned.
twitter_get_repostsREADThe repost POSTS of one post — not the accounts that made them. Different endpoint and different answer from Read who reposted a post, which returns account objects: this returns Post objects, so each repost carries its own id, timestamp and metrics. It is the only one of the two that lets an agent reply to a specific repost or say WHEN the amplification happened. Billed per post returned, about $0.005.
twitter_get_reposts_of_meREADList posts that repost the connected account's own posts. Owned data, so about $0.001 per post. Takes no account id at all — X resolves the account from the token, which is what makes it impossible to point at anybody else.
twitter_get_spaceREADRead one X Space by id. About $0.005.
twitter_get_space_postsREADRead the posts shared inside one X Space. About $0.005 per post.
twitter_get_space_ticket_buyersREADThe accounts that bought tickets to a paid Space. COMMERCIAL DATA ABOUT NAMED INDIVIDUALS: every row is a person who paid the customer money. X returns it only to the account that hosted the Space, so the recipient is already party to the transaction, but it is the most sensitive read in the Spaces family and an agent should say what it intends to do with the list before fetching it. Billed at the account rate, about $0.010 each, so the page size defaults low.
twitter_get_spaces_by_creatorsREADRead the Spaces created by up to 100 accounts in one request. About $0.005 per Space.
twitter_get_spaces_by_idsREADRead up to 100 X Spaces by id in ONE request, with state, title, host and speaker ids, participant count and scheduled start. About $0.005 per Space.
twitter_get_trendsREADRead what is trending in one place, identified by its Yahoo 'Where On Earth' id — 1 is worldwide. One flat $0.010 request regardless of how many trends come back.
twitter_get_userREADLook up one X account by @handle and return its numeric id, display name, description, creation date and public metrics. To resolve MORE than one handle, use 'Look up accounts by handle' instead — it does up to 100 in a single request at the same per-account price. Billed at about $0.010.
twitter_get_user_affiliatesREADThe accounts affiliated with a business account — the badge relationship X shows on employee profiles. A cheap public read, billed at about $0.010 per account returned.
twitter_get_user_postsREADList one account's posts, newest first, with text, creation time, author, conversation id and public metrics. Billed at about $0.005 per post read, so a wide page size is a real cost.
twitter_get_users_by_idsREADRead up to 100 accounts by numeric id in ONE request. Same $0.010 per account as reading them individually, but one request instead of a hundred against a 900-per-15-minute window that every connection on the same X app shares. Prefer this whenever more than one account is needed.
twitter_get_users_by_usernamesREADResolve up to 100 @handles to accounts in ONE request. This is the fix for X's most common ergonomic trap: nearly every action needs a NUMERIC user id and humans supply handles. Billed at about $0.010 per account.
twitter_hide_replyWRITEHide one reply to a post the connected account authored. The safest write X has left on self-serve: X refuses it unless the parent post belongs to this account, so it cannot touch a stranger's conversation; it is fully reversible by 'Un-hide a reply'; and it carries its own permission, so reply moderation can be granted WITHOUT granting the ability to publish. Hiding is not deleting — the reply still exists and its author can still see it.
twitter_initialize_media_uploadWRITEReserve a media id and start a CHUNKED upload — step 1 of 5: initialize, then append once per chunk, then finalize, then check status if X says it is processing, then pass the id to Publish a post. Give the file's real byte count and MIME type; X uses them to pre-allocate. Categories decide the limits: tweet_image 5 MB, tweet_gif 15 MB, tweet_video and amplify_video 512 MB. The DM categories are refused — Agentic Fabriq ships no Direct Message operation, so media staged for one could only be sent by something outside Agentic Fabriq, with no audit row. additional_owners and shared are refused too: both grant other accounts a standing right over this media that Agentic Fabriq cannot revoke. For a single image under 5 MB use Upload media instead — one call, no chunking.
twitter_mute_userWRITEMute one account for the connected account. A mute is PRIVATE — invisible to the muted account, sending no signal — and fully reversible by 'Unmute an account'. Not marked destructive for those reasons, but it silences a source the account owner may be relying on, so grant it deliberately. BLOCKING is not available: a block is visible to the blocked account and is a security decision Agentic Fabriq will not make for a customer.
twitter_pin_listWRITEPin a list to the connected account's profile. Reversible by 'Unpin a list'.
twitter_publish_articleWRITEDESTRUCTIVE — publish a long-form Article draft as the connected account. Public immediately, with an unbounded audience and NO character ceiling, which makes it the largest blast radius Agentic Fabriq exposes on X. There is no undo: X publishes no unpublish endpoint, and deleting the Article afterwards would not retract screenshots or reposts. Everything true of publishing a post is true here with more text behind it.
twitter_remove_list_memberWRITERemove one account from a list. The inverse of 'Add an account to a list'.
twitter_repostWRITEDESTRUCTIVE — repost an existing post to the connected account's own timeline. It republishes content this account did not write, which is a public endorsement; 'Retract a repost' removes this account's copy but not the reposts of the repost, nor the screenshots. AVAILABILITY IS UNCONFIRMED: X's 2026-04-20 removal named Following, Likes and Quote-Posts and did not name reposts, but reposts are the obvious fourth member of that group. If X has swept it too, this returns an HTTP 403.
twitter_search_communitiesREADSearch X Communities by name. About $0.005 per Community returned.
twitter_search_newsREADSearch the news stories X surfaces. Useful for research before drafting.
twitter_search_recentREADSearch the LAST SEVEN DAYS of posts using X's search operator language. Older posts need full-archive search, which is Enterprise-only from $42,000/month and is not available. Billed at about $0.005 per post returned — run 'Count recent posts' first to find out how many that will be. Note that since X's 2026-05-04 search reindex, retweets are no longer returned in keyword search at all.
twitter_search_spacesREADSearch X Spaces by title, filtered to live, scheduled or all. About $0.005 per Space returned.
twitter_search_usersREADFind accounts by name or topic without knowing the exact handle. Billed at about $0.010 per account returned — DOUBLE a post read — so the default page size is 25 rather than X's 100.
twitter_set_media_metadataWRITEAttach ALT TEXT and content warnings to uploaded media, before it is posted. Alt text is the reason this exists: media posted without it is invisible to anyone using a screen reader, so an agent that can post images and cannot describe them publishes inaccessible content on the customer's account by default. Call it BEFORE attaching the id to a post — once the post is public, the alt text a reader missed is not recoverable. sensitive_media_warning is disclosure and can be set deliberately. X's advertising and distribution controls — geo and domain restrictions, audience policy, sticker and management info — are not exposed.
twitter_unfollow_listWRITEUnfollow a list. The inverse of 'Follow a list'.
twitter_unhide_replyWRITEUn-hide a reply this account previously hid. The inverse of 'Hide a reply', on the same endpoint and under the same permission.
twitter_unmute_userWRITEUnmute one account. The inverse of 'Mute an account', shipped alongside it.
twitter_unpin_listWRITEUnpin a list from the connected account's profile. The inverse of 'Pin a list'.
twitter_unrepostWRITERetract a repost the connected account made. The inverse of 'Repost a post', shipped alongside it. Takes the ORIGINAL post's id, not the id of the repost.
twitter_update_listWRITERename or re-describe a list, or change its visibility. Note that switching a list from private to public publishes it and everyone in it; that is reversible by the same action, but the exposure in between is not.
twitter_upload_mediaWRITEUpload an image or a subtitle file in ONE call, with no chunking. Images only up to 5 MB, plus .srt and .vtt subtitle files. X's own specification advertises video and GIF on this endpoint and the endpoint rejects them in practice, which is why the chunked path exists — Agentic Fabriq refuses them here locally rather than letting X answer with a billed error that does not say what to do instead. The media argument is the file's bytes, base64-encoded. DM categories, additional_owners and shared are refused.
Put X behind one governed endpoint.
Same permissions, same audit trail, whatever else you connect next.