API Reference

OpenTweet API Docs

Create, schedule, and publish posts to X/Twitter programmatically. Simple REST API with Bearer token auth.

Quick Start

Base URL

https://opentweet.io

Authentication

All endpoints require a Bearer token. Get your API key from .

bash
curl -H "Authorization: Bearer ot_your_api_key" \
  https://opentweet.io/api/v1/me

Rate Limits

60
requests / minute
1,000
requests / day
50
posts / bulk request

Rate limit headers included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset

Endpoints

GET/api/v1/me

Verify Connection & Check Limits

Verify your API key works and check your subscription status, daily post limits, and post counts. Call this first before scheduling or publishing.

Requires API Key

Response

json
{
  "authenticated": true,
  "subscription": {
    "has_access": true,
    "status": "active",
    "is_trialing": false,
    "trial_ends_at": null,
    "current_period_ends_at": "2026-04-01T00:00:00Z"
  },
  "limits": {
    "can_post": true,
    "posts_published_today": 3,
    "remaining_posts_today": 17,
    "daily_limit": 20
  },
  "stats": {
    "total_posts": 142,
    "scheduled_posts": 8,
    "posted_posts": 120,
    "draft_posts": 14
  }
}

If subscription.has_access is false, you cannot schedule or publish posts.

GET/api/v1/posts

List Posts

Retrieve a paginated list of your posts. Filter by status to see only scheduled, posted, draft, or failed posts.

Requires API Key

Query Parameters

NameTypeDescription
pageintegerPage number (default: 1)
limitintegerPosts per page (default: 20, max: 100)
statusstringFilter: "scheduled", "posted", "draft", or "failed"

Response

json
{
  "posts": [
    {
      "id": "65f1a2b3c4d5e6f7a8b9c0d1",
      "category": "General",
      "text": "Just shipped a new feature!",
      "scheduled_date": "2026-03-01T10:00:00Z",
      "posted": false,
      "posted_date": null,
      "failed": false,
      "failed_reason": null,
      "is_thread": false,
      "thread_tweets": null,
      "media_urls": null,
      "x_post_id": null,
      "review_status": "approved",
      "created_at": "2026-02-16T08:30:00Z",
      "updated_at": "2026-02-16T08:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 142,
    "pages": 8
  }
}
POST/api/v1/posts

Create Post(s)

Create a single post, a thread, or bulk create up to 50 posts at once. Include scheduled_date to schedule immediately (requires subscription).

Requires API Key

Request Body

Including scheduled_date requires an active subscription and counts toward daily limits. Omit it to save as a draft. All dates must be in the future (ISO 8601).

json
// Single post
{
  "text": "Just shipped a new feature!",
  "category": "Product",
  "scheduled_date": "2026-03-01T10:00:00Z"
}

// Thread
{
  "text": "Here's what I learned building a SaaS in 2026:",
  "is_thread": true,
  "thread_tweets": [
    "1/ Start with a problem you have yourself",
    "2/ Ship fast, iterate faster",
    "3/ Your first 10 users matter more than the next 1000"
  ],
  "scheduled_date": "2026-03-01T10:00:00Z"
}

// Bulk create (up to 50)
{
  "posts": [
    { "text": "Monday motivation", "scheduled_date": "2026-03-02T09:00:00Z" },
    { "text": "Tuesday tip", "scheduled_date": "2026-03-03T14:00:00Z" }
  ]
}

Response

json
{
  "success": true,
  "count": 1,
  "posts": [
    {
      "id": "65f1a2b3c4d5e6f7a8b9c0d1",
      "text": "Just shipped a new feature!",
      "category": "Product",
      "scheduled_date": "2026-03-01T10:00:00Z",
      "is_thread": false,
      "created_at": "2026-02-16T08:30:00Z"
    }
  ]
}
GET/api/v1/posts/:id

Get Single Post

Retrieve details of a specific post by its ID.

Requires API Key

Response

json
{
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "category": "General",
  "text": "Just shipped a new feature!",
  "scheduled_date": "2026-03-01T10:00:00Z",
  "posted": false,
  "posted_date": null,
  "failed": false,
  "is_thread": false,
  "x_post_id": null,
  "review_status": "approved",
  "created_at": "2026-02-16T08:30:00Z",
  "updated_at": "2026-02-16T08:30:00Z"
}
PUT/api/v1/posts/:id

Update Post

Update a draft or scheduled post. You cannot update posts that have already been published.

Requires API Key

Request Body

All fields are optional. Only include the fields you want to update.

json
{
  "text": "Updated tweet text",
  "category": "Marketing",
  "is_thread": false,
  "thread_tweets": [],
  "media_urls": []
}

Response

json
{
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "text": "Updated tweet text",
  "category": "Marketing",
  "scheduled_date": "2026-03-01T10:00:00Z",
  "is_thread": false,
  "updated_at": "2026-02-16T09:00:00Z"
}

Returns 400 if the post has already been published.

DELETE/api/v1/posts/:id

Delete Post

Permanently delete a post.

Requires API Key

Response

json
{
  "success": true,
  "message": "Post deleted"
}
POST/api/v1/posts/:id/schedule

Schedule Post

Set or update the scheduled publish time for a post. Requires an active subscription.

Requires API Key

Request Body

Date must be in the future. Use ISO 8601 format.

json
{
  "scheduled_date": "2026-03-01T10:00:00Z"
}

Response

json
{
  "success": true,
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "text": "Just shipped a new feature!",
  "scheduled_date": "2026-03-01T10:00:00Z",
  "message": "Post scheduled successfully"
}

Requires active subscription.

Counts toward daily post limits.

POST/api/v1/posts/:id/publish

Publish Immediately

Publish a post to X/Twitter right now. No request body needed. Requires an active subscription.

Requires API Key

Response

json
{
  "success": true,
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "text": "Just shipped a new feature!",
  "x_post_id": "1234567890123456789",
  "posted_date": "2026-02-16T10:00:00Z",
  "message": "Post published successfully"
}

Requires active subscription.

Returns 502 if the X/Twitter API fails.

Status Codes

CodeMeaning
200Success
201Created (new post)
400Bad request (validation error)
401Unauthorized (invalid API key)
403Forbidden (subscription required)
404Post not found
429Rate limit or daily post limit exceeded
500Server error
502X/Twitter API error

Error Response Shape

json
{
  "error": "Human-readable error message",
  "details": ["Array of specific validation errors (optional)"]
}

Common Workflows

Verify your connection

bash
curl -H "Authorization: Bearer ot_your_key" \
  https://opentweet.io/api/v1/me

Check authenticated is true and subscription.has_access is true.

Create and schedule a tweet (one step)

bash
curl -X POST https://opentweet.io/api/v1/posts \
  -H "Authorization: Bearer ot_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Just shipped a new feature!",
    "scheduled_date": "2026-03-01T10:00:00Z"
  }'

Post immediately

bash
# Step 1: Create a draft
curl -X POST https://opentweet.io/api/v1/posts \
  -H "Authorization: Bearer ot_your_key" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello from the API!"}'

# Step 2: Publish it (replace POST_ID with the id from step 1)
curl -X POST https://opentweet.io/api/v1/posts/POST_ID/publish \
  -H "Authorization: Bearer ot_your_key"

Schedule a week of content

bash
curl -X POST https://opentweet.io/api/v1/posts \
  -H "Authorization: Bearer ot_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "posts": [
      {"text": "Monday motivation", "scheduled_date": "2026-03-02T09:00:00Z"},
      {"text": "Tuesday tip", "scheduled_date": "2026-03-03T14:00:00Z"},
      {"text": "Wednesday wins", "scheduled_date": "2026-03-04T11:00:00Z"},
      {"text": "Thursday thoughts", "scheduled_date": "2026-03-05T16:00:00Z"},
      {"text": "Friday feels", "scheduled_date": "2026-03-06T10:00:00Z"}
    ]
  }'
🤖

Using OpenClaw?

Install the official skill and your agent handles everything above automatically.

bash
clawhub install opentweet/x-poster
export OPENTWEET_API_KEY="ot_your_key"
openclaw "schedule 5 tweets about our launch for this week"

Your agent can also read the plain-text API docs directly at /api/v1/docs.

Ready to build?

Get your API key and start posting in under 3 minutes.

API included in every plan. No extra charge.