PowerMarketing Docs

Publishing to X (Twitter)

This tutorial covers connecting an X account to PowerMarketing and publishing to it — the developer app, OAuth 2.0 with PKCE, threading behaviour, rate limits, metrics, and troubleshooting.

Human action AI Agent Approval gate Live on X

Prerequisites. (1) An active brand in PowerMarketing. (2) A working LLM key, or the shared allowance. (3) An X account. (4) Access to the X developer portal — a free developer account is enough to publish.

Long posts become threads — they are never truncated

X allows 280 characters per post. PowerMarketing's brand voice and content pillars routinely produce more than that, so anything longer is split into a thread, each reply chained to the one before it.

This changed on 2026-07-27. The previous adapter did content[:280] — a 600-character post published as a sentence that stopped mid-word, with the rest silently discarded and no error. If you have X posts from before this date that read as though they were cut off, that is why.
Content lengthResult
≤ 280 charactersOne post.
> 280 charactersA thread, split on word boundaries. Nothing is lost.
A single word > 280 charactersHard-split — a URL-like token cannot break cleanly, so it is cut rather than dropped.

The post's recorded ID and URL are those of the first post in the thread, so Posts and metrics track the thread head.

To forbid threading — for example if a brand's policy is one post or nothing — pass {"thread": false} in the publish options. Over-length content then raises a clear error instead of publishing a thread.


One-Time Setup

Step 1 — Create the X developer app

1

Create a project and an app

At the developer portal, create a Project, then an App inside it. The app name is shown on the consent screen, so use something your audience will recognise.

Step 2 — Configure user authentication

1

Open "User authentication settings"

In the app's settings, click Set up under User authentication settings.

2

App permissions: Read and write

Choose Read and write. The default is read-only, and publishing fails with a 403 if you leave it.

3

Type of App: Web App / Confidential client

Choose Web App, Automated App or Bot. This issues a Client Secret, which PowerMarketing needs — a public client will not work.

4

Add the callback URI

Paste the exact URL PowerMarketing shows you in Step 3:

https://marketing-api.planningpowertools.com/api/oauth/x/callback

It must match character for character. A mismatch is rejected before the consent screen even loads.

5

Copy the OAuth 2.0 Client ID and Secret

X shows the secret once. These are the OAuth 2.0 credentials — not the API Key/Secret, and not the Bearer Token. Using the wrong pair is the single most common setup mistake here.

Step 3 — Save them in PowerMarketing

1

Settings → Credentials → X (Twitter) Configuration

Paste the Client ID and Client Secret, confirm the Callback URI (use Copy to take the exact value to X), and click Save App Config. The badge turns to Configured.

Step 4 — Connect the account

1

Click Connect X Account

You are sent to X's consent screen. PowerMarketing requests tweet.read, tweet.write, users.read and offline.access, using PKCE — which X requires. Authorise, and you are returned to Settings with the account listed by its handle.


Publishing a post

✍️
You
Topic, platform X
→
🤖
Agent
Draft written
→
🛡️
Gate
Approval, unless auto
→
🧵
Auto
Split into a thread
→
✅
Live
On your timeline

Unlike YouTube, X content can auto-publish: post, short_post, news and the other non-locked content types follow your Publication Rules and autopilot level as normal. Only video and reel always require approval.


Tokens & refresh

X access tokens are valid for two hours. PowerMarketing renews them automatically about two minutes before expiry, so a connected account keeps working indefinitely.

X rotates refresh tokens. Every refresh returns a new refresh token and invalidates the previous one. PowerMarketing stores the new value each time — this is why connecting the same account into two tools at once tends to break both: whichever refreshes second is holding a token that has already been retired.

The offline.access scope is what makes X issue a refresh token at all. If it is missing, the connection is rejected at setup rather than failing silently two hours later.


Rate limits & access tiers

Per X's published rate limits, the posting endpoint allows:

EndpointLimit
POST /2/tweets — per user100 per 15 minutes
POST /2/tweets — per app10,000 per 24 hours
A thread costs one request per segment. A 1,500-character post is six requests, not one. This matters far more on X than elsewhere, because X also applies a monthly post cap on the free tier.

X sells tiered access (Free, Basic, Pro, Enterprise) with different monthly caps. Those caps change from time to time, so check the current figures on X's own pricing page rather than relying on a number written here — and size your posting cadence against the tier you are actually on.


Metrics

The daily metrics job reads GET /2/tweets/{id}?tweet.fields=public_metrics and maps the result onto PowerMarketing's common shape:

PowerMarketingX field
impressionsimpression_count
likeslike_count
commentsreply_count
sharesretweet_count + quote_count

X splits amplification into reposts and quotes while the learn-loop has a single shares field, so the two are summed. Metrics are read for the thread head; replies in the thread accrue their own numbers, which are not aggregated.


Reference tables

ItemValue
Required scopestweet.read, tweet.write, users.read, offline.access
App permissionsRead and write
App typeWeb App / confidential client (must issue a secret)
Callback URI{API_BASE}/api/oauth/x/callback
Authorize URLhttps://x.com/i/oauth2/authorize
Token URLhttps://api.x.com/2/oauth2/token (HTTP Basic auth)
Publish endpointPOST https://api.x.com/2/tweets
PKCERequired — S256
Access token lifetime2 hours, refreshed automatically
Character limit280 per post; longer content threads

Troubleshooting

SymptomCause & fix
403 on publishApp permissions are still Read. Set them to Read and write, then reconnect the account — changing permissions does not upgrade tokens already issued.
"X did not return a refresh token"offline.access is missing from the app's scopes. Add it and connect again.
invalid_request at the consent screenThe callback URI does not match the one registered. Use the Copy button and paste it verbatim.
Token exchange fails with invalid_clientYou used the API Key/Secret or the Bearer Token instead of the OAuth 2.0 Client ID and Secret.
Publishing stops after ~2 hoursRefresh could not run — usually the Client Secret changed. Re-save the app config, then reconnect.
Publishing stops after working for daysThe refresh token was rotated by another tool using the same account. Reconnect from PowerMarketing.
403 "duplicate content"X rejects identical posts. Edit the draft or use Regenerate.
"X thread broke after N segment(s)"A mid-thread request failed, usually a rate limit. The error names the first post's URL — check the thread on X and post the remainder manually, or delete and republish.
Post is over 280 and you did not want a threadPass {"thread": false} in the publish options to get an error instead.