curl --request GET \
--url https://api.scraperize.com/v1/bluesky/post \
--header 'x-api-key: <api-key>'import requests
url = "https://api.scraperize.com/v1/bluesky/post"
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/post', 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/post",
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/post"
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/post")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scraperize.com/v1/bluesky/post")
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": {
"post": {
"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": []
},
"thread": {
"ancestors": [],
"hasMoreAncestors": false,
"isAuthorThread": true,
"hiddenByThreadgate": false
},
"fetchedAt": "2026-10-17T19:15:45.046Z"
},
"meta": {
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f",
"creditsCharged": 1,
"creditsRemaining": 4999,
"cached": false
}
}{
"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"
}
}Post
Fetches a public Bluesky post by URL: its text, hashtags, mentions and links, language, the author, like / repost / reply / quote / bookmark counts, images, video or link preview, the quoted post (or embedded feed, list or starter pack), reply restrictions and content labels — plus its thread context: for a reply, the parent and root posts and every post above it, root first, and whether it is part of the author’s own thread.
curl --request GET \
--url https://api.scraperize.com/v1/bluesky/post \
--header 'x-api-key: <api-key>'import requests
url = "https://api.scraperize.com/v1/bluesky/post"
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/post', 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/post",
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/post"
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/post")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scraperize.com/v1/bluesky/post")
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": {
"post": {
"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": []
},
"thread": {
"ancestors": [],
"hasMoreAncestors": false,
"isAuthorThread": true,
"hiddenByThreadgate": false
},
"fetchedAt": "2026-10-17T19:15:45.046Z"
},
"meta": {
"requestId": "req_8f0c2b7e-1a2b-4c3d-9e8f-0a1b2c3d4e5f",
"creditsCharged": 1,
"creditsRemaining": 4999,
"cached": false
}
}{
"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/post. Here are the details:
Endpoint: GET https://api.scraperize.com/v1/bluesky/post
Description: Fetches a public Bluesky post by URL: its text, hashtags, mentions and links, language, the author, like / repost / reply / quote / bookmark counts, images, video or link preview, the quoted post (or embedded feed, list or starter pack), reply restrictions and content labels — plus its thread context: for a reply, the parent and root posts and every post above it, root first, and whether it is part of the author’s own thread.
Required Headers:
- x-api-key: Your API key
Parameters:
- url (string) [required]: Bluesky post link, e.g. `https://bsky.app/profile/espn.com/post/3muznlkmspz2x` (the handle or the DID form both work; the post’s `at://` URI is accepted too).
- 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": {
"post": {
"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": []
},
"thread": {
"ancestors": [],
"hasMoreAncestors": false,
"isAuthorThread": true,
"hiddenByThreadgate": false
},
"fetchedAt": "2026-10-17T19:15:45.046Z"
},
"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 post link, e.g. https://bsky.app/profile/espn.com/post/3muznlkmspz2x (the handle or the DID form both work; the post’s at:// URI is accepted too).
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