Twitter / X API

Schedule and automate Twitter/X posts with SocialSyncerAPI — Tweets, threads, images, videos, GIFs, and polls.

Quick Reference

Before You Start

Twitter has a strict 280 character limit for free accounts. URLs always count as 23 characters regardless of actual length. Emojis count as 2 characters. Use customContent to provide a shorter Twitter version for cross-platform posts.

Quick Start

Post a tweet in under 60 seconds:

Python (httpx)

import httpx

resp = httpx.post(
    "https://api.socialsyncerapi.com/v1/posts",
    headers={"Authorization": "Bearer sk_your_api_key"},
    json={
        "content": "Hello from SocialSyncerAPI!",
        "platforms": [
            {"platform": "twitter", "accountId": "YOUR_ACCOUNT_ID"}
        ],
        "publishNow": True
    }
)
print("Tweet posted!", resp.json()["id"])

curl

curl -X POST https://api.socialsyncerapi.com/v1/posts \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Hello from SocialSyncerAPI!",
    "platforms": [
      {"platform": "twitter", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    "publishNow": true
  }'

Node.js (fetch)

const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_your_api_key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    content: "Hello from SocialSyncerAPI!",
    platforms: [
      { platform: "twitter", accountId: "YOUR_ACCOUNT_ID" }
    ],
    publishNow: true
  })
});
const data = await resp.json();
console.log("Tweet posted!", data.id);

Content Types

Text Tweet

A simple text-only tweet. Keep it under 280 characters for free accounts.

Text Tweet — Python

import httpx

resp = httpx.post(
    "https://api.socialsyncerapi.com/v1/posts",
    headers={"Authorization": "Bearer sk_your_api_key"},
    json={
        "content": "Just shipped a new feature. Check it out!",
        "platforms": [
            {"platform": "twitter", "accountId": "YOUR_ACCOUNT_ID"}
        ],
        "publishNow": True
    }
)

Text Tweet — curl

curl -X POST https://api.socialsyncerapi.com/v1/posts \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Just shipped a new feature. Check it out!",
    "platforms": [
      {"platform": "twitter", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    "publishNow": true
  }'

Text Tweet — Node.js

const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_your_api_key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    content: "Just shipped a new feature. Check it out!",
    platforms: [
      { platform: "twitter", accountId: "YOUR_ACCOUNT_ID" }
    ],
    publishNow: true
  })
});

Image Tweet

Attach up to 4 images per tweet. JPEG, PNG, WebP, and GIF formats are supported.

Image Tweet — Python

import httpx

resp = httpx.post(
    "https://api.socialsyncerapi.com/v1/posts",
    headers={"Authorization": "Bearer sk_your_api_key"},
    json={
        "content": "Check out this photo!",
        "mediaItems": [
            {"type": "image", "url": "https://cdn.example.com/photo.jpg"}
        ],
        "platforms": [
            {"platform": "twitter", "accountId": "YOUR_ACCOUNT_ID"}
        ],
        "publishNow": True
    }
)

Image Tweet — curl

curl -X POST https://api.socialsyncerapi.com/v1/posts \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Check out this photo!",
    "mediaItems": [
      {"type": "image", "url": "https://cdn.example.com/photo.jpg"}
    ],
    "platforms": [
      {"platform": "twitter", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    "publishNow": true
  }'

Image Tweet — Node.js

const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_your_api_key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    content: "Check out this photo!",
    mediaItems: [
      { type: "image", url: "https://cdn.example.com/photo.jpg" }
    ],
    platforms: [
      { platform: "twitter", accountId: "YOUR_ACCOUNT_ID" }
    ],
    publishNow: true
  })
});

Video Tweet

Attach a single video per tweet. MP4 and MOV formats, up to 512 MB, max 140 seconds.

Video Tweet — Python

import httpx

resp = httpx.post(
    "https://api.socialsyncerapi.com/v1/posts",
    headers={"Authorization": "Bearer sk_your_api_key"},
    json={
        "content": "New product demo",
        "mediaItems": [
            {"type": "video", "url": "https://cdn.example.com/demo.mp4"}
        ],
        "platforms": [
            {"platform": "twitter", "accountId": "YOUR_ACCOUNT_ID"}
        ],
        "publishNow": True
    }
)

Video Tweet — curl

curl -X POST https://api.socialsyncerapi.com/v1/posts \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "New product demo",
    "mediaItems": [
      {"type": "video", "url": "https://cdn.example.com/demo.mp4"}
    ],
    "platforms": [
      {"platform": "twitter", "accountId": "YOUR_ACCOUNT_ID"}
    ],
    "publishNow": true
  }'

Video Tweet — Node.js

const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_your_api_key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    content: "New product demo",
    mediaItems: [
      { type: "video", url: "https://cdn.example.com/demo.mp4" }
    ],
    platforms: [
      { platform: "twitter", accountId: "YOUR_ACCOUNT_ID" }
    ],
    publishNow: true
  })
});

Thread (Multi-Tweet)

Create Twitter threads with multiple connected tweets using platformSpecificData.threadItems. Each item becomes a reply to the previous tweet and can have its own content and media.

Note: When threadItems is provided, the top-level content field is used only for display and search purposes, it is NOT published. You must include your first tweet as threadItems[0].

Thread — Python

import httpx

resp = httpx.post(
    "https://api.socialsyncerapi.com/v1/posts",
    headers={"Authorization": "Bearer sk_your_api_key"},
    json={
        "platforms": [{
            "platform": "twitter",
            "accountId": "YOUR_ACCOUNT_ID",
            "platformSpecificData": {
                "threadItems": [
                    {
                        "content": "1/ Starting a thread about API design",
                        "mediaItems": [{"type": "image", "url": "https://cdn.example.com/image1.jpg"}]
                    },
                    {"content": "2/ First, always use proper HTTP methods..."},
                    {"content": "3/ Second, version your APIs from day one..."},
                    {"content": "4/ Finally, document everything! /end"}
                ]
            }
        }],
        "publishNow": True
    }
)

Thread — curl

curl -X POST https://api.socialsyncerapi.com/v1/posts \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "platforms": [{
      "platform": "twitter",
      "accountId": "YOUR_ACCOUNT_ID",
      "platformSpecificData": {
        "threadItems": [
          {
            "content": "1/ Starting a thread about API design",
            "mediaItems": [{"type": "image", "url": "https://cdn.example.com/image1.jpg"}]
          },
          {"content": "2/ First, always use proper HTTP methods..."},
          {"content": "3/ Second, version your APIs from day one..."},
          {"content": "4/ Finally, document everything! /end"}
        ]
      }
    }],
    "publishNow": true
  }'

Thread — Node.js

const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_your_api_key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    platforms: [{
      platform: "twitter",
      accountId: "YOUR_ACCOUNT_ID",
      platformSpecificData: {
        threadItems: [
          {
            content: "1/ Starting a thread about API design",
            mediaItems: [{ type: "image", url: "https://cdn.example.com/image1.jpg" }]
          },
          { content: "2/ First, always use proper HTTP methods..." },
          { content: "3/ Second, version your APIs from day one..." },
          { content: "4/ Finally, document everything! /end" }
        ]
      }
    }],
    publishNow: true
  })
});

Poll

Create a Twitter/X poll by providing platformSpecificData.poll. Polls are mutually exclusive with media attachments and threads.

Poll — Python

import httpx

resp = httpx.post(
    "https://api.socialsyncerapi.com/v1/posts",
    headers={"Authorization": "Bearer sk_your_api_key"},
    json={
        "content": "Which feature should we ship next?",
        "platforms": [{
            "platform": "twitter",
            "accountId": "YOUR_ACCOUNT_ID",
            "platformSpecificData": {
                "poll": {
                    "options": ["Dark mode", "New analytics", "More integrations"],
                    "duration_minutes": 1440
                }
            }
        }],
        "publishNow": True
    }
)

Poll — curl

curl -X POST https://api.socialsyncerapi.com/v1/posts \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Which feature should we ship next?",
    "platforms": [{
      "platform": "twitter",
      "accountId": "YOUR_ACCOUNT_ID",
      "platformSpecificData": {
        "poll": {
          "options": ["Dark mode", "New analytics", "More integrations"],
          "duration_minutes": 1440
        }
      }
    }],
    "publishNow": true
  }'

Poll — Node.js

const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_your_api_key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    content: "Which feature should we ship next?",
    platforms: [{
      platform: "twitter",
      accountId: "YOUR_ACCOUNT_ID",
      platformSpecificData: {
        poll: {
          options: ["Dark mode", "New analytics", "More integrations"],
          duration_minutes: 1440
        }
      }
    }],
    publishNow: true
  })
});

Reply

Use platformSpecificData.replyToTweetId to publish a tweet as a reply to an existing tweet.

Note: replyToTweetId cannot be combined with replySettings. For threads, only the first tweet replies to the target.

Reply — Python

import httpx

resp = httpx.post(
    "https://api.socialsyncerapi.com/v1/posts",
    headers={"Authorization": "Bearer sk_your_api_key"},
    json={
        "content": "Replying via SocialSyncerAPI",
        "platforms": [{
            "platform": "twitter",
            "accountId": "YOUR_ACCOUNT_ID",
            "platformSpecificData": {
                "replyToTweetId": "1748391029384756102"
            }
        }],
        "publishNow": True
    }
)

Reply — curl

curl -X POST https://api.socialsyncerapi.com/v1/posts \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Replying via SocialSyncerAPI",
    "platforms": [{
      "platform": "twitter",
      "accountId": "YOUR_ACCOUNT_ID",
      "platformSpecificData": {
        "replyToTweetId": "1748391029384756102"
      }
    }],
    "publishNow": true
  }'

Reply — Node.js

const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_your_api_key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    content: "Replying via SocialSyncerAPI",
    platforms: [{
      platform: "twitter",
      accountId: "YOUR_ACCOUNT_ID",
      platformSpecificData: {
        replyToTweetId: "1748391029384756102"
      }
    }],
    publishNow: true
  })
});

Media Requirements

Images

GIFs

Videos

Platform-Specific Data

All fields go inside platformSpecificData on the Twitter platform entry.

Constraints

What You Can't Do

These features are not available through Twitter's API:

Common Errors