Posts
Create a post with words, images, a video or a GIF; read one post; delete the account's own; pin and unpin.
Early access. Tell us what you're building and we'll set you up. Contact us
Create A Post#
POST /posts (accounts.write, Idempotency-Key required) posts from the
account's own X. JSON for words only:
curl -sS -X POST "https://api.lempile.com/posts" \
-H "X-API-KEY: $LEMPILE_API_KEY" \
-H "Idempotency-Key: launch-post-1" \
-H "Content-Type: application/json" \
-d '{ "account_id": "janedemo", "text": "Shipping today." }'multipart/form-data for pictures or a video:
curl -sS -X POST "https://api.lempile.com/posts" \
-H "X-API-KEY: $LEMPILE_API_KEY" \
-H "Idempotency-Key: launch-post-2" \
-F account_id=janedemo \
-F "text=Before and after" \
-F attachments=@before.png \
-F attachments=@after.png{ "object": "PostCreated", "provider": "X", "post_id": "1850000000000000001" }text: required, up to 3,000 characters. More than 280 needs X Premium on the account: without it X keeps the post in its box, and the answer is422 errors/not_sentwith that reason indetail.attachments(multipart only): up to 4 images (JPEG, PNG, WebP or GIF, 8 MB each), or one MP4 of up to 50 MB on its own.gif: a GIF from X's own GIF search,{ "query": "ship it", "url": "…" }(a JSON string in a form field).urlis a result ofGET /posts/gifs; the browser searches X again and refuses if that GIF is gone. Not with attachments.dry_run: true: everything but the Post button, answered200{ "object": "PostDryRun", "not_sent": true }.dry_runis part of the request, so the real post needs a newIdempotency-Key.
To reply, use POST /posts/{post_id}/comments. There is no
quote parameter.
Posts are paced: at least 45 seconds after the account's last write, 70 writes
in 24 hours. The request waits up to 140 seconds; past that it answers
504 errors/timeout and the receipt says what
happened.
Search X's GIFs#
GET /posts/gifs?account_id=&q=&limit= (accounts.read): X's GIF search as
the composer shows it (q 2–40 characters, limit 1–24, default 12).
Nothing is typed into a post.
{ "object": "GifList", "provider": "X", "query": "ship it",
"items": [{ "url": "https://media1.giphy.com/media/demoGifId/giphy.gif", "title": "Ship it", "width": 498, "height": 280 }] }Read A Post#
GET /posts/{post_id}?account_id= (accounts.read):
{
"object": "Post", "provider": "X", "id": "1850000000000000001",
"author": "Jane Demo",
"author_details": { "id": "janedemo", "public_identifier": "janedemo", "profile_url": "https://x.com/janedemo", "profile_picture_url": "https://pbs.twimg.com/profile_images/0/demo.jpg" },
"date": "2026-11-06T09:12:00.000Z", "text": "Shipping today.",
"share_url": "https://x.com/janedemo/status/1850000000000000001",
"reply_counter": 3, "comment_counter": 3, "reaction_counter": 12, "repost_counter": 1,
"quote_counter": 0, "bookmark_counter": 2, "impressions_counter": 840, "user_reacted": false
}quote_counter, bookmark_counter and impressions_counter are null when
the post's page was read instead of X's own data.
Delete A Post#
DELETE /posts/{post_id}?account_id= (accounts.write) deletes one of the
account's own posts or replies through X's menu on it, then opens it again to
check it's gone: 200 { "object": "PostDeleted", "post_id": "…" }.
403 errors/not_own_post: someone else's post. Nothing was deleted.404 errors/post_not_found: missing or already deleted.422 errors/delete_unavailable: X's menu, its Delete item or the confirmation didn't show. Nothing was deleted.504 errors/timeout: Delete was confirmed but the post may still be there. Open it before trying again.
Pin And Unpin#
POST /accounts/{account_id}/posts/{status_id}/pin and /unpin
(accounts.write, optional Idempotency-Key, optional body
{ "dry_run": true }). X keeps one pinned post, so a new pin replaces the old
one. The answer comes once the profile shows it:
{ "object": "PostPin", "provider": "X", "status": "pinned", "status_id": "1850000000000000001",
"previous_pinned_id": "1840000000000000002", "already": false }status is pinned, unpinned, already_pinned or already_unpinned. Only
the account's own posts (400 errors/not_own_post); 502 errors/pin_unconfirmed
means check the profile before trying again.
Was this page helpful?