X (Twitter) setup
Registering an X developer application and wiring it into SocialRelay.
X is the quickest platform to get publishing for real: unlike Meta and TikTok, posting works as soon as your app exists, without waiting on a review. What the paid tiers buy you is volume, not permission.
Prerequisites
- An X account that will do the posting
- A developer account at
developer.x.com— the free tier is enough to publish
1. Create the app
- Open the X developer portal and create a project, then an app inside it.
- Give the app a name users will recognise on the consent screen.
- Open the app’s User authentication settings and choose Set up.
2. Configure OAuth 2.0
SocialRelay uses OAuth 2.0 with PKCE, not OAuth 1.0a. Set the following:
| Setting | Value |
|---|---|
| App permissions | Read and write — read-only cannot post |
| Type of App | Web App, Automated App or Bot (a confidential client) |
| Callback URI | https://social.aitoolbucket.com/api/oauth/x/callback |
| Website URL | https://social.aitoolbucket.com |
Read and write must be set before you connect
3. Scopes
SocialRelay requests exactly these:
tweet.read read tweets, needed to confirm a post exists
tweet.write create tweets
users.read read the connected account's own profile
media.write upload images
offline.access receive a refresh token so the connection survivesoffline.access matters more than it looks: without it X issues no refresh token, the access token expires in a couple of hours, and every scheduled post after that fails until someone reconnects by hand.
4. Copy the credentials
From the app’s Keys and tokens tab, take the OAuth 2.0 Client ID and Client Secret. These are not the same as the API Key/Secret or the Access Token/Secret, which belong to OAuth 1.0a.
cd /var/www/creator
read -rsp "X_CLIENT_ID: " V && printf '\nX_CLIENT_ID="%s"\n' "$V" >> .env
read -rsp "X_CLIENT_SECRET: " V && printf '\nX_CLIENT_SECRET="%s"\n' "$V" >> .env
sudo systemctl restart creator-app creator-workerX_ACCESS_TOKEN and X_ACCESS_SECRET are optional
.env.example only for deployments that want an app-level fallback for media upload.5. Connect the account
- Open Social Accounts in the dashboard.
- Press Connect X (Twitter).
- Approve the request on X.
- You are returned to Social Accounts and the card shows Connected with your handle.
- Press Test Connection — it should report the username back.
What X will and will not accept
SocialRelay enforces these before it calls the API, so an invalid post is caught in the review screen rather than becoming a failed publish:
- 280 characters, counted including hashtags, by code point so emoji count as one
- Up to 4 images, or none — text-only posts are fine
- 5 MB per image, JPEG, PNG, or WebP
Troubleshooting
401 or X_TOKEN_EXPIRED
The access token expired and could not be refreshed. Usually offline.access was missing when the account was connected, so no refresh token was ever stored. Reconnect the account after confirming the scope.
403 when publishing
Almost always app permissions still set to read-only. Change to Read and write, then reconnect — the existing token keeps the permissions it was granted.
Duplicate content
X rejects an identical tweet posted twice in quick succession. This surfaces as X_DUPLICATE_CONTENT. Change the text and retry.
X_RATE_LIMITED
You have hit the posting cap for your access tier. The job is retried automatically with exponential backoff, honouring the platform’s Retry-After where it sends one. No action is needed unless it keeps failing, which means the tier is too small for your volume.
X_MEDIA_TOO_LARGE
An image is over 5 MB. SocialRelay checks declared sizes before uploading and re-checks after downloading, so this can also mean the image at that URL is larger than the payload claimed.

