# Bluesky Post Search API. Posts matching your search.

Posts by keyword, hashtag, author or link. We handle the proxies, blocks and platform changes.

[Get API key](https://socialtap.dev/signup/?next=%2Fplayground%2F%3Fendpoint%3Dbluesky.search_posts)

## Bluesky Post Search API at a glance

Returns public Bluesky posts that match your words, newest or top first, filtered by date, language, author, mention, hashtag or site. Each post has its link, publish time, full text with hashtags, mentions and full link URLs, images and video, link card, quote and reply, and exact like, reply, repost, quote and bookmark counts. Page back through the newest-first results with the cursor.

GET `/v1/bluesky/search_posts`

[Read the API reference](https://socialtap.dev/docs/reference/bluesky/search_posts/index.md)

- **1 credit** per page, $0.75–$1.97 per 1,000 pages
- **22 typed fields** null when unknown
- **100** posts per page, newest first, by the time each post states, to the second
- **`query`** is all it needs, e.g. `climate change`

## Send one request. Get up to 100 posts back.

Copy the request in your language, or hand it to your agent. Sign up for an API key and your first 100 credits are free.

`$ npm install socialtap`

`query = climate change`

[Open in playground](https://socialtap.dev/playground/?endpoint=bluesky.search_posts)

cURL:

```shell
curl 'https://socialtap.dev/v1/bluesky/search_posts?query=bitcoin&sort=newest' \
  -H "x-api-key: $SOCIALTAP_API_KEY"
```

TypeScript SDK:

```typescript
import { SocialTap } from "socialtap";

const client = new SocialTap(); // apiKey defaults to process.env.SOCIALTAP_API_KEY

const res = await client.bluesky.searchPosts.list({ query: "bitcoin", sort: "newest" });
console.log(res.data);
console.log(res.credits.charged, res.meta.request_id);
```

Node.js (fetch):

```javascript
const params = new URLSearchParams({
  query: "bitcoin",
  sort: "newest",
});
const res = await fetch(`https://socialtap.dev/v1/bluesky/search_posts?${params}`, {
  headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, page, meta } = body;
console.log(data, meta.credits_charged);
```

Python (requests):

```python
import os

import requests

res = requests.get(
    "https://socialtap.dev/v1/bluesky/search_posts",
    params={"query": "bitcoin", "sort": "newest"},
    headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
    raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, page, meta = body["data"], body["page"], body["meta"]
print(data, meta["credits_charged"])
```

Go (net/http):

```go
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
)

func main() {
	q := url.Values{}
	q.Set("query", "bitcoin")
	q.Set("sort", "newest")
	req, err := http.NewRequest("GET", "https://socialtap.dev/v1/bluesky/search_posts?"+q.Encode(), nil)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	var body struct {
		Data  json.RawMessage `json:"data"`
		Page  json.RawMessage `json:"page"`
		Meta  map[string]any  `json:"meta"`
		Error *struct {
			Code    string `json:"code"`
			Message string `json:"message"`
		} `json:"error"`
	}
	if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
		log.Fatal(err)
	}
	if body.Error != nil {
		log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
	}
	fmt.Println(string(body.Data), body.Meta["credits_charged"])
}
```

200 OK:

```json
{
  "data": [
    {
      "approximate_fields": [],
      "author": {
        "avatar_url": "https://cdn.bsky.app/img/avatar/plain/did:plc:hlod3gl5ewwglnr4yarddcrk/bafkreihy5kd5vnqqs77wtxzdf5kdyq24x23vtawwb5knkz7wh5yesamsoy",
        "display_name": "Swiss Whale Intelligence 🇨🇭",
        "id": "did:plc:hlod3gl5ewwglnr4yarddcrk",
        "is_verified": false,
        "url": "https://bsky.app/profile/btcwhalealerts.com",
        "username": "btcwhalealerts.com"
      },
      "coauthors": [],
      "duration_ms": null,
      "hashtags": [
        "Bitcoin",
        "Crypto"
      ],
      "id": "at://did:plc:hlod3gl5ewwglnr4yarddcrk/app.bsky.feed.post/3mzjyfostuj2n",
      "is_nsfw": false,
      "is_pinned": null,
      "is_sponsored": null,
      "language": "en",
      "media": [],
      "mentions": [],
      "metrics": {
        "comment_count": 0,
        "like_count": 0,
        "quote_count": 0,
        "repost_count": 0,
        "save_count": 0,
        "share_count": null,
        "view_count": null
      },
      "platform": "bluesky",
      "platform_specific": {
        "bluesky": {
          "bridged_from_url": null,
          "cid": "bafyreiduygaoktbbpfbii3ds5d4nkmu5c3yfjwqvlwkeqzrhoxa5gxpgvy",
          "created_at": "2026-11-05T04:04:24Z",
          "embedded_record_uri": null,
          "indexed_at": "2026-11-05T04:04:24Z",
          "labels": [],
          "languages": [
            "en"
          ],
          "link_card": null,
          "links": [
            "https://swisswhaleintelligence.com/tx/8b044d3165b582ac112c14b3afc7ff017dba8bd3f124b03dbbf9912a27e0bfaa"
          ],
          "quoted_post": null,
          "quoted_post_id": null,
          "reply_root_post_id": null,
          "reply_to_post_id": null,
          "reposted_at": null,
          "reposted_by": null
        }
      },
      "platform_type": null,
      "published_at": "2026-11-05T04:04:24Z",
      "text": "🐳 4,259 BTC ($343.7M) whale transfer\nPast similar activity: avg -2.2% price drop 72h after.\n\nhttps://swisswhaleintelligence.com/tx/8b044d3165b582ac112c14b3afc7ff017dba8bd3f124b03dbbf9912a27e0bfaa #Bitcoin #Crypto",
      "thumbnail_url": null,
      "title": null,
      "type": "text",
      "unknown_fields": [],
      "url": "https://bsky.app/profile/btcwhalealerts.com/post/3mzjyfostuj2n"
    },
    {
      "approximate_fields": [],
      "author": {
        "avatar_url": "https://cdn.bsky.app/img/avatar/plain/did:plc:pnmlwvud7rkanzzns5nanon6/bafkreibjn6xzku5qrjmp4s7abkf753wh5h7youodu7jgynnwtnwtbl2ciu",
        "display_name": "Pandavana Crypto News",
        "id": "did:plc:pnmlwvud7rkanzzns5nanon6",
        "is_verified": false,
        "url": "https://bsky.app/profile/pandacrypto.bsky.social",
        "username": "pandacrypto.bsky.social"
      },
      "coauthors": [],
      "duration_ms": null,
      "hashtags": [
        "Crypto",
        "Solana"
      ],
      "id": "at://did:plc:pnmlwvud7rkanzzns5nanon6/app.bsky.feed.post/3mzjyf2labq2g",
      "is_nsfw": false,
      "is_pinned": null,
      "is_sponsored": null,
      "language": null,
      "media": [],
      "mentions": [],
      "metrics": {
        "comment_count": 0,
        "like_count": 0,
        "quote_count": 0,
        "repost_count": 0,
        "save_count": 0,
        "share_count": null,
        "view_count": null
      },
      "platform": "bluesky",
      "platform_specific": {
        "bluesky": {
          "bridged_from_url": null,
          "cid": "bafyreibohrvfnua3lpwuaqnnfssupil4q64mrmtzlktlqchfuqzrnubx3e",
          "created_at": "2026-11-05T04:04:02Z",
          "embedded_record_uri": null,
          "indexed_at": "2026-11-05T04:04:03Z",
          "labels": [],
          "languages": [],
          "link_card": null,
          "links": [],
          "quoted_post": null,
          "quoted_post_id": null,
          "reply_root_post_id": null,
          "reply_to_post_id": null,
          "reposted_at": null,
          "reposted_by": null
        }
      },
      "platform_type": null,
      "published_at": "2026-11-05T04:04:02Z",
      "text": "#Crypto Prices:\r\n\r\nBitcoin $80,414.50\r\nEthereum $2,418.80\r\nXRP $1.31\r\n#Solana $96.16\r\nSui $0.93\r\n\r\n\r\n",
      "thumbnail_url": null,
      "title": null,
      "type": "text",
      "unknown_fields": [],
      "url": "https://bsky.app/profile/pandacrypto.bsky.social/post/3mzjyf2labq2g"
    },
    {
      "approximate_fields": [],
      "author": {
        "avatar_url": "https://cdn.bsky.app/img/avatar/plain/did:plc:vjpyc66fyniyqp2v6j7mxdvm/bafkreicg6htpnqv6cih6dhdxemkzugqmg4sqpgsfys5stz74ckwocynnoi",
        "display_name": "miatone.bsky.social",
        "id": "did:plc:vjpyc66fyniyqp2v6j7mxdvm",
        "is_verified": false,
        "url": "https://bsky.app/profile/miatone.bsky.social",
        "username": "miatone.bsky.social"
      },
      "coauthors": [],
      "duration_ms": null,
      "hashtags": [],
      "id": "at://did:plc:vjpyc66fyniyqp2v6j7mxdvm/app.bsky.feed.post/3mzjya6ieog2l",
      "is_nsfw": false,
      "is_pinned": null,
      "is_sponsored": null,
      "language": null,
      "media": [],
      "mentions": [],
      "metrics": {
        "comment_count": 0,
        "like_count": 0,
        "quote_count": 0,
        "repost_count": 0,
        "save_count": 0,
        "share_count": null,
        "view_count": null
      },
      "platform": "bluesky",
      "platform_specific": {
        "bluesky": {
          "bridged_from_url": null,
          "cid": "bafyreib4vxlqmmhsycxfkhzj27k4466dgooh2rbmiod3gqf2bey3ryiqxu",
          "created_at": "2026-11-05T04:01:18Z",
          "embedded_record_uri": null,
          "indexed_at": "2026-11-05T04:01:19Z",
          "labels": [],
          "languages": [],
          "link_card": null,
          "links": [],
          "quoted_post": null,
          "quoted_post_id": null,
          "reply_root_post_id": null,
          "reply_to_post_id": null,
          "reposted_at": null,
          "reposted_by": null
        }
      },
      "platform_type": null,
      "published_at": "2026-11-05T04:01:18Z",
      "text": "This caught my attention today: Nearly $1 Billion in Crypto Liquidations Hit as Bitcoin Jumps 4.6%",
      "thumbnail_url": null,
      "title": null,
      "type": "text",
      "unknown_fields": [],
      "url": "https://bsky.app/profile/miatone.bsky.social/post/3mzjya6ieog2l"
    }
  ],
  "page": {
    "has_more": true,
    "next_cursor": "c1.EXAMPLE_CURSOR",
    "next_cursor_expires_at": "2026-10-26T12:00:00Z",
    "end_reason": null
  },
  "meta": {
    "request_id": "req_3f9c2a7d1e8b4c6a9f0e2d4b6a8c0e1f",
    "platform": "bluesky",
    "source": "api",
    "is_cached": false,
    "credits_charged": 1,
    "latency_ms": 560,
    "fetched_at": "2026-10-25T12:00:00Z",
    "input": null,
    "credits_remaining": 9999,
    "client_request_id": null,
    "warnings": []
  }
}
```

Long arrays and strings are shortened here. Real responses are complete.

## One schema on 21 platforms.

The [response reference](https://socialtap.dev/docs/reference/bluesky/search_posts/index.md#response) lists every field, its type and when it is `null`. [See the full schema](https://socialtap.dev/resources/post/index.md).

- ### Null means unknown

  A field Bluesky doesn't show is null, never zero or an empty string, so a real zero always means zero.
- ### What it accepts

  Words to find posts by, as Bluesky's search reads them: a topic, a phrase in quotes, a #hashtag or an @handle, and a leading - leaves a word out (climate change, "coffee roaster" -bean, #atproto).
- ### Write one parser

  Bluesky, TikTok, Instagram and 18 more platforms answer in these fields, so the code that reads one reads them all.

- **`platform`string**: Platform ID (tiktok, youtube, …).
- **`id`string**: Platform-native post ID (string; Instagram shortcode, Reddit with its t3_ prefix).
- **`url`string**: Canonical post URL.
- **`type`string**: Normalized content shape. New values may be added; treat unknown values as other.
- **`platform_type`string**: The platform's own product label, lowercase (reel, short, story, live, tweet, …).
- **`title`string**: Headline (YouTube title, Reddit title); null on caption-only platforms.
- **`text`string**: Caption, description or body as plain text.
- **`language`string**: BCP-47 language of text, when the platform states it.

Live data from 33 platforms.

[TikTok](https://socialtap.dev/apis/tiktok/index.md) · [Instagram](https://socialtap.dev/apis/instagram/index.md) · [Facebook](https://socialtap.dev/apis/facebook/index.md) · [YouTube](https://socialtap.dev/apis/youtube/index.md) · [Reddit](https://socialtap.dev/apis/reddit/index.md) · [Threads](https://socialtap.dev/apis/threads/index.md) · [Spotify](https://socialtap.dev/apis/spotify/index.md) · [Amazon](https://socialtap.dev/apis/amazon/index.md) · [Apple Music](https://socialtap.dev/apis/applemusic/index.md) · [Pinterest](https://socialtap.dev/apis/pinterest/index.md) · [Rumble](https://socialtap.dev/apis/rumble/index.md) · [X](https://socialtap.dev/apis/x/index.md) · [Bluesky](https://socialtap.dev/apis/bluesky/index.md) · [Twitch](https://socialtap.dev/apis/twitch/index.md) · [LinkedIn](https://socialtap.dev/apis/linkedin/index.md) · [Telegram](https://socialtap.dev/apis/telegram/index.md) · [TikTok Shop](https://socialtap.dev/apis/tiktokshop/index.md) · [Kwai](https://socialtap.dev/apis/kwai/index.md) · [Snapchat](https://socialtap.dev/apis/snapchat/index.md) · [SoundCloud](https://socialtap.dev/apis/soundcloud/index.md) · [Truth Social](https://socialtap.dev/apis/truthsocial/index.md) · [Kick](https://socialtap.dev/apis/kick/index.md) · [Komi](https://socialtap.dev/apis/komi/index.md) · [Lnk.Bio](https://socialtap.dev/apis/linkbio/index.md) · [Linkme](https://socialtap.dev/apis/linkme/index.md) · [Linktree](https://socialtap.dev/apis/linktree/index.md) · [Pillar](https://socialtap.dev/apis/pillar/index.md) · [TikTok Ad Library](https://socialtap.dev/apis/tiktok-ad-library/index.md) · [Facebook Ad Library](https://socialtap.dev/apis/facebook-ad-library/index.md) · [Facebook Events](https://socialtap.dev/apis/facebook-events/index.md) · [Facebook Marketplace](https://socialtap.dev/apis/facebook-marketplace/index.md) · [Google Ads Transparency Center](https://socialtap.dev/apis/google-ads-transparency/index.md) · [LinkedIn Ad Library](https://socialtap.dev/apis/linkedin-ad-library/index.md)

## What teams build with the Bluesky Post Search API.

- ### Track what people say about a brand
- ### Collect posts with a hashtag or mention
- ### Search one account's posts for a subject
- ### Find who links to a site or page
- ### Study a subject by language and date

## Good to know before you build.

- Results come from Bluesky's own search, read without a login. Bluesky's app offers search only to signed-in people, so Bluesky could close this route, and the endpoint would then answer from the web search fallback below.
- When Bluesky's search doesn't answer, the first page comes from a public web search's index instead, with each post it finds read from Bluesky, so its fields stay full. A partial_data warning names the sort and filters it couldn't fully apply. That list holds only what the index has, often a small part of what Bluesky has and very little on rare words, non-Latin text or recent dates, in the engine's ranking rather than the order you asked for.
- If Bluesky's other routes are down too, the posts are what the index shows of them: id names the author as the link does, type reads text, text is the index's copy and can be cut short, the time comes from the post's record key, and the warning lists the fields left null. Repeat the request later for the full answer.
- A next_cursor continues the list it came from. If Bluesky's search stops answering partway through a walk, that page fails with a retryable error rather than continue on a different list. Start without the cursor for the fallback's list.
- A post whose author chose to be seen only by signed-in people is left out, as everywhere on Bluesky without a login, so a page can hold fewer posts than its limit, or none, and still have a next_cursor. On some searches that is a large share of the results, above all in Japanese. Bluesky's search also hides a few posts of its own.
- sort=newest goes by the time each post states, to the second, as Bluesky's search does, so a post imported from elsewhere or with a wrong clock can sit out of order by published_at. since and until filter by that time and then by published_at, so an imported post whose published_at lies outside them is left out.
- When more posts share one second than a page holds, the walk goes on past that second without the rest, and that page says so with an items_omitted warning.
- sort=popular serves one page, because Bluesky doesn't serve its Top ranking further, and the page ends with platform_limit.
- An author, mention or tag nobody has returns an empty page, not an error, as Bluesky's search does. mentions matches posts that really link the account, and an @handle in the query is read the same way.
- Case does not matter. The query's own site: operators are removed, and intitle:, inurl:, in: and operators like them are read as the plain words they name.

## 1 credit per page. Failed requests are free.

Buy credits once and spend them on any endpoint, on any platform.

[Plans and packs](https://socialtap.dev/pricing/index.md) · [How this endpoint is priced](https://socialtap.dev/docs/reference/bluesky/search_posts/index.md#pricing) · [How credits work](https://socialtap.dev/docs/credits/index.md)

| Source | Price per successful page | Per 1,000 pages |
| --- | --- | --- |
| Any source | 1 credit | $0.75–$1.97 |

- Cache hits are free.
- Credits from packs and top-ups never expire.
- A monthly plan's credits are spent first, and what is left of them ends at each renewal.
- Prices exclude tax: sales tax is added at checkout where it applies.
- Outside the US, plans and packs are sold to businesses: checkout asks for your VAT, GST or other business tax ID.

## Questions about the Bluesky Post Search API.

More in the [API reference](https://socialtap.dev/docs/reference/bluesky/search_posts/index.md).

**Can I search by hashtag, author or link?**

Yes. Send tag, author, mentions, domain or links_to, or write Bluesky's own operators (from:, mentions:, lang:, since:) in the query, which are read as those params.

**How much does the Bluesky Post Search API cost?**

A page of up to 100 posts costs 1 credit. Every successful page is charged, empty pages included. SocialTap credits cost $0.75–$1.97 per 1,000, depending on the plan or pack.

**How do I get the next page?**

Repeat the same request with cursor set to page.next_cursor from the previous response, keeping the other parameters. When page.has_more is false there are no more pages. Cursors expire after 24 hours.

Other platforms

## Posts on 20 more platforms.

- [TikTok Search API](https://socialtap.dev/apis/tiktok/search_posts/index.md) (1 credit / page · `GET /v1/tiktok/search_posts`)
- [Instagram Search API](https://socialtap.dev/apis/instagram/search_posts/index.md) (1 credit / page · `GET /v1/instagram/search_posts`)
- [Facebook Post API](https://socialtap.dev/apis/facebook/post/index.md) (1 credit · `GET /v1/facebook/post`)
- [YouTube Video API](https://socialtap.dev/apis/youtube/post/index.md) (1 credit · `GET /v1/youtube/post`)
- [Reddit Search API](https://socialtap.dev/apis/reddit/search_posts/index.md) (1 credit / page · `GET /v1/reddit/search_posts`)
- [Threads Search API](https://socialtap.dev/apis/threads/search_posts/index.md) (1 credit / page · `GET /v1/threads/search_posts`)
- [Spotify Track API](https://socialtap.dev/apis/spotify/track/index.md) (1 credit · `GET /v1/spotify/track`)
- [Amazon Shop Posts API](https://socialtap.dev/apis/amazon/shop_posts/index.md) (1 credit / page · `GET /v1/amazon/shop_posts`)
- [Apple Music Track API](https://socialtap.dev/apis/applemusic/track/index.md) (1 credit · `GET /v1/applemusic/track`)
- [Pinterest Pin API](https://socialtap.dev/apis/pinterest/pin/index.md) (1 credit · `GET /v1/pinterest/pin`)
- [Rumble Search API](https://socialtap.dev/apis/rumble/search_posts/index.md) (1 credit / page · `GET /v1/rumble/search_posts`)
- [X (Twitter) Post API](https://socialtap.dev/apis/x/post/index.md) (1 credit · `GET /v1/x/post`)
- [Twitch Video and Clip API](https://socialtap.dev/apis/twitch/video/index.md) (1 credit · `GET /v1/twitch/video`)
- [LinkedIn Post API](https://socialtap.dev/apis/linkedin/post/index.md) (1 credit · `GET /v1/linkedin/post`)
- [Telegram Post API](https://socialtap.dev/apis/telegram/post/index.md) (1 credit · `GET /v1/telegram/post`)
- [Kwai Post API](https://socialtap.dev/apis/kwai/post/index.md) (1 credit · `GET /v1/kwai/post`)
- [Snapchat Spotlight API](https://socialtap.dev/apis/snapchat/spotlight/index.md) (1 credit · `GET /v1/snapchat/spotlight`)
- [SoundCloud Track API](https://socialtap.dev/apis/soundcloud/track/index.md) (1 credit · `GET /v1/soundcloud/track`)
- [Truth Social Post API](https://socialtap.dev/apis/truthsocial/post/index.md) (1 credit · `GET /v1/truthsocial/post`)
- [Kick Clip API](https://socialtap.dev/apis/kick/post/index.md) (1 credit · `GET /v1/kick/post`)

More Bluesky

## Bluesky API. 5 endpoints, one key.

- [Bluesky Post API](https://socialtap.dev/apis/bluesky/post/index.md) (1 credit · `GET /v1/bluesky/post`)
- [Bluesky User Posts API](https://socialtap.dev/apis/bluesky/posts/index.md) (1 credit / page · `GET /v1/bluesky/posts`)
- [Bluesky Profile API](https://socialtap.dev/apis/bluesky/profile/index.md) (1 credit · `GET /v1/bluesky/profile`)
- [Bluesky Comments API](https://socialtap.dev/apis/bluesky/comments/index.md) (1 credit / page · `GET /v1/bluesky/comments`)

## Try it with your own search.

Type it in the playground, or copy the request into your code.

100free credits

- No credit card
- Failed requests are free
- Works on all 218 endpoints

[Start for free](https://socialtap.dev/signup/) [Read the docs](https://socialtap.dev/docs/index.md)

---

[HTML version](https://socialtap.dev/apis/bluesky/search_posts/) · [Docs index for AI agents](https://socialtap.dev/llms.txt) · [All docs in one file](https://socialtap.dev/llms-full.txt)
