Overview
Connect X, scopes, capabilities, wallet costs, and known limits.
Prepaid wallet required
X API calls are pass-through billing. X bills Onepostly for usage, and Onepostly debits your prepaid wallet at the same X list prices — no markup. If your wallet has no credits, requests are rejected with 402 INSUFFICIENT_WALLET. Top up in Dashboard → Settings → Billing.
Onepostly maps the X API v2 (OAuth 2.0 + PKCE) into the same /v1/* surface as other platforms. This section covers X-only behavior.
In this section
| Page | Topics |
|---|---|
| Posts | Publish, media, threads, quotes, schedule, remote delete |
| Engagement | Likes, retweets, bookmarks, comments |
| Insights | Analytics / normalized metrics |
Cross-platform API flow lives under each platform (e.g. X) plus shared guides like Media and Webhooks.
Connect
- Dashboard → Connections → connect X
- Approve scopes in the X consent screen
- Resolve
connectionIdwith your API key:
curl https://api.onepostly.com/v1/connections \
-H "x-api-key: op_YOUR_KEY"Use the matching row’s id (where platform is "x") as connectionId in publish requests.
After scope upgrades (media, likes, bookmarks), reconnect X so the new scopes appear on the token.
OAuth scopes
| Scope | Used for |
|---|---|
tweet.read | Read tweets / public metrics / search replies |
tweet.write | Create tweets, replies, quotes, threads, delete |
users.read | Account profile |
media.write | Media upload |
like.read / like.write | Like / unlike |
bookmark.read / bookmark.write | Bookmark / unbookmark |
offline.access | Refresh tokens |
Auth errors
| Code | Meaning |
|---|---|
INSUFFICIENT_WALLET | Onepostly prepaid wallet is empty |
TOKEN_INVALID / 401 | Expired or invalid token → reconnect |
PERMISSION_DENIED / 403 | Missing scope → reconnect with the required scopes |
Capabilities
| Action | Supported | Notes |
|---|---|---|
| Text post | Yes | POST /v1/posts |
| Image / video / GIF | Yes | Upload via POST /v1/media, then mediaUrls |
| Thread (reply chain) | Yes | thread[]; media on first tweet only |
| Quote | Yes | quoteTweetId on create, or POST …/quotes |
| Schedule | Yes | scheduledFor + timezone |
| Remote delete | Yes | Full thread chain (metadata.threadIds) |
| Insights | Yes | |
| List comments | Yes | |
| Reply / delete reply | Yes | Own replies |
| Retweet / unretweet / list | Yes | List can be unreliable on some tiers |
| Like / unlike | Yes | Needs like.write |
| Bookmark / unbookmark | Yes | Needs bookmark.write |
| Stories | No | Rejected as unsupported |
Wallet (X)
X usage is prepaid via the Onepostly wallet at X list prices — pass-through, no markup.
- Thread publish = sum of each segment’s create cost (URL surcharge applies per segment, when X charges it)
- Thread delete = delete cost × number of segments
- Failed platform calls do not keep the wallet charge
Top up: Dashboard → Settings → Billing.
402 INSUFFICIENT_WALLET = Onepostly wallet is empty — top up before retrying.
Known limitations
- Quote may fail on some X API tiers when quote is gated
- Retweeter list can 401 intermittently; retweet count via insights
sharesis more reliable - Character limit is 280 per segment (enforced by Onepostly before calling X)
- Engagement requires matching OAuth scopes on the current token (reconnect after scope upgrades)