Blog/Developer Tools/

Threads Public Data API | SandBase

Read public Threads profiles, posts, replies, and search with one REST API. No Threads login, no SDK — one SandBase key, built for agent workflows.

Dark cinematic render of Threads profile, post, and reply data flowing through one API conduit into an agent core

Threads is Meta’s fast-growing text conversation network, and its public profiles, posts, and replies map directly onto brand monitoring, creator research, and social listening. Getting at it programmatically usually means reverse-engineering the app, managing tokens, and rebuilding a scraper every time the app changes.

The SandBase Threads public data API removes that setup tax. It reads public Threads profiles, posts, replies, and search through plain REST endpoints — one SandBase API key, no Threads login and no SDK. The endpoint API reference is the source of truth for each parameter and for the response envelope; the business-payload field names shown below are an illustrative shape, not a guaranteed schema, so confirm them against a live response for the endpoint you call.

This is not Meta’s official Threads API. Use Meta’s official APIs when you need authenticated member actions, posting, or a licensed data agreement. Use SandBase when your workflow needs public, read-only data for research and monitoring. Ready to try it? Get a SandBase API key and browse the Threads endpoints.

Key takeaway

  • One API reads public Threads profiles, posts, replies, reposts, and search.
  • The Model API endpoints documented here are called with POST /v1/api/threads/<path> — pass only that endpoint’s params, no SDK, one SANDBASE_API_KEY.
  • Endpoints key off natural identifiers: a username resolves a profile, then its user_id (the pk/id from user-info) drives post and reply reads, and a post_id drives comment reads.
  • It returns public, read-only data only. There is no posting, no platform login on your side, and no private data; authenticate with a SandBase API key.

Which Threads API do you need?

Your needChooseWhy
Post, act as a member, or use account-authorized dataMeta’s official Threads APIMember and account operations run through Meta directly.
Read public profiles, posts, replies, or searchSandBase Threads public-data APIPlain REST, one SandBase key, structured JSON for read-only workflows.
Private or account-only dataNeither public workflowThat data is out of scope for this public-data guide.

What you can get from the Threads API

The catalog is organized on a web surface. Grouped by job:

  • Profiles — public profile info by username (or by id), including bio, follower count, and verified status.
  • Posts & replies — a user’s posts, replies, and reposts, plus a single post’s detail and its comments.
  • Search — profile search, plus top and recent post search by keyword.

Availability differs by endpoint, and some upstream reads can be intermittent — treat each endpoint’s live API reference as the source of truth and confirm availability before you build on a specific one.

SandBase Threads API page: description, capability tags, and the endpoint list The Threads API page on SandBase — a tagged overview and the endpoint list, each with its path.

What Threads provides vs. what SandBase adds

Public data comes from Threads. SandBase does not own or operate Threads; it provides a uniform API layer for eligible public-data workflows. Each capability becomes one documented endpoint, auth collapses to a single key, and responses come back as predictable JSON — so an agent can chain “read a profile → read its posts → pull a post’s comments” along one convention instead of maintaining a scraper.

Quick start: your first call

SandBase exposes more than one API surface. The catalog may show GET paths under /apis/v1/...; this guide uses the vendor-qualified Model API path on each endpoint’s API reference. Do not swap the HTTP method or URL — follow the reference for the endpoint you choose.

Read a public profile by username:

import os
import requests

resp = requests.post(
    "https://api.sandbase.ai/v1/api/threads/web/user-info",
    headers={
        "Authorization": f"Bearer {os.environ['SANDBASE_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={"username": "zuck"},
)
resp.raise_for_status()
body = resp.json()
if body.get("status") != "completed":
    error = body.get("error", {})
    raise RuntimeError(error.get("message", "Threads request did not complete"))

# The reference guarantees the envelope (id/status/model/outputs[0].data);
# business fields vary by endpoint, so read defensively and confirm
# the exact paths against a live response.
data = body["outputs"][0]["data"]
user = data.get("user", {})
print(user.get("full_name"), user.get("follower_count"), user.get("is_verified"))
curl -X POST https://api.sandbase.ai/v1/api/threads/web/user-info \
  -H "Authorization: Bearer $SANDBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"username": "zuck"}'

Responses share the same envelope: an id, a status, the model name, and — for a completed run — an outputs array whose single item carries the payload under data. A completed run carries outputs; a failed or timeout run carries error and no outputs. That envelope is what the endpoint reference guarantees; here the profile object nests under a user key, and the operation-specific fields inside are documented per endpoint. Branch on status before reading outputs[0].data, and check each endpoint’s reference for its run mode. The block below is my tested response, tested on 2026-09-27 (UTC) — field names and values can change over time, so confirm them against a live response:

{
  "id": "77059cb9-8616-4be1-abfe-96e82a12b54f",
  "status": "completed",
  "model": "threads/web/user-info",
  "outputs": [
    {
      "data": {
        "user": {
          "full_name": "Mark Zuckerberg",
          "biography": "Mostly superintelligence and MMA takes",
          "follower_count": 5744972,
          "is_verified": true,
          "bio_links": [],
          "id": "63055343223",
          "pk": "63055343223"
        }
      }
    }
  ]
}

A failed or timeout run carries error and never outputs. Response shapes differ by endpoint — inspect one real response and map the exact path per endpoint.

SandBase API reference for a Threads endpoint, showing the vendor-qualified URL and the response schema The endpoint API reference is the source of truth for each parameter name and response path.

Capability map

Capability clusterRepresentative endpointTypical use
Profilethreads/web/user-infoPublic profile signals by username
Poststhreads/web/user-postsRead a user’s posts by user_id (optional end_cursor)
Repliesthreads/web/user-repliesRead a user’s replies by user_id (optional end_cursor)
Post commentsthreads/web/post-commentsEngagement and sentiment inputs by post_id (optional end_cursor)
Searchthreads/web/search-profilesCreator and topic discovery by query

Paging differs by endpoint — several endpoints accept a per-endpoint cursor request parameter. Read each endpoint’s schema, and confirm the endpoint is available before you build on it.

SandBase Threads endpoint list showing profile, post, reply, and search endpoints with their paths A slice of the Threads endpoint list on the web surface.

Chaining calls in an agent workflow

Because the endpoints documented here share the same auth and the same response envelope, an agent can walk from a profile to a post’s comments without special-casing each surface. A common social-listening pattern looks like this:

  1. Read the profile. Call threads/web/user-info with a username to get bio, follower count, verified status, and the profile’s pk/id.
  2. Read the posts. Take the pk/id from step 1 and call threads/web/user-posts with it as user_id (optional end_cursor for paging) to read the user’s recent posts. Confirm availability against the reference first — this upstream read can be intermittent.
  3. Read the comments. Call threads/web/post-comments with a post_id (optional end_cursor) to gather a post’s replies as engagement inputs.

Each step returns the same envelope, so your agent branches on status once and reuses the same JSON-reading code across every step. A completed run carries outputs; a failed or timeout run carries error and no outputs.

Common use cases

Threads profile API for creator research

Call threads/web/user-info with a username to read bio, follower count, verified status, and bio links. Input: a username. Output: a profile record under user. Endpoint: user-info.

Threads posts API for content monitoring

First resolve the profile with threads/web/user-info (a username) to get its pk/id, then read threads/web/user-posts for the user’s recent posts. Input: a user_id (the pk/id from user-info), plus an optional end_cursor for paging. Output: a list of posts. Endpoint: user-posts. Confirm availability against the reference before building on it — this upstream read can be intermittent.

Threads search API for discovery

Run threads/web/search-profiles with a keyword to surface creators around a niche. Input: a keyword. Output: matching profiles. Endpoint: search-profiles.

Why run this at the API layer

You could point a headless browser at Threads and parse the app’s payloads, but that path is fragile: the app changes, tokens rotate, and you maintain a scraper instead of shipping features. Reading through one uniform API means your code depends on named JSON fields and a single response envelope rather than an app internal. Auth is one key, and because the endpoints documented here return the same envelope — a completed run carries outputs, while a failed or timeout run carries error and no outputs — retries, logging, and error handling live in one helper you write once and reuse everywhere.

That uniformity is what makes the workflow composable for an agent. Swap one username for another, and the code path is identical. Add a second read — a user’s replies, say — and it slots in behind the same status-checking helper. The practical payoff is that your time goes to what the data means for your research, not to keeping a scraper alive against a moving target. When you need more than single reads, check the live listing for the endpoint that fits and confirm its parameters — and its current availability — before wiring it in.

Limitations and boundaries

  • Public, read-only data only. No posting, following, or private/account-only data.
  • Rate and volume. Treat responses as best-effort reads; as a client-side resilience measure, retry with backoff on transient errors such as HTTP 429 or an intermittent upstream error.
  • Parameters and shapes follow the upstream surface. Identifiers vary: user-info takes a username, user-posts/user-replies take a user_id (the pk/id from user-info), post-comments takes a post_id, and search-profiles takes a query; paging is a per-endpoint end_cursor. The profile payload nests under user. Inspect a real response and read the schema first.
  • Verify endpoints against the live reference. Availability and fields can change, and some post/search reads can be intermittent; confirm before building on a specific endpoint.
  • This is not an official Meta partnership. SandBase provides uniform access to public data; respect Threads’ terms and applicable rules for your use case.

FAQ

Do I need a Threads or Meta login? No. You authenticate to SandBase with your SANDBASE_API_KEY. These read endpoints do not require a Threads account or OAuth on your side.

What identifies a profile or a post? A username identifies a profile for user-info, which returns the profile’s pk/id. Use that value as the user_id for user-posts and user-replies. A post_id identifies a single post’s comments for post-comments, and search-profiles takes a query.

Why does the profile nest under user? The user-info payload wraps the profile in a user object, with fields such as full_name, biography, follower_count, and is_verified. Read data["user"] defensively and confirm the fields against a live response.

Can I read private or account-only data? No. The API returns public data only. Private and account-authorized content are out of scope.

Start with a profile read

Create a SandBase API key, call user-info, and inspect the returned schema before you expand to posts, replies, or search. When you are ready: