Docs · Post
Post
A post with its replies (three levels deep) and the posts it replies to.
https://api.lurkapi.com/v1/bluesky/postWhen to use this
Use it to read a conversation: the post, its replies nested under replies, and parents from the thread's first post down to the one this post answers. Replies go three levels deep; pass a reply's uri as url to read further down.
Deleted posts and posts from accounts that block viewers are left out of replies; in parents, the chain stops below one.
A requested post hidden from logged-out visitors returns 403 not_public. Hidden replies and their branches are omitted, hidden quotes are null, and the parent chain stops below a hidden author.
Unknown and deleted posts return 404 not_found.
Parameters
All parameters go in the query string.
| Parameter | Description |
|---|---|
urlstringrequired | The post's URL, e.g. https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l, or its at:// URI.
|
Example request
Replace YOUR_API_KEY with your key, or set LURKAPI_KEY for the code. Get a free key.
curl "https://api.lurkapi.com/v1/bluesky/post?url=https%3A%2F%2Fbsky.app%2Fprofile%2Fbsky.app%2Fpost%2F3mtykea5kds2d" \
-H "x-api-key: YOUR_API_KEY"const params = new URLSearchParams({
url: "https://bsky.app/profile/bsky.app/post/3mtykea5kds2d",
});
const res = await fetch(`https://api.lurkapi.com/v1/bluesky/post?${params}`, {
headers: { "x-api-key": process.env.LURKAPI_KEY },
});
const data = await res.json();
if (!data.success) throw new Error(`${data.code}: ${data.error}`);
console.log(data.replies);import os
import requests
res = requests.get(
"https://api.lurkapi.com/v1/bluesky/post",
params={
"url": "https://bsky.app/profile/bsky.app/post/3mtykea5kds2d",
},
headers={"x-api-key": os.environ["LURKAPI_KEY"]},
timeout=60,
)
data = res.json()
if not data["success"]:
raise RuntimeError(f"{data['code']}: {data['error']}")
print(data["replies"])Example response
A real response from this endpoint, captured from the live API and trimmed to a couple of items. Strings over 96 characters (mostly signed media URLs) are cut short and end in ….
Show the example response (13 KB)Hide
{
"success": true,
"credits_remaining": 999985,
"credits_charged": 1,
"post": {
"uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtykea5kds2d",
"cid": "bafyreiekdsq4kh7go75zsdw7echsceb6zp2zczozoqoz3kcmtezievbdtu",
"url": "https://bsky.app/profile/bsky.app/post/3mtykea5kds2d",
"text": "NOW PLAYING: \"Flight over Jupiter\" by @kevinmgill.bsky.social",
"createdAt": "2026-08-26T14:31:49.108Z",
"author": {
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/b…"
},
"replyCount": 10,
"repostCount": 32,
"likeCount": 494,
"quoteCount": 0,
"bookmarkCount": 66,
"langs": [
"en"
],
"images": [],
"video": null,
"external": null,
"quote": {
"uri": "at://did:plc:we2butxgfrqjxqxztwznhrrv/app.bsky.feed.post/3mtw2mowtdc2q",
"url": "https://bsky.app/profile/kevinmgill.bsky.social/post/3mtw2mowtdc2q",
"text": "Take a relaxing flight with NASA's Juno Spacecraft as it passes over Jup…",
"createdAt": "2026-08-25T14:44:53.700Z",
"author": {
"did": "did:plc:we2butxgfrqjxqxztwznhrrv",
"handle": "kevinmgill.bsky.social",
"displayName": "Kevin M. Gill",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:we2butxgfrqjxqxztwznhrrv/b…"
}
},
"links": [],
"mentions": [
"kevinmgill.bsky.social"
],
"tags": [],
"replyTo": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtwm5grjns22"
},
"replies": [
{
"uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtyzbvfbb222",
"cid": "bafyreighwp7yizyb62fchduf2wta5xc5bubbjkn4552rvpyi4j4apunxsq",
"url": "https://bsky.app/profile/bsky.app/post/3mtyzbvfbb222",
"text": "NOW PLAYING: \"Tour of Western Railway BART Exhibit\" by @bart.gov",
"createdAt": "2026-08-26T18:58:56.845Z",
"author": {
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/b…"
},
"replyCount": 9,
"repostCount": 18,
"likeCount": 402,
"quoteCount": 2,
"bookmarkCount": 32,
"langs": [
"en"
],
"images": [],
"video": null,
"external": null,
"quote": {
"uri": "at://did:plc:qddhk5tchy7gdyws2l4srl47/app.bsky.feed.post/3mtwudf3uok27",
"url": "https://bsky.app/profile/bart.gov/post/3mtwudf3uok27",
"text": "Come take the full tour of the BART A, B and C Cars on display at the We…",
"createdAt": "2026-08-25T22:24:58.681Z",
"author": {
"did": "did:plc:qddhk5tchy7gdyws2l4srl47",
"handle": "bart.gov",
"displayName": "BART",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:qddhk5tchy7gdyws2l4srl47/b…"
}
},
"links": [],
"mentions": [
"bart.gov"
],
"tags": [],
"replyTo": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtykea5kds2d",
"replies": [
{
"uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtzbwnbvrs24",
"cid": "bafyreie4usq5gutvl7drrj6rliswozwzzmcei3qy7g6wyuxyobwb4wprdy",
"url": "https://bsky.app/profile/bsky.app/post/3mtzbwnbvrs24",
"text": "NOW PLAYING: \"Sludgecam\" by @neorsd.org",
"createdAt": "2026-08-26T21:33:42.923Z",
"author": {
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/b…"
},
"replyCount": 15,
"repostCount": 16,
"likeCount": 298,
"quoteCount": 0,
"bookmarkCount": 11,
"langs": [
"en"
],
"images": [],
"video": null,
"external": null,
"quote": {
"uri": "at://did:plc:itwimoiaj7qfal7hizju3syz/app.bsky.feed.post/3mtwwrztp622j",
"url": "https://bsky.app/profile/neorsd.org/post/3mtwwrztp622j",
"text": "longer videos on @bsky.app means i can finally post 10 full minutes of s…",
"createdAt": "2026-08-25T23:08:57.677Z",
"author": {
"did": "did:plc:itwimoiaj7qfal7hizju3syz",
"handle": "neorsd.org",
"displayName": "NE Ohio Regional Sewer District",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:itwimoiaj7qfal7hizju3syz/b…"
}
},
"links": [],
"mentions": [
"neorsd.org"
],
"tags": [],
"replyTo": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtyzbvfbb222",
"replies": [
{
"uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtzmdtsaw22w",
"cid": "bafyreie7xfzf65hhtseni2ppxs5q5mrjr5cyzawblhwuknvjcy2mc7kgny",
"url": "https://bsky.app/profile/bsky.app/post/3mtzmdtsaw22w",
"text": "NOW PLAYING: \"Taskmaster Fan Fiction (Greg's Christmas Feast)\" by @thehornesection.bsky.social",
"createdAt": "2026-08-27T00:40:03.375Z",
"author": {
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/b…"
},
"replyCount": 9,
"repostCount": 23,
"likeCount": 525,
"quoteCount": 3,
"bookmarkCount": 55,
"langs": [
"en"
],
"images": [],
"video": null,
"external": null,
"quote": {
"uri": "at://did:plc:sfytqb5ksdwbhen5jorylyf6/app.bsky.feed.post/3mtwakstrcc2k",
"url": "https://bsky.app/profile/thehornesection.bsky.social/post/3mtwakstrcc2k",
"text": "Throwback to when Alex found some Taskmaster fan fiction about him and G…",
"createdAt": "2026-08-25T16:31:13.139Z",
"author": {
"did": "did:plc:sfytqb5ksdwbhen5jorylyf6",
"handle": "thehornesection.bsky.social",
"displayName": "The Horne Section",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:sfytqb5ksdwbhen5jorylyf6/b…"
}
},
"links": [],
"mentions": [
"thehornesection.bsky.social"
],
"tags": [],
"replyTo": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtzbwnbvrs24",
"replies": []
}
]
},
{
"uri": "at://did:plc:xwzonyjk7rpsn7v6attpxmf2/app.bsky.feed.post/3mu3j2i2m222k",
"cid": "bafyreieuadtlbmfyw4hl4gtyg66eb7nkdtil5csqirktskq3v67mdgd3ui",
"url": "https://bsky.app/profile/hologrid99.bsky.social/post/3mu3j2i2m222k",
"text": "nice ⭐",
"createdAt": "2026-08-27T18:46:27.328Z",
"author": {
"did": "did:plc:xwzonyjk7rpsn7v6attpxmf2",
"handle": "hologrid99.bsky.social",
"displayName": null,
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:xwzonyjk7rpsn7v6attpxmf2/b…"
},
"replyCount": 0,
"repostCount": 0,
"likeCount": 0,
"quoteCount": 0,
"bookmarkCount": 0,
"langs": [
"en"
],
"images": [],
"video": null,
"external": null,
"quote": null,
"links": [],
"mentions": [],
"tags": [],
"replyTo": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtyzbvfbb222",
"replies": []
}
]
},
{
"uri": "at://did:plc:xh3czhp62wowuzbor5jfmklx/app.bsky.feed.post/3mtylqgnnjc25",
"cid": "bafyreib35r3mx4fuk4g5aiviczcsxhwhqkjwqytcqpphpjvm7cwgbmpnce",
"url": "https://bsky.app/profile/gokaired215.bsky.social/post/3mtylqgnnjc25",
"text": "OK so for some reason videos over like 5 minutes don't appear on a profile for me?",
"createdAt": "2026-08-26T14:56:32.321Z",
"author": {
"did": "did:plc:xh3czhp62wowuzbor5jfmklx",
"handle": "gokaired215.bsky.social",
"displayName": "G",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:xh3czhp62wowuzbor5jfmklx/b…"
},
"replyCount": 0,
"repostCount": 0,
"likeCount": 0,
"quoteCount": 0,
"bookmarkCount": 0,
"langs": [
"en"
],
"images": [],
"video": null,
"external": null,
"quote": null,
"links": [],
"mentions": [],
"tags": [],
"replyTo": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtykea5kds2d",
"replies": []
}
],
"parents": [
{
"uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtwkahfcss2p",
"cid": "bafyreie76xk3wtpecmwh3s5ybju7vjv7cybe2he4l77okrmpcpr3uuwece",
"url": "https://bsky.app/profile/bsky.app/post/3mtwkahfcss2p",
"text": "NOW PLAYING: \"Chiitan Blooper Reel\" by @chiitan.love",
"createdAt": "2026-08-25T19:24:23.007Z",
"author": {
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/b…"
},
"replyCount": 11,
"repostCount": 76,
"likeCount": 806,
"quoteCount": 8,
"bookmarkCount": 50,
"langs": [
"en"
],
"images": [],
"video": null,
"external": null,
"quote": {
"uri": "at://did:plc:t5pur7eruxfgxy7ynpfrmg2w/app.bsky.feed.post/3mtw4hu5cy22l",
"url": "https://bsky.app/profile/chiitan.love/post/3mtw4hu5cy22l",
"text": "✨Chiitan Special video✨\nCelebrating that Bluesky now lets you post longe…",
"createdAt": "2026-08-25T15:17:58.872Z",
"author": {
"did": "did:plc:t5pur7eruxfgxy7ynpfrmg2w",
"handle": "chiitan.love",
"displayName": "Chiitan🌈ちぃたん☆",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:t5pur7eruxfgxy7ynpfrmg2w/b…"
}
},
"links": [],
"mentions": [
"chiitan.love"
],
"tags": [],
"replyTo": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtwgs26j2c2d"
},
{
"uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtwm5grjns22",
"cid": "bafyreifn4ucipyjbdtylqjnfbpimp5ujf3wmbuvechb6lwjgf36vlj5vvi",
"url": "https://bsky.app/profile/bsky.app/post/3mtwm5grjns22",
"text": "NOW PLAYING: \"Four Minutes and Nineteen Seconds of College Football High…",
"createdAt": "2026-08-25T19:58:29.180Z",
"author": {
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/b…"
},
"replyCount": 13,
"repostCount": 31,
"likeCount": 524,
"quoteCount": 9,
"bookmarkCount": 29,
"langs": [
"en"
],
"images": [],
"video": null,
"external": null,
"quote": {
"uri": "at://did:plc:upyx3raxzpwlnzojrncogd7y/app.bsky.feed.post/3mtw23sqfcs2w",
"url": "https://bsky.app/profile/sickoscommittee.org/post/3mtw23sqfcs2w",
"text": "I set a college football highlight video to the full 4 minutes and 19 se…",
"createdAt": "2026-08-25T14:35:27.264Z",
"author": {
"did": "did:plc:upyx3raxzpwlnzojrncogd7y",
"handle": "sickoscommittee.org",
"displayName": "Sickos Committee",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:upyx3raxzpwlnzojrncogd7y/b…"
}
},
"links": [],
"mentions": [
"sickoscommittee.org"
],
"tags": [],
"replyTo": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mtwkahfcss2p"
}
]
}Response fields
Every field of a successful response. [] marks a list: a[].b is the b of each item in a. nullable fields can be null; optional fields can be missing.
Show all 136 fieldsHide
| Field | Type | Description |
|---|---|---|
| success | true | Always true here; errors have success: false. |
| credits_remaining | number | Your balance after this call. On anonymous playground calls: free tries left today. |
| credits_charged | number | Credits this call cost; 0 on free endpoints. On anonymous playground calls: tries used (1). |
| post | object | The post. |
| post.uri | string | The post's at:// URI, its permanent id. |
| post.cid | string | Content hash of this version of the post. |
| post.url | string | The post on bsky.app. |
| post.text | string | Post text. Empty for media-only posts. |
| post.createdAt | string | When it was posted, ISO 8601. |
| post.author | object | Who posted it. |
| post.author.did | string | The account's permanent id, e.g. did:plc:z72i7hdynmk6r22z27h6tvur. |
| post.author.handle | string | Handle, e.g. bsky.app. It can change; the DID doesn't. |
| post.author.displayName | stringnullable | Display name; null if not set. |
| post.author.avatar | stringnullable | Avatar image URL; null if none. |
| post.replyCount | number | Replies. |
| post.repostCount | number | Reposts. |
| post.likeCount | number | Likes. |
| post.quoteCount | number | Quote posts. |
| post.bookmarkCount | number | Times saved to bookmarks. |
| post.langs | string[] | Languages the author tagged, e.g. en. |
| post.images | object[] | Attached images, in order. Empty if none. |
| post.images[].thumbnail | string | Small image URL. |
| post.images[].fullsize | string | Full-size image URL. |
| post.images[].alt | string | Alt text; empty if none. |
| post.video | objectnullable | Attached video; null if none. |
| post.video.playlist | string | HLS playlist (.m3u8) URL. |
| post.video.thumbnail | stringnullable | Poster image URL; null if none. |
| post.video.alt | stringnullable | Alt text; null if none. |
| post.external | objectnullable | Link card; null if none. |
| post.external.uri | string | The linked page. |
| post.external.title | string | Link card title. |
| post.external.description | string | Link card description. |
| post.external.thumbnail | stringnullable | Link card image URL; null if none. |
| post.quote | objectnullable | The post this one quotes; null if none or hidden from logged-out visitors. Embedded lists, feeds and starter packs aren't returned. |
| post.quote.uri | string | The quoted post's at:// URI. Pass it as url to the post endpoint. |
| post.quote.url | string | The quoted post on bsky.app. |
| post.quote.text | stringnullable | Its text; null when it was deleted or its author blocks viewers. |
| post.quote.createdAt | stringnullable | When it was posted, ISO 8601; null when unavailable. |
| post.quote.author | objectnullable | Who posted it; null when unavailable. |
| post.quote.author.did | string | The account's permanent id, e.g. did:plc:z72i7hdynmk6r22z27h6tvur. |
| post.quote.author.handle | string | Handle, e.g. bsky.app. It can change; the DID doesn't. |
| post.quote.author.displayName | stringnullable | Display name; null if not set. |
| post.quote.author.avatar | stringnullable | Avatar image URL; null if none. |
| post.links | string[] | Links in the text. |
| post.mentions | string[] | Handles mentioned in the text, without @. |
| post.tags | string[] | Hashtags in the text, without #. |
| post.replyTo | stringnullable | at:// URI of the post this replies to; null for top-level posts. |
| replies | object[] | Replies in Bluesky's order, each with its own replies. |
| replies[].uri | string | The post's at:// URI, its permanent id. |
| replies[].cid | string | Content hash of this version of the post. |
| replies[].url | string | The post on bsky.app. |
| replies[].text | string | Post text. Empty for media-only posts. |
| replies[].createdAt | string | When it was posted, ISO 8601. |
| replies[].author | object | Who posted it. |
| replies[].author.did | string | The account's permanent id, e.g. did:plc:z72i7hdynmk6r22z27h6tvur. |
| replies[].author.handle | string | Handle, e.g. bsky.app. It can change; the DID doesn't. |
| replies[].author.displayName | stringnullable | Display name; null if not set. |
| replies[].author.avatar | stringnullable | Avatar image URL; null if none. |
| replies[].replyCount | number | Replies. |
| replies[].repostCount | number | Reposts. |
| replies[].likeCount | number | Likes. |
| replies[].quoteCount | number | Quote posts. |
| replies[].bookmarkCount | number | Times saved to bookmarks. |
| replies[].langs | string[] | Languages the author tagged, e.g. en. |
| replies[].images | object[] | Attached images, in order. Empty if none. |
| replies[].images[].thumbnail | string | Small image URL. |
| replies[].images[].fullsize | string | Full-size image URL. |
| replies[].images[].alt | string | Alt text; empty if none. |
| replies[].video | objectnullable | Attached video; null if none. |
| replies[].video.playlist | string | HLS playlist (.m3u8) URL. |
| replies[].video.thumbnail | stringnullable | Poster image URL; null if none. |
| replies[].video.alt | stringnullable | Alt text; null if none. |
| replies[].external | objectnullable | Link card; null if none. |
| replies[].external.uri | string | The linked page. |
| replies[].external.title | string | Link card title. |
| replies[].external.description | string | Link card description. |
| replies[].external.thumbnail | stringnullable | Link card image URL; null if none. |
| replies[].quote | objectnullable | The post this one quotes; null if none or hidden from logged-out visitors. Embedded lists, feeds and starter packs aren't returned. |
| replies[].quote.uri | string | The quoted post's at:// URI. Pass it as url to the post endpoint. |
| replies[].quote.url | string | The quoted post on bsky.app. |
| replies[].quote.text | stringnullable | Its text; null when it was deleted or its author blocks viewers. |
| replies[].quote.createdAt | stringnullable | When it was posted, ISO 8601; null when unavailable. |
| replies[].quote.author | objectnullable | Who posted it; null when unavailable. |
| replies[].quote.author.did | string | The account's permanent id, e.g. did:plc:z72i7hdynmk6r22z27h6tvur. |
| replies[].quote.author.handle | string | Handle, e.g. bsky.app. It can change; the DID doesn't. |
| replies[].quote.author.displayName | stringnullable | Display name; null if not set. |
| replies[].quote.author.avatar | stringnullable | Avatar image URL; null if none. |
| replies[].links | string[] | Links in the text. |
| replies[].mentions | string[] | Handles mentioned in the text, without @. |
| replies[].tags | string[] | Hashtags in the text, without #. |
| replies[].replyTo | stringnullable | at:// URI of the post this replies to; null for top-level posts. |
| replies[].replies | BlueskyReply[] | Replies to this reply. |
| parents | object[] | The posts above this one in the thread, first post first. Empty for top-level posts. |
| parents[].uri | string | The post's at:// URI, its permanent id. |
| parents[].cid | string | Content hash of this version of the post. |
| parents[].url | string | The post on bsky.app. |
| parents[].text | string | Post text. Empty for media-only posts. |
| parents[].createdAt | string | When it was posted, ISO 8601. |
| parents[].author | object | Who posted it. |
| parents[].author.did | string | The account's permanent id, e.g. did:plc:z72i7hdynmk6r22z27h6tvur. |
| parents[].author.handle | string | Handle, e.g. bsky.app. It can change; the DID doesn't. |
| parents[].author.displayName | stringnullable | Display name; null if not set. |
| parents[].author.avatar | stringnullable | Avatar image URL; null if none. |
| parents[].replyCount | number | Replies. |
| parents[].repostCount | number | Reposts. |
| parents[].likeCount | number | Likes. |
| parents[].quoteCount | number | Quote posts. |
| parents[].bookmarkCount | number | Times saved to bookmarks. |
| parents[].langs | string[] | Languages the author tagged, e.g. en. |
| parents[].images | object[] | Attached images, in order. Empty if none. |
| parents[].images[].thumbnail | string | Small image URL. |
| parents[].images[].fullsize | string | Full-size image URL. |
| parents[].images[].alt | string | Alt text; empty if none. |
| parents[].video | objectnullable | Attached video; null if none. |
| parents[].video.playlist | string | HLS playlist (.m3u8) URL. |
| parents[].video.thumbnail | stringnullable | Poster image URL; null if none. |
| parents[].video.alt | stringnullable | Alt text; null if none. |
| parents[].external | objectnullable | Link card; null if none. |
| parents[].external.uri | string | The linked page. |
| parents[].external.title | string | Link card title. |
| parents[].external.description | string | Link card description. |
| parents[].external.thumbnail | stringnullable | Link card image URL; null if none. |
| parents[].quote | objectnullable | The post this one quotes; null if none or hidden from logged-out visitors. Embedded lists, feeds and starter packs aren't returned. |
| parents[].quote.uri | string | The quoted post's at:// URI. Pass it as url to the post endpoint. |
| parents[].quote.url | string | The quoted post on bsky.app. |
| parents[].quote.text | stringnullable | Its text; null when it was deleted or its author blocks viewers. |
| parents[].quote.createdAt | stringnullable | When it was posted, ISO 8601; null when unavailable. |
| parents[].quote.author | objectnullable | Who posted it; null when unavailable. |
| parents[].quote.author.did | string | The account's permanent id, e.g. did:plc:z72i7hdynmk6r22z27h6tvur. |
| parents[].quote.author.handle | string | Handle, e.g. bsky.app. It can change; the DID doesn't. |
| parents[].quote.author.displayName | stringnullable | Display name; null if not set. |
| parents[].quote.author.avatar | stringnullable | Avatar image URL; null if none. |
| parents[].links | string[] | Links in the text. |
| parents[].mentions | string[] | Handles mentioned in the text, without @. |
| parents[].tags | string[] | Hashtags in the text, without #. |
| parents[].replyTo | stringnullable | at:// URI of the post this replies to; null for top-level posts. |
Caching and freshness
Responses are cached for up to 3 minutes, so a repeat call within that window can return the same data. It still costs 1 credit.
Errors
Errors return { success: false, error, code, docs } with the HTTP status below. Validation errors, 401/402/429 rejections and 5xx failures are free; not_found is charged (how charging works). All error codes.
| Status | Code | Meaning |
|---|---|---|
| 401 | missing_api_key | No API key. Send it in the x-api-key header. |
| 401 | invalid_api_key | The key is unknown or was revoked. |
| 402 | insufficient_credits | Not enough credits for this call. Buy a pack or wait for tomorrow's top-up. |
| 403 | not_public | The platform confirmed this account or content isn't available to logged-out visitors. Use a publicly visible target. |
| 404 | not_found | The endpoint, or the thing you asked for (ad, post, subreddit), doesn't exist. Charged when the platform was checked. |
| 405 | method_not_allowed | Endpoints take GET with query params. |
| 429 | rate_limited | Too many calls at once. Wait for the retry-after seconds, then retry. |
| 500 | internal_error | Something broke on our side. Retry; 5xx errors are free. |
| 502 | upstream_error | The platform didn't give a usable answer. Retry; 5xx errors are free. |
| 503 | upstream_busy | All our connections to the platform are busy. Retry in a few seconds; 5xx errors are free. |
| 504 | upstream_timeout | The platform took over 30 seconds to answer. Retry; timeouts are free. |
Use it in Claude
Once LurkAPI is connected to Claude, this endpoint is the bluesky_post tool. Ask in plain English, for example:
Use LurkAPI's bluesky_post with url "https://bsky.app/profile/bsky.app/post/3mtykea5kds2d" and summarize what you find.Claude calls bluesky_post with arguments like these, and each call costs 1 credit:
{
"url": "https://bsky.app/profile/bsky.app/post/3mtykea5kds2d"
}Tool results skip nulls and empty lists to save tokens.