Bluesky API: Search posts
Searches public Bluesky posts for words, optionally ordered by latest or top and filtered by date, author or language. Search indexing may lag behind new posts.
Unofficial. Not affiliated with or endorsed by Bluesky.
Inputs
Values from the run on Oct 23, 2026, shown under Output.
- Sort optional
sort Order results by latest or top.
latest
One of
latest,top. Defaultlatest.- Query, required
query Words to search for, such as climate policy.
climate policy
- Author optional
author Only posts from this handle, for example bsky.app.
Not set
- Language optional
language Language name or two-letter code, for example English or en. Leave blank for any language.
Not set
- Since Date optional
since_date Include posts from this date onward, for example 2026-09-01 (YYYY-MM-DD).
Not set
- Max Results optional
max_results Maximum posts to return, for example 25.
5
Whole number from 1 to 100. Default
25.
Input as JSON
{ "sort": "latest", "query": "climate policy", "max_results": 5}Output
{ "posts": [ { "text": "๐๐ฃ๐ผ๐น๐ถ๐ฐ๐ ๐ฐ๐ฒ๐ฟ๐๐ฎ๐ถ๐ป๐๐ ๐ฎ๐ป๐ฑ ๐ถ๐ป๐ฐ๐ฒ๐ป๐๐ถ๐๐ฒ๐ ๐ฐ๐ฟ๐ฒ๐ฎ๐๐ฒ ๐ฎ๐ป ๐ฒ๐ป๐ฎ๐ฏ๐น๐ถ๐ป๐ด ๐ฒ๐ป๐๐ถ๐ฟ๐ผ๐ป๐บ๐ฒ๐ป๐ for the transition. Measures such as transition plans or the integration of nature and climate considerations into prudential frameworks, send market signals that cascade through tโฆ", "likes": 0, "replies": 1, "reposts": 0, "post_uri": "at://did:plc:mh2csbc5e6cni3z7wi7vts7g/app.bsky.feed.post/3myjpqh26ak2s" , "post_link": "https://bsky.app/profile/eurosif.bsky.social/post/3myjpqh26ak2s" , "posted_at": "2026-10-23T08:04:07.646000Z", "image_links": [], "author_handle": "eurosif.bsky.social", "author_display_name": "Eurosif, the European Sustainable Investment Forum" }, { "text": "โฒ๏ธ The findings point to working time reduction being a promising and under-explored policy instrument in climate mitigation", "likes": 0, "replies": 1, "reposts": 0, "post_uri": "at://did:plc:jqaguraawdoo2bqkfotpop5q/app.bsky.feed.post/3myjpm7ocds2x" , "post_link": "https://bsky.app/profile/etui.bsky.social/post/3myjpm7ocds2x" , "posted_at": "2026-10-23T08:01:47.779000Z", "image_links": [], "author_handle": "etui.bsky.social", "author_display_name": "ETUI" }, { "text": "The Breakdown & Plane Error:\nConfusing scientific reporting (WHAT) with systemic policy enforcement (WHO), treating data publication as effective climate action.", "likes": 0, "replies": 1, "reposts": 0, "post_uri": "at://did:plc:xvo7gsaojuuuxc6rlw374pls/app.bsky.feed.post/3myjnsx2je52p" , "post_link": "https://bsky.app/profile/judgement-bot.bsky.social/post/3myjnsx2je52p" , "posted_at": "2026-10-23T07:29:47.150313Z", "image_links": [], "author_handle": "judgement-bot.bsky.social", "author_display_name": "Alethekanon" } ]}Code
curl https://api.fous.com/v1/runs \ -H "Authorization: Bearer $FOUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"method":"bsky.app/search_posts","input":{"sort":"latest","query":"climate policy","max_results":5}}' # Save as fous.py, then run: python3 fous.pyimport json, os, timefrom urllib.error import HTTPErrorfrom urllib.request import Request, urlopenAPI = "https://api.fous.com/v1/runs" KEY = os.environ["FOUS_API_KEY"]HEADERS = { "Authorization": f"Bearer {KEY}", "Content-Type": "application/json" ,}def call(url, body=None): data = json.dumps(body).encode() if body else None request = Request(url, data, HEADERS) try: with urlopen(request, timeout=120) as r: return r.status, json.load(r) except HTTPError as error: message = json.load(error)["error"]["message"] raise RuntimeError(message) from errorstatus, run = call(API, { "method": "bsky.app/search_posts" , "input": { "sort": "latest", "query": "climate policy", "max_results": 5 }})# 202: still going after 30 s. Ask again until it ends.while status == 202: time.sleep(2) status, run = call(f"{API}/{run['id']}")print(json.dumps(run["data"], indent=2))// Save as fous.mjs, then run: node fous.mjsconst api = "https://api.fous.com/v1/runs" ;const headers = { Authorization: `Bearer ${process.env.FOUS_API_KEY}`, "Content-Type": "application/json" ,};let response = await fetch(api, { method: "POST", headers, body: JSON.stringify({ "method": "bsky.app/search_posts" , "input": { "sort": "latest", "query": "climate policy", "max_results": 5 } }), signal: AbortSignal.timeout(120_000),});let run = await response.json();// 202: still going after 30 s. Ask again until it ends.while (response.status === 202) { await new Promise((done) => setTimeout(done, 2_000)); response = await fetch(`${api}/${run.id}`, { headers }); run = await response.json();}if (!response.ok) throw new Error(run.error.message);console.log(run.data);# Connect your agent to Fous once, over MCP (Streamable HTTP):# https://api.fous.com/mcp# Set FOUS_API_KEY first: create a key at https://app.fous.com/keys.# Claude Codeclaude mcp add \ --scope user \ --transport http fous https://api.fous.com/mcp \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Codexcodex mcp add fous \ --url https://api.fous.com/mcp \ --bearer-token-env-var FOUS_API_KEY# Cursor, VS Code, Windsurf, Cline and morenpx -y add-mcp https://api.fous.com/mcp -g -n fous \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Then ask your agent:# "Use Fous to run bsky.app/search_posts# with {"sort":"latest","query":"climate policy","max_results":5}"Over HTTP, the answerโs data holds the output. A run still going after 30 seconds answers 202 with its id: ask GET /v1/runs/{id} until it ends.
Schema
Input schema
{ "type": "object", "required": [ "query" ], "properties": { "sort": { "enum": [ "latest", "top" ], "type": "string", "default": "latest", "description": "Order results by latest or top." }, "query": { "type": "string", "minLength": 1, "description": "Words to search for, such as climate policy." }, "author": { "type": "string", "description": "Only posts from this handle, for example bsky.app." }, "language": { "type": "string", "description": "Language name or two-letter code, for example English or en. Leave blank for any language." }, "since_date": { "type": "string", "description": "Include posts from this date onward, for example 2026-09-01 (YYYY-MM-DD)." }, "max_results": { "type": "integer", "default": 25, "maximum": 100, "minimum": 1, "description": "Maximum posts to return, for example 25." } }}Output schema
{ "type": "object", "required": [ "posts" ], "properties": { "posts": { "type": "array", "items": { "type": "object", "required": [ "author_handle", "author_display_name", "text", "posted_at", "likes", "reposts", "replies", "image_links", "post_link", "post_uri" ], "properties": { "text": { "type": [ "string", "null" ] }, "likes": { "type": "integer" }, "replies": { "type": "integer" }, "reposts": { "type": "integer" }, "post_uri": { "type": "string" }, "post_link": { "type": "string" }, "posted_at": { "type": [ "string", "null" ], "format": "date-time" }, "image_links": { "type": "array", "items": { "type": "string" } }, "author_handle": { "type": [ "string", "null" ] }, "author_display_name": { "type": [ "string", "null" ] } } }, "description": "Public posts matching the search, in requested order." } }}- Price
- 1 credit per completed run (1ยข with pay as you go); failed runs are free.
- Method
bsky.app/search_posts- Returns
- author, text, time, likes, reposts, replies, image links, post link
Use it from your agent
Give your agent this line. It reads SKILL.md, gets a Fous API key and connects the Fous MCP server. Its run then takes the method bsky.app/search_posts with the inputs above.
Ask your agent
- Find the most liked Bluesky posts about solar panel subsidies from the past week
- Search public posts mentioning 'open source license change' sorted by latest, max 40 results
- Show me top Bluesky posts by handle alice.example.social about local elections since 2026-08-15
- Look up posts in Spanish about hurricane preparedness, sorted by top, limited to 15 results
- On bsky.app, search for recent posts with the words 'remote work policy' ordered by latest, including image links
See more
All Bluesky methodsLists an account's latest public Bluesky posts, newest first. Replies and reposts are left out unless requested; a repost's time is when the account reposted it.
bsky.app/list_recent_postsLooks up a public Bluesky profile by handle or profile link, including bio, audience counts and join date. A bare name first checks its .bsky.social handle, then the top relevant people-search result.
bsky.app/get_profileFinds public Reddit posts by topic, optionally in one community, for a time window and sort order. Returns up to 100 posts in Reddit search order with score, comment count, text and link.
reddit.com/search_postsFinds BBC News articles matching search words, newest first or by relevance, with publication time, authors, section and summary, optionally limited to a date range. Date filters and newest order apply to the first 180 search matches; older or less relevant matches may be missed.
bbc.com/search_newsFinds Open Library books by search words, optionally narrowed by author and subject, sorted by relevance or publication age. Returns work-level results; free_online means at least one edition is marked public or borrowable, not that a loan is available now.
openlibrary.org/search_booksFinds public Hugging Face models by search words, with an optional task and sort order. License is null when the model does not publish one.
huggingface.co/search_modelsFinds public Hugging Face Spaces demos for a task, with descriptions, likes, running status and update dates.
huggingface.co/search_spacesFinds Stack Overflow programming questions matching plain-language search words, optionally filtered by tag and answer status, with a chosen sort order.
stackoverflow.com/search_questions