How to Get a Threads API Access Token (Long-Lived, 2026)
To get a Threads API access token, create a Meta app with the Access the Threads API use case, add yourself as a Threads Tester and accept the invite in Threads settings, then send yourself through threads.com/oauth/authorize and exchange the code for a short-lived token valid for one hour. Swap it with th_exchange_token for a long-lived token valid for 60 days, and refresh it with th_refresh_token once it is at least 24 hours old.
A Threads API access token lets your app read and publish for one Threads account that granted it permission. Threads uses Meta's app system but its own app ID, secret, hosts and token endpoints, so Facebook or Instagram tokens will not work here. This guide follows Meta's Threads docs as they read today. For prices and limits on what you can read, see Is the Threads API free? and Threads API: official vs alternatives.
How to get Threads API access, step by step
- Create the app. At developers.facebook.com/apps, create an app and pick the "Access the Threads API" use case (create an app).
- Find the right ID and secret. The app has two of each. Use the Threads app ID and Threads app secret, found under Settings in the left menu.
- Add permissions. Under Use cases, open the Threads use case and click Add next to each permission.
threads_basicis always on. - Set URLs. In Settings, add a valid OAuth redirect URI, a Deauthorize callback URL and a Data Deletion Requests URL, then Save.
- Add a tester. In App roles > Roles, click Add People and choose Threads Tester.
- Accept the invite. As that tester, open Threads, go to Account Settings > Website permissions and accept.
- Authorize and exchange (below).
Testers can grant permissions at any time. Anyone else needs the app to be published and each permission approved through App Review (get started). Meta lists no review time.
Threads API permissions
| Permission | For |
|---|---|
threads_basic | Required for every endpoint; your own profile and posts |
threads_content_publish | Publishing posts |
threads_read_replies | Reading replies |
threads_manage_replies | Replying and managing replies |
threads_manage_insights | Post and account insights |
threads_keyword_search | Searching public posts; without it you search only your own |
threads_delete, threads_manage_mentions, threads_location_tagging, threads_profile_discovery | Deleting, mentions, locations, looking up other profiles |
Get the authorization code
https://threads.com/oauth/authorize?client_id=THREADS_APP_ID&redirect_uri=https://example.com/threads/callback&scope=threads_basic,threads_content_publish&response_type=code&state=RANDOM
The code is valid for one hour and works once. Meta appends #_ to the redirect; strip it, since it is not part of the code (access tokens and permissions).
Exchange it for a short-lived access token
curl -X POST "https://graph.threads.com/oauth/access_token" \
-F client_id=THREADS_APP_ID \
-F client_secret=THREADS_APP_SECRET \
-F grant_type=authorization_code \
-F redirect_uri=https://example.com/threads/callback \
-F code=CODE
The answer is {"access_token": "THQVJ...", "token_type": "bearer", "user_id": ...}, valid for one hour.
Get a Threads long-lived access token
curl "https://graph.threads.com/access_token?grant_type=th_exchange_token&client_secret=THREADS_APP_SECRET&access_token=SHORT_TOKEN"
Run this on your server, before the short token expires. expires_in comes back near 5,184,000 seconds, 60 days (long-lived tokens).
Refresh a Threads access token
curl "https://graph.threads.com/refresh_access_token?grant_type=th_refresh_token&access_token=LONG_TOKEN"
The token must be at least 24 hours old, unexpired, and have threads_basic. The refreshed token is valid for 60 days from the refresh. Miss the window and the user must authorize again.
| Token | Lifetime | Endpoint |
|---|---|---|
| Authorization code | 1 hour, one use | threads.com/oauth/authorize |
| Short-lived | 1 hour | graph.threads.com/oauth/access_token |
| Long-lived | 60 days, refreshable after 24 hours | th_exchange_token, th_refresh_token |
| App access token | Tied to app secret | client_credentials, or TH|APP_ID|APP_SECRET |
The app access token is server-only and is what the oEmbed endpoint needs (app access tokens).
First request and a refresh job in Python
curl "https://graph.threads.com/v1.0/me?fields=id,username,name,threads_profile_picture_url,threads_biography,is_verified&access_token=LONG_TOKEN"
import os, time
import requests
G = "https://graph.threads.com"
token = os.environ["THREADS_TOKEN"]
app_token = f"TH|{os.environ['THREADS_APP_ID']}|{os.environ['THREADS_APP_SECRET']}"
me = requests.get(f"{G}/v1.0/me", timeout=30, params={
"fields": "id,username,threads_biography", "access_token": token}).json()
print(me["username"])
info = requests.get(f"{G}/v1.0/debug_token", timeout=30, params={
"input_token": token, "access_token": app_token}).json()["data"]
days_left = (info["expires_at"] - time.time()) / 86400
print("valid:", info["is_valid"], "days left:", round(days_left, 1))
if info["is_valid"] and days_left < 50: # older than 10 days: refresh
new = requests.get(f"{G}/refresh_access_token", timeout=30, params={
"grant_type": "th_refresh_token", "access_token": token}).json()
print("refreshed, expires_in", new["expires_in"]) # store new["access_token"]
debug_token returns is_valid, expires_at, scopes and user_id; Meta's Access Token Debugger shows the same in a browser (debug access token). Both graph.threads.com and graph.threads.net work; Meta's examples use .com (overview).
Threads API rate limits
- Calls: 4,800 times the account's impressions per 24 hours, per app and user, with a minimum of 10 impressions in the formula.
- Publishing per 24 hours: 250 posts (a carousel counts as one), 1,000 replies, 100 deletes. Check with
GET /{threads-user-id}/threads_publishing_limit. - Keyword search: 2,200 queries per user per rolling 24 hours across all apps, up to 100 results per call; empty results do not count (keyword search).
Common Threads token errors
| Error | Cause | Fix |
|---|---|---|
| 400 "Matching code was not found or was already used" | Code reused, expired after an hour, or #_ left on | Authorize again; strip #_ |
| Redirect URI error at login | URI not in Client OAuth Settings exactly | Add it in Settings and Save |
| Login screen does not offer your app | Tester invite not accepted | Accept it in Account Settings > Website permissions |
| "The App_id in the input_token did not match the Viewing App" | Token from another app, often the Facebook app ID | Use the Threads app ID and secret |
| Refresh fails | Token under 24 hours old or already expired | Wait a day, or re-authorize |
If you just need public data
Most Threads permissions act on accounts that authorized your app. If you want public profiles, posts or search results of any account, ScrapeIO needs no Meta app or tester: the Threads profile API, user posts API, keyword search API and post API, at 1 credit a call. See best Threads scrapers and the Threads MCP server.
curl "https://scrapeio.com/v1/threads/profile?handle=zuck" \
-H "x-api-key: YOUR_KEY"
FAQ
How long does a Threads access token last?
Short-lived tokens last one hour, long-lived tokens 60 days. Refreshing gives another 60 days from that moment.
Where do I find the Threads app ID and secret?
In your Meta app under Settings. Use the Threads values, not the Facebook app ID shown elsewhere.
Why can't I log in to my own Threads app?
Your account must have the Threads Tester role and you must accept the invite in Threads settings under Website permissions.
Do I need App Review for the Threads API?
Not for testers. To let other users grant permissions, publish the app and get each permission approved.
Can I use an Instagram token for Threads?
No. Threads has its own app ID, secret and token endpoints on graph.threads.com.
Sources
Checked on 9 November 2026 from each vendor's own pages. Prices and limits change; follow the links before you decide.
- https://developers.facebook.com/documentation/threads/get-started
- https://developers.facebook.com/documentation/threads/get-started/create-an-app.md
- https://developers.facebook.com/documentation/threads/get-started/get-access-tokens-and-permissions
- https://developers.facebook.com/documentation/threads/get-started/long-lived-tokens
- https://developers.facebook.com/documentation/threads/get-started/app-access-tokens
- https://developers.facebook.com/documentation/threads/threads-profiles.md
- https://developers.facebook.com/documentation/threads/troubleshooting/debug-access-token
- https://developers.facebook.com/documentation/threads/overview.md
- https://developers.facebook.com/documentation/threads/keyword-search.md
100 free credits, no card. Credits never expire.
Get API key