Integrating Threads data into Python projects is a highly sought-after capability for developers. Whether you are building social listening monitors, content analytics dashboards, or post-publishing schedulers, accessing Threads user profiles is the starting point. However, depending on your architectural needs, you have two radically different paths: integrating Meta’s official, highly-regulated API, or using a developer-friendly, read-only data platform like HonestHook.
In this guide, we will walk you through how to query Threads API profile and quota data using Python, dive deep into Meta's strict limitations, provide working scripts, and honestly compare the official access model against the simplified alternative.
Under the Hood: The Official Threads API
To fetch profile details or publish content officially, you must interact with Meta’s Graph API. The Threads API can be accessed via either graph.threads.com or graph.threads.net.
Unlike open APIs, Meta applies a highly complex rate-limiting model that is based on organic engagement rather than static developer tiers. Your API call count is calculated dynamically over a rolling 24-hour window using the following formula:
Calls within 24 hours = 4800 * Number of Impressions
An "Impression" is defined as the number of times any content from the app user's Threads account has entered a person's screen within the last 24 hours. If your account has low visibility, Meta implements a default minimum impression count of 10. This means even a dormant or brand-new account starts with a baseline limit of 48,000 calls per 24 hours (4,800 * 10).
Additionally, your application is subject to daily CPU time limit restrictions based on impressions:
720000 * number_of_impressions for total_cputime2880000 * Number of Impressions for total_time
The Strict Functional Quotas
If your Python application does write actions, the official API imposes absolute ceilings over a 24-hour moving period:
- Posts: Limited to 250 API-published posts. Carousels count as a single post but must contain between 2 and 20 child items. Text posts are limited to 500 characters.
- Replies: Limited to 1,000 replies.
- Deletions: Limited to 100 deletions.
- Location Searches: Limited to 500 location searches.
Furthermore, any media your Python code uploads must adhere to strict parameters:
- Images: Must be JPEG or PNG, under 8 MB, with an aspect ratio limit of 10:1. The width must be between 320 pixels (minimum) and 1440 pixels (maximum). Any other color space will be forced into sRGB.
- Videos: Must use MOV or MP4 containers, without edit lists, containing the moov atom at the front. The file must be under 1 GB, maximum 300 seconds long, with a VBR video bitrate up to 100 Mbps, and a 128 kbps audio bitrate. Frame rates must fall strictly between 23 and 60 FPS, and horizontal resolution maxes out at 1920 columns.
Python Implementation: Retrieving Quotas and Profile Limits
Let's write a Python script to verify a user's active API status and remaining quotas. To call the official Graph API, you will need an access token with active permissions (specifically threads_basic, threads_content_publish, threads_manage_replies, and threads_delete depending on what you check).
Here is the Python code using the requests library to fetch the user's active quotas from the GET /{threads-user-id}/threads_publishing_limit endpoint:
import requests
def get_threads_user_quotas(user_id, access_token):
# We query the official Graph API using the threads.net endpoint
url = f"https://graph.threads.net/v1.0/{user_id}/threads_publishing_limit"
# Define the fields we want to retrieve
params = {
"fields": "quota_usage,config,reply_quota_usage,reply_config,delete_quota_usage,delete_config,location_search_quota_usage,location_search_config",
"access_token": access_token
}
try:
response = requests.get(url, params=params)
response.raise_for_status()
data = response.json()
return data
except requests.exceptions.RequestException as e:
print(f"Error communicating with Threads API: {e}")
return None
# Example usage (Replace with actual credentials)
USER_ID = "YOUR_THREADS_USER_ID"
ACCESS_TOKEN = "YOUR_THREADS_ACCESS_TOKEN"
quota_data = get_threads_user_quotas(USER_ID, ACCESS_TOKEN)
if quota_data:
print("Successfully retrieved user quota data:")
print(quota_data)
When this code executes successfully, you will receive a structured response revealing your current status: quota_usage tells you how many of your 250 available post slots you have consumed, while reply_quota_usage tracks your consumption of the 1,000 daily replies.
Troubleshooting Video and Media Profiles in Python
If your script is publishing rich media and you do not immediately receive a media ID from the POST /{threads-user-id}/threads_publish endpoint, your Python logic should query the container status.
The official recommendation is to poll the GET /{threads-container-id} endpoint once per minute, for no more than 5 minutes. This endpoint returns status strings like EXPIRED, ERROR, FINISHED, IN_PROGRESS, or PUBLISHED.
Here is how to structure that check in Python:
import time
import requests
def monitor_container_status(container_id, access_token):
url = f"https://graph.threads.net/v1.0/{container_id}"
params = {
"fields": "status,error_message",
"access_token": access_token
}
# Recommended: query once per minute, for no more than 5 minutes
for attempt in range(5):
try:
response = requests.get(url, params=params)
response.raise_for_status()
data = response.json()
status = data.get("status")
print(f"Attempt {attempt + 1}: Status is {status}")
if status == "PUBLISHED":
print("Success! Media has been published.")
return data
elif status == "ERROR":
print(f"Failed with error: {data.get('error_message')}")
return data
elif status == "EXPIRED":
print("The container has expired (exceeded 24 hours).")
return data
except requests.exceptions.RequestException as e:
print(f"API Error: {e}")
# Wait 60 seconds before retrying
time.sleep(60)
print("Polling timed out after 5 minutes.")
return None
If your status turns into an ERROR, Meta’s API can return explicit error codes such as FAILED_DOWNLOADING_VIDEO, FAILED_PROCESSING_AUDIO, FAILED_PROCESSING_VIDEO, INVALID_ASPEC_RATIO, INVALID_BIT_RATE, INVALID_DURATION, INVALID_FRAME_RATE, INVALID_AUDIO_CHANNELS, or INVALID_AUDIO_CHANNEL_LAYOUT. Handling these within your code is vital for stability.
An Honest Comparison: Official API vs. HonestHook
When deciding how to fetch user data and profiles in Python, you must weigh your specific requirements.
Where the Official Meta Threads API is Better:
The official Threads API is the only choice if your Python application needs to perform write actions. If you are building a scheduler that posts content on behalf of a user, interacts with other accounts by replying (up to 1,000 times daily), or deletes published items (up to 100 times daily), you must use Meta's official endpoints. HonestHook is strictly a read-only public data API and does not support any state-changing write operations.
Where HonestHook is Better:
If you are building directories, monitoring public profiles, tracking influencers, or performing social media research, using the official API is highly impractical. To get profile data via Meta, you must configure a Facebook developer app, obtain explicit permissions like threads_basic, set up OAuth login flows, and navigate complex rate limits bound to organic impressions. If your target profiles do not grant you explicit access tokens, you simply cannot read their public data.
With HonestHook’s /threads-api, you bypass these hurdles entirely. You can query any public Threads user profile using a single Python call with a standard API key. There are no impression-based rate limits (4800 * impressions) to track, no sRGB image conversions, and no developer review processes.
Getting Public Threads Profiles via HonestHook
Fetching public profiles with HonestHook in Python requires no OAuth handshake. Here is a simple demonstration of how you can extract clean, formatted public profile data:
import requests
def get_public_threads_profile(username, api_key):
# Clean, unified endpoint to retrieve public profile data
url = f"https://api.honesthook.com/api/v1/threads/profile/{username}"
headers = {
"Authorization": f"Bearer {api_key}",
"Accept": "application/json"
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"HonestHook API Error: {e}")
return None
# Retrieve profile information instantly
API_KEY = "your_honesthook_api_key_here"
profile_info = get_public_threads_profile("zuck", API_KEY)
print(profile_info)
Choosing the Right Path
If you need a deep integration for publishing tools and managing user accounts, take the time to set up Meta’s Graph API and manage your 250-post, 1,000-reply quotas. If you want hassle-free, robust, and scalable access to public Threads data in Python, HonestHook is designed exactly for you.
Check out our /threads-api to explore unified endpoints for multiple platforms, or view our pricing page to find a plan that fits your production workload.
Get a free API key — 1,000 credits a month, no card
Sources used for this article: https://developers.facebook.com/docs/threads/overview (accessed October 3, 2026) and https://developers.facebook.com/docs/threads/troubleshooting (accessed October 3, 2026).