curl --request GET \
--url https://api.scraperize.com/v1/bluesky/user/posts \
--header 'x-api-key: <api-key>'import requests
url = "https://api.scraperize.com/v1/bluesky/user/posts"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.scraperize.com/v1/bluesky/user/posts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.scraperize.com/v1/bluesky/user/posts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.scraperize.com/v1/bluesky/user/posts"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.scraperize.com/v1/bluesky/user/posts")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scraperize.com/v1/bluesky/user/posts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"user": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"posts": [
{
"id": "3muznlkmspz2x",
"uri": "at://did:plc:x7d6j54pm22ufehkes6jo4jf/app.bsky.feed.post/3muznlkmspz2x",
"cid": "bafyreiceaay7jrgqznvxhttsmizofewx3mj6bwebjtz76nd2wh4hix4fty",
"url": "https://bsky.app/profile/espn.com/post/3muznlkmspz2x",
"text": "One more sleep until NFL football is BACK. 🏈",
"createdAt": "2026-09-08T18:27:24.700Z",
"indexedAt": "2026-09-08T18:27:30.159Z",
"langs": [],
"tags": [],
"via": null,
"hashtags": [],
"mentions": [],
"links": [],
"author": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"likeCount": 100,
"repostCount": 11,
"replyCount": 11,
"quoteCount": 6,
"bookmarkCount": 0,
"media": {
"images": [],
"video": {
"playlistUrl": "https://video.bsky.app/watch/did%3Aplc%3Ax7d6j54pm22ufehkes6jo4jf/bafkreiflqivgi6afl5jv4qnmwzo3ks7jwe2dfurohsjfgafbtd5crw4gaq/playlist.m3u8",
"thumbnailUrl": "https://video.bsky.app/watch/did%3Aplc%3Ax7d6j54pm22ufehkes6jo4jf/bafkreiflqivgi6afl5jv4qnmwzo3ks7jwe2dfurohsjfgafbtd5crw4gaq/thumbnail.jpg",
"alt": null,
"width": null,
"height": null
},
"link": null
},
"quote": null,
"embeddedRecord": null,
"isReply": false,
"reply": null,
"isRepost": false,
"repostedBy": null,
"repostedAt": null,
"isPinned": false,
"threadPostIndex": null,
"threadPostCount": null,
"replySettings": null,
"labels": []
},
{
"id": "3mpglmolczz2w",
"uri": "at://did:plc:x7d6j54pm22ufehkes6jo4jf/app.bsky.feed.post/3mpglmolczz2w",
"cid": "bafyreid2eoctnshw7unb5ozrjqsy63kpqmwwvhj2xuxsfo4z5zucfazqum",
"url": "https://bsky.app/profile/espn.com/post/3mpglmolczz2w",
"text": "Former Tennessee Titans and Arizona Cardinals running back Chris Johnson revealed that he has been diagnosed with ALS in an interview with ABC's \"Good Morning America\".\n\nJohnson, 39, told GMA co-anchor Michael Strahan that he was diagnosed with the disease in 2025.",
"createdAt": "2026-06-29T13:25:44.562Z",
"indexedAt": "2026-06-29T13:25:45.268Z",
"langs": [],
"tags": [],
"via": null,
"hashtags": [],
"mentions": [],
"links": [],
"author": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"likeCount": 137,
"repostCount": 34,
"replyCount": 16,
"quoteCount": 17,
"bookmarkCount": 1,
"media": {
"images": [],
"video": null,
"link": {
"url": "http://spr.ly/63329BDvG6W",
"title": "Former NFL RB Chris Johnson discusses ALS diagnosis",
"description": "Former Titans and Cardinals running back Chris Johnson told \"Good Morning America\" that he was diagnosed with ALS in 2025.",
"thumbnailUrl": "https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreicgzhnme4wgvolagtic3dki5icwfkmlxz23cmakg2mj2h4xkwvg2q"
}
},
"quote": null,
"embeddedRecord": null,
"isReply": false,
"reply": null,
"isRepost": false,
"repostedBy": null,
"repostedAt": null,
"isPinned": false,
"threadPostIndex": null,
"threadPostCount": null,
"replySettings": null,
"labels": []
},
{
"id": "3mov4cob7hn2x",
"uri": "at://did:plc:x7d6j54pm22ufehkes6jo4jf/app.bsky.feed.post/3mov4cob7hn2x",
"cid": "bafyreihvnizv4s2h72qtu2cbglugxldzs32rbctwfcj73mrc4mevvn5ux4",
"url": "https://bsky.app/profile/espn.com/post/3mov4cob7hn2x",
"text": "Breaking: Michigan coach Dusty May is finalizing a deal to take the Dallas Mavericks head coaching job, sources tell Pete Thamel, Shams Charania and Adam Schefter.",
"createdAt": "2026-06-22T14:36:26.839Z",
"indexedAt": "2026-06-22T14:36:28.062Z",
"langs": [],
"tags": [],
"via": null,
"hashtags": [],
"mentions": [],
"links": [],
"author": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"likeCount": 145,
"repostCount": 25,
"replyCount": 15,
"quoteCount": 57,
"bookmarkCount": 2,
"media": {
"images": [
{
"url": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreihdlyxrpv3lvnxk6vi6x5tbewwj7o3ix7wkcxgfgetqukqxfbefta",
"thumbnailUrl": "https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreihdlyxrpv3lvnxk6vi6x5tbewwj7o3ix7wkcxgfgetqukqxfbefta",
"alt": "Michigan men's basketball coach Dusty May is finalizing a deal to take the Dallas Mavericks head coaching job, sources tell Pete Thamel, Shams Charania and Adam Schefter.",
"width": 720,
"height": 900
}
],
"video": null,
"link": null
},
"quote": null,
"embeddedRecord": null,
"isReply": false,
"reply": null,
"isRepost": false,
"repostedBy": null,
"repostedAt": null,
"isPinned": false,
"threadPostIndex": null,
"threadPostCount": null,
"replySettings": null,
"labels": []
}
],
"count": 30,
"cursor": "2025-09-25T17:06:11.912Z",
"hasMore": true,
"fetchedAt": "2026-10-17T19:15:44.136Z"
},
"meta": {
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f",
"creditsCharged": 1,
"creditsRemaining": 4999,
"cached": false
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "The request was invalid.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "API key required — pass it in the `x-api-key` header.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "This request costs 1 credit, but your balance is 0. Top up to continue.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "The requested content was not found (it may not exist, be deleted, or be private).",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f",
"details": [
{
"path": "url",
"message": "url is required"
}
]
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded — max 100 requests per 60s. Retry in ~30s.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "UPSTREAM_BLOCKED",
"message": "The source is temporarily unavailable. Please try again shortly.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}User posts
An account’s posts, newest first, as on its profile’s Posts tab: its posts, reposts and its own threads, with the pinned post first on page 1. About 30 per page, with a cursor for the next page. Each post has its text, hashtags, mentions and links, the author, like / repost / reply / quote / bookmark counts, images, video or link preview, the quoted post (or embedded feed, list or starter pack), reply context (parent, root and grandparent author), who reposted it and when, reply restrictions and content labels.
Pass exactly one of handle or userId.
curl --request GET \
--url https://api.scraperize.com/v1/bluesky/user/posts \
--header 'x-api-key: <api-key>'import requests
url = "https://api.scraperize.com/v1/bluesky/user/posts"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.scraperize.com/v1/bluesky/user/posts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.scraperize.com/v1/bluesky/user/posts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.scraperize.com/v1/bluesky/user/posts"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.scraperize.com/v1/bluesky/user/posts")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scraperize.com/v1/bluesky/user/posts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"user": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"posts": [
{
"id": "3muznlkmspz2x",
"uri": "at://did:plc:x7d6j54pm22ufehkes6jo4jf/app.bsky.feed.post/3muznlkmspz2x",
"cid": "bafyreiceaay7jrgqznvxhttsmizofewx3mj6bwebjtz76nd2wh4hix4fty",
"url": "https://bsky.app/profile/espn.com/post/3muznlkmspz2x",
"text": "One more sleep until NFL football is BACK. 🏈",
"createdAt": "2026-09-08T18:27:24.700Z",
"indexedAt": "2026-09-08T18:27:30.159Z",
"langs": [],
"tags": [],
"via": null,
"hashtags": [],
"mentions": [],
"links": [],
"author": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"likeCount": 100,
"repostCount": 11,
"replyCount": 11,
"quoteCount": 6,
"bookmarkCount": 0,
"media": {
"images": [],
"video": {
"playlistUrl": "https://video.bsky.app/watch/did%3Aplc%3Ax7d6j54pm22ufehkes6jo4jf/bafkreiflqivgi6afl5jv4qnmwzo3ks7jwe2dfurohsjfgafbtd5crw4gaq/playlist.m3u8",
"thumbnailUrl": "https://video.bsky.app/watch/did%3Aplc%3Ax7d6j54pm22ufehkes6jo4jf/bafkreiflqivgi6afl5jv4qnmwzo3ks7jwe2dfurohsjfgafbtd5crw4gaq/thumbnail.jpg",
"alt": null,
"width": null,
"height": null
},
"link": null
},
"quote": null,
"embeddedRecord": null,
"isReply": false,
"reply": null,
"isRepost": false,
"repostedBy": null,
"repostedAt": null,
"isPinned": false,
"threadPostIndex": null,
"threadPostCount": null,
"replySettings": null,
"labels": []
},
{
"id": "3mpglmolczz2w",
"uri": "at://did:plc:x7d6j54pm22ufehkes6jo4jf/app.bsky.feed.post/3mpglmolczz2w",
"cid": "bafyreid2eoctnshw7unb5ozrjqsy63kpqmwwvhj2xuxsfo4z5zucfazqum",
"url": "https://bsky.app/profile/espn.com/post/3mpglmolczz2w",
"text": "Former Tennessee Titans and Arizona Cardinals running back Chris Johnson revealed that he has been diagnosed with ALS in an interview with ABC's \"Good Morning America\".\n\nJohnson, 39, told GMA co-anchor Michael Strahan that he was diagnosed with the disease in 2025.",
"createdAt": "2026-06-29T13:25:44.562Z",
"indexedAt": "2026-06-29T13:25:45.268Z",
"langs": [],
"tags": [],
"via": null,
"hashtags": [],
"mentions": [],
"links": [],
"author": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"likeCount": 137,
"repostCount": 34,
"replyCount": 16,
"quoteCount": 17,
"bookmarkCount": 1,
"media": {
"images": [],
"video": null,
"link": {
"url": "http://spr.ly/63329BDvG6W",
"title": "Former NFL RB Chris Johnson discusses ALS diagnosis",
"description": "Former Titans and Cardinals running back Chris Johnson told \"Good Morning America\" that he was diagnosed with ALS in 2025.",
"thumbnailUrl": "https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreicgzhnme4wgvolagtic3dki5icwfkmlxz23cmakg2mj2h4xkwvg2q"
}
},
"quote": null,
"embeddedRecord": null,
"isReply": false,
"reply": null,
"isRepost": false,
"repostedBy": null,
"repostedAt": null,
"isPinned": false,
"threadPostIndex": null,
"threadPostCount": null,
"replySettings": null,
"labels": []
},
{
"id": "3mov4cob7hn2x",
"uri": "at://did:plc:x7d6j54pm22ufehkes6jo4jf/app.bsky.feed.post/3mov4cob7hn2x",
"cid": "bafyreihvnizv4s2h72qtu2cbglugxldzs32rbctwfcj73mrc4mevvn5ux4",
"url": "https://bsky.app/profile/espn.com/post/3mov4cob7hn2x",
"text": "Breaking: Michigan coach Dusty May is finalizing a deal to take the Dallas Mavericks head coaching job, sources tell Pete Thamel, Shams Charania and Adam Schefter.",
"createdAt": "2026-06-22T14:36:26.839Z",
"indexedAt": "2026-06-22T14:36:28.062Z",
"langs": [],
"tags": [],
"via": null,
"hashtags": [],
"mentions": [],
"links": [],
"author": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"likeCount": 145,
"repostCount": 25,
"replyCount": 15,
"quoteCount": 57,
"bookmarkCount": 2,
"media": {
"images": [
{
"url": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreihdlyxrpv3lvnxk6vi6x5tbewwj7o3ix7wkcxgfgetqukqxfbefta",
"thumbnailUrl": "https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreihdlyxrpv3lvnxk6vi6x5tbewwj7o3ix7wkcxgfgetqukqxfbefta",
"alt": "Michigan men's basketball coach Dusty May is finalizing a deal to take the Dallas Mavericks head coaching job, sources tell Pete Thamel, Shams Charania and Adam Schefter.",
"width": 720,
"height": 900
}
],
"video": null,
"link": null
},
"quote": null,
"embeddedRecord": null,
"isReply": false,
"reply": null,
"isRepost": false,
"repostedBy": null,
"repostedAt": null,
"isPinned": false,
"threadPostIndex": null,
"threadPostCount": null,
"replySettings": null,
"labels": []
}
],
"count": 30,
"cursor": "2025-09-25T17:06:11.912Z",
"hasMore": true,
"fetchedAt": "2026-10-17T19:15:44.136Z"
},
"meta": {
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f",
"creditsCharged": 1,
"creditsRemaining": 4999,
"cached": false
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "The request was invalid.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "API key required — pass it in the `x-api-key` header.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "This request costs 1 credit, but your balance is 0. Top up to continue.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "The requested content was not found (it may not exist, be deleted, or be private).",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f",
"details": [
{
"path": "url",
"message": "url is required"
}
]
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded — max 100 requests per 60s. Retry in ~30s.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}{
"error": {
"code": "UPSTREAM_BLOCKED",
"message": "The source is temporarily unavailable. Please try again shortly.",
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f"
}
}cache_max_age) are free.Copy for AI assistant
Copy for AI assistant
I want to make an API call to /v1/bluesky/user/posts. Here are the details:
Endpoint: GET https://api.scraperize.com/v1/bluesky/user/posts
Description: An account's posts, newest first, as on its profile's Posts tab: its posts, reposts and its own threads, with the pinned post first on page 1. About 30 per page, with a `cursor` for the next page. Each post has its text, hashtags, mentions and links, the author, like / repost / reply / quote / bookmark counts, images, video or link preview, the quoted post (or embedded feed, list or starter pack), reply context (parent, root and grandparent author), who reposted it and when, reply restrictions and content labels.
Required Headers:
- x-api-key: Your API key
Parameters:
- handle (string): Bluesky handle, e.g. `espn.com` or `name.bsky.social` (a leading `@` or a `bsky.app/profile/...` URL also work). Required unless `userId` is given.
- userId (string): The account DID, e.g. `did:plc:x7d6j54pm22ufehkes6jo4jf`. Required unless `handle` is given.
- cursor (string): The `cursor` from the previous page, to get the next one.
- cache_max_age (select): Optional. Return a cached result if one this age or newer exists — served for **0 credits** with `meta.cached=true` and `meta.cachedAt`. Otherwise a fresh scrape runs (**1 credit**) and refreshes the cache. Omit to always scrape fresh.
Example Response:
{
"data": {
"user": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"posts": [
{
"id": "3muznlkmspz2x",
"uri": "at://did:plc:x7d6j54pm22ufehkes6jo4jf/app.bsky.feed.post/3muznlkmspz2x",
"cid": "bafyreiceaay7jrgqznvxhttsmizofewx3mj6bwebjtz76nd2wh4hix4fty",
"url": "https://bsky.app/profile/espn.com/post/3muznlkmspz2x",
"text": "One more sleep until NFL football is BACK. 🏈",
"createdAt": "2026-09-08T18:27:24.700Z",
"indexedAt": "2026-09-08T18:27:30.159Z",
"langs": [],
"tags": [],
"via": null,
"hashtags": [],
"mentions": [],
"links": [],
"author": {
"did": "did:plc:x7d6j54pm22ufehkes6jo4jf",
"handle": "espn.com",
"displayName": "ESPN",
"url": "https://bsky.app/profile/espn.com",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:x7d6j54pm22ufehkes6jo4jf/bafkreie4oxawqqsfzvk47ysr3unsnmviedzpylxmwxnpa534to2bzas4ie",
"pronouns": null,
"isVerified": true,
"labels": [],
"createdAt": "2024-11-25T21:49:49.345Z"
},
"likeCount": 100,
"repostCount": 11,
"replyCount": 11,
"quoteCount": 6,
"bookmarkCount": 0,
"media": {
"images": [],
"video": {
"playlistUrl": "https://video.bsky.app/watch/did%3Aplc%3Ax7d6j54pm22ufehkes6jo4jf/bafkreiflqivgi6afl5jv4qnmwzo3ks7jwe2dfurohsjfgafbtd5crw4gaq/playlist.m3u8",
"thumbnailUrl": "https://video.bsky.app/watch/did%3Aplc%3Ax7d6j54pm22ufehkes6jo4jf/bafkreiflqivgi6afl5jv4qnmwzo3ks7jwe2dfurohsjfgafbtd5crw4gaq/thumbnail.jpg",
"alt": null,
"width": null,
"height": null
},
"link": null
},
"quote": null,
"embeddedRecord": null,
"isReply": false,
"reply": null,
"isRepost": false,
"repostedBy": null,
"repostedAt": null,
"isPinned": false,
"threadPostIndex": null,
"threadPostCount": null,
"replySettings": null,
"labels": []
}
],
"count": 30,
"cursor": "2025-09-25T17:06:11.912Z",
"hasMore": true,
"fetchedAt": "2026-10-17T19:15:44.136Z"
},
"meta": {
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f",
"creditsCharged": 1,
"creditsRemaining": 4999,
"cached": false
}
}
Please help me write code in my preferred programming language to make this API call and handle the response appropriately. Include error handling and best practices.
Authorizations
Your API key. Send it in the x-api-key header (or Authorization: Bearer <key>). Create and manage keys from your dashboard.
Query Parameters
Bluesky handle, e.g. espn.com or name.bsky.social (a leading @ or a bsky.app/profile/... URL also work). Required unless userId is given.
The account DID, e.g. did:plc:x7d6j54pm22ufehkes6jo4jf. Required unless handle is given.
The cursor from the previous page, to get the next one.
Optional. Return a cached result if one this age or newer exists — served for 0 credits with meta.cached=true and meta.cachedAt. Otherwise a fresh scrape runs (1 credit) and refreshes the cache. Omit to always scrape fresh.
1d, 3d, 7d, 14d, 30d