Start here
You call an X API endpoint that writes, such as posting, and get back 403 Forbidden with the problem type oauth1-permissions. A 403 from X means your credentials are valid but don't have permission for that action [1]. With OAuth 1.0a, the permission lives in two places: the app's setting, and the access token you made under that setting.
The short version
- The app needs Read and write. Read only can't post, like or follow [2].
- Old tokens keep the old permission. X says changing permissions "requires users to re-authorize your app to get new tokens with the updated scope" [2]. For your own account, that means pressing Regenerate on the access token after the change.
- Regenerating kills the old token. Copy the new pair at once; X shows it only once [3] [4].
- The API key and secret don't change. Only the access token and secret need regenerating.
Four steps: a post returns 403 oauth1-permissions, set the app to Read and write, regenerate the access token and secret, the new pair carries the new permission. The first is red.
Open your app in the Developer Console
Goal: Have the right app open in the console, signed in as the account that will post.
- Go to console.x.com and sign in with your X account [3].
- Open Apps in the side menu and click the app whose keys you use [4].
- Check who you're signed in as. The access token on the Keys and tokens tab makes requests "on behalf of your own account" [2], the account that owns the app. If that isn't the account you want to post as, the posts will go out from the wrong account.
Good enough when
Set the app permission to Read and write
Goal: The app's OAuth 1.0a permission reads Read and write.
- On the app's page, find User authentication settings and click Set up (or Edit if it's already set up) [7].
- Under App permissions, pick Read and write. Pick Read and write and Direct message only if your program also sends DMs [2].
- If the form asks for the type of app, pick the one that matches yours; a script that posts for you is an automated app or bot [2].
- If it asks for a Callback URI and Website URL, they must be filled in to save. For a script that only uses the console's tokens,
http://127.0.0.1is accepted as a local callback [2], and the website can be your own site [7]. - Click Save.
Good enough when
Regenerate the access token and secret
Goal: A new access token and secret, made after the permission change.
- Open the Keys and tokens tab of the same app [4].
- Find Access Token and Secret and click Regenerate [5]. Confirm.
- Copy both values straight away. They're shown once, and the old pair stops working now [3].
- Don't regenerate the API Key and Secret (the consumer keys). They didn't cause the 403, and regenerating them breaks everything else that uses them [3].
- If the console shows which permission the new token has, it should say Read and write. If it still says Read, the save in step 2 didn't take; go back and save again, then regenerate again.
Good enough when
Put the new pair in the env file
Goal: Your program reads the new token and secret.
- Open
~/.config/x-api/env. Replace the values ofX_ACCESS_TOKENandX_ACCESS_TOKEN_SECRETwith the new pair. LeaveX_API_KEY,X_API_KEY_SECRETandX_BEARER_TOKENas they are. - Keep the file out of git [5].
Good enough when
Check that writing works
Goal: The call that returned 403 now succeeds.
- Rerun the exact command that failed. With our tools that's the queued post, for example
x-pull queue-tick <queue.json> --send, or a dry run first without--send. - A post is public. If you only want to prove the token works, post to a test account, or delete the test post afterwards.
Good enough when
Reference
Sources
- X docs, Response codes and errors: 403 means valid auth but no permission for the resource or action. docs.x.com/x-api/fundamentals/response-codes-and-errors
- X docs, Apps: the three OAuth 1.0a permission levels, the note that changing permissions needs re-authorization for new tokens, OAuth 2.0 app types and callback URL rules (127.0.0.1 for local). docs.x.com/fundamentals/developer-apps
- X docs, Developer Console: console.x.com; keys and tokens are shown once, and regenerating invalidates the old ones. docs.x.com/fundamentals/developer-portal
- X docs, API Key and Secret: find or regenerate credentials under Apps, then the app's Keys and tokens tab. docs.x.com/fundamentals/authentication/oauth-1-0a/api-key-and-secret
- X docs, Authentication best practices: the Regenerate button beside each set of keys and tokens; keep secrets out of version control. docs.x.com/fundamentals/authentication/guides/authentication-best-practices
- X docs, Obtaining access tokens using 3-legged OAuth: access tokens don't expire, and the example token begins with the user's numeric id. docs.x.com/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens
- X Developer Community thread on User authentication settings (2022, older portal): where App permissions, callback and website URL are set; the website URL is informational. devcommunity.x.com/t/user-authentication-settings/173310