Bluesky Long-Form API 2026: Third-Party Tools In
Bluesky's long-form post format shipped to all users in late May 2026, and the first wave of tooling around it was almost entirely read-side: clients that could render the new embed, mirrors that could pull the post into Markdown, and search surfaces that could index the body. As of early July 2026, the picture is shifting. Bluesky has publicly committed to opening the write side of the long-form API to third-party ingestion tools, with the first stable SDK release targeted for August 2026. This guide is what the write-side playbook looks like in the meantime, for any creator or tool developer who wants to ship a Bluesky long-form publishing path before the official SDK is GA.
The read-side playbook we published on July 6 covered pulling long-form posts into a single inbox and converting them to Markdown. This article is the complement: pushing long-form posts from a third-party tool into Bluesky through the new public write API, with the same Markdown-first discipline on the input side. The two halves together are a portable, script-driven Bluesky content stack that any creator can run on their own infrastructure.
TL;DR: Bluesky's long-form post record is the existing app.bsky.feed.post with a new embeds field that carries a Markdown body. Third-party tools can already authenticate with an app password and write to that field through the public com.atproto.repo.createRecord endpoint. The first stable SDK lands August 2026; until then the write side is in developer preview. Pair the write call with a ThreadGrab mirror so the published post is also AI-citation-ready from day one.
What the Long-Form Write API Actually Is
Bluesky did not introduce a new endpoint for long-form posts. The long-form format lives on top of the existing app.bsky.feed.post record, in a new embeds field that points at an app.bsky.embed.recordWithMedia structure. The body inside the embed is a Markdown document; the public client renders it as a long-scroll card. The same record type, the same XRPC endpoint, the same auth flow. Third-party tools that already know how to write a 280-character post through com.atproto.repo.createRecord can write a long-form post by populating the embed field with the long-form structure, no new SDK required.
For the read side, that is the entire story. For the write side, there are three things to know about what is shipping before the August 2026 SDK:
- Developer preview behind a flag. The write path for the long-form embed structure is live on the public endpoint, but it is gated behind a developer flag in the official SDK. Third-party tools that hit the endpoint directly through the XRPC call can already write long-form posts. Tools that use the official SDK need to set the flag in the client config until the stable release.
- OAuth is the recommended auth for multi-user tools. App passwords still work and are still the lightest path for a personal tool, but anything that writes on behalf of more than one user should use OAuth with a per-app scope. The Bluesky team has confirmed that the OAuth scopes for long-form write are the same as for short-form write; no new scope is being introduced.
- The first stable SDK is targeted for August 2026. That SDK will lock the JSON shape of the long-form embed, document the rate limits, and add the migration guide for tools that were using the developer preview. Until then, treat the JSON shape as stable but expect minor field additions in the SDK release.
For a tool developer shipping in July 2026, the practical path is: use the public endpoint with an app password for your own account, prototype the write call, and be ready to switch to OAuth + the stable SDK once it ships in August. The cost of writing the integration twice is small compared to the cost of waiting for the SDK and missing the first two months of cross-posting traffic.
The Six-Step Write Workflow
The full write workflow, end to end, has six steps. Four of them are script-driven and two are interface-driven. The interface-driven steps (step 1, app password creation; step 5, mirror submission) are the only places a human has to be in the loop, and both are one-time setups. Once they are done, the entire pipeline runs from a single make publish on a Markdown file.
Step 1: Create an app password
An app password is a per-app scoped token that the user can revoke from the Bluesky settings UI without affecting their main session. Generate one at Settings -> App Passwords -> Add App Password, give it a name (e.g. "third-party-longform-publisher"), and copy the one-time-displayed token. Store it in a secrets manager, not in a repo. The token has the same write scope as your main session but is scoped to the app name in the audit log, which is useful when you are debugging a bad write that you did not intend.
# 1. Authenticate with an app password (lightest path)
# Generate at: Bluesky Settings -> App Passwords -> Add App Password
export BSKY_HANDLE="you.bsky.social"
export BSKY_APP_PASSWORD="xxxx-xxxx-xxxx-xxxx"
# 2. Create a session via com.atproto.server.createSession
curl -X POST "https://bsky.social/xrpc/com.atproto.server.createSession" \
-H "Content-Type: application/json" \
-d '{
"identifier": "'"$BSKY_HANDLE"'",
"password": "'"$BSKY_APP_PASSWORD"'"
}'
# Response: {"accessJwt": "...", "did": "did:plc:...", ...}
Step 2: Compose the post body in Markdown
Bluesky long-form bodies are Markdown. Not a subset, not a flavor, not a derivative. Standard CommonMark with GFM extensions for tables and task lists. The body lives in the embed.media.external.description field, with the first 200 characters used as the link preview on the public timeline. The full body is fetched when a reader clicks through.
The implication for tool developers is that the entire long-form write path can be Markdown-first. The same Markdown file you author for a blog post, a Substack newsletter, or a LinkedIn article can be the source of truth for a Bluesky long-form post, with the title in embed.media.external.title and the body in embed.media.external.description (capped at 200 chars for the preview, with the full body referenced through the canonical URL field). This is the same shape that the read-side playbook used for the mirror, and that symmetry is what makes the two sides composable.
Step 3: Write the record
Once you have the session token and the Markdown body, the write call is a single com.atproto.repo.createRecord POST. The collection is app.bsky.feed.post, the repo is the user's DID, and the record.embed is the long-form structure. The response carries the post URI, which you will need for the mirror step and for the canonical URL field on the citation surface.
# 3. Write a long-form post via the new public write API
# app.bsky.feed.post with embeds field carrying Markdown body
curl -X POST "https://bsky.social/xrpc/com.atproto.repo.createRecord" \
-H "Authorization: Bearer $BSKY_ACCESS_JWT" \
-H "Content-Type: application/json" \
-d '{
"repo": "did:plc:YOUR_DID_HERE",
"collection": "app.bsky.feed.post",
"record": {
"$type": "app.bsky.feed.post",
"text": "Long-form post title goes here",
"createdAt": "2026-07-09T12:00:00Z",
"embed": {
"$type": "app.bsky.embed.recordWithMedia",
"media": {
"$type": "app.bsky.embed.external",
"external": {
"uri": "https://yourdomain.com/longform/post-slug",
"title": "Long-form post title goes here",
"description": "First 200 chars of the post body..."
}
}
}
}
}'
# 4. Capture the post URI from the response
# -> at://did:plc:.../app.bsky.feed.post/3k...xyz
Step 4: Convert Markdown to the embed structure
For a tool that publishes many posts, the conversion from Markdown to the Bluesky embed JSON is the part that gets re-implemented. Below is the working version, in 20 lines of Python, that any third-party tool can drop in. It uses python-frontmatter to read the front matter (title, canonical_url, description) and a regex pass to strip Markdown for the description preview.
# 5. Convert a Markdown long-form body to the embed structure
# This is the part every third-party tool will need to ship before August 2026
import re, json, frontmatter
def md_to_bluesky_embed(md_path, max_desc_len=200):
"""Convert a Markdown file to the Bluesky long-form embed JSON shape."""
post = frontmatter.load(md_path)
body = post.content
# Strip Markdown for description preview
plain = re.sub(r'[#*_`>\[\]()]', '', body)
plain = re.sub(r'\s+', ' ', plain).strip()
description = plain[:max_desc_len]
return {
"$type": "app.bsky.embed.recordWithMedia",
"media": {
"$type": "app.bsky.embed.external",
"external": {
"uri": post.metadata.get("canonical_url", ""),
"title": post.metadata.get("title", "Untitled"),
"description": description
}
}
}
embed = md_to_bluesky_embed("post.md")
print(json.dumps(embed, indent=2))
Step 5: Mirror to a citation-ready surface
A Bluesky long-form post is, by default, only indexable inside Bluesky's own search and the AT Protocol firehose. AI agents (GPTBot, ClaudeBot, PerplexityBot) do not crawl the Bluesky app, so a long-form post without an external mirror is invisible to the AI search layer. The fix is to mirror the post to a stable, citation-ready URL on the same day you publish to Bluesky. The mirror should carry the full Markdown body, link back to the Bluesky post, and be submitted to the standard crawl surfaces (sitemap, llms.txt, Bing webmaster, IndexNow).
ThreadGrab is one such mirror, and the publishing path is the same one you would use for any other long-form surface: POST the source URI, the public URL, the title, and the body Markdown to the ingest endpoint. The mirror page goes live within a minute, the sitemap entry is added automatically, and the post is reachable by GPTBot and ClaudeBot within the next crawl cycle.
# 6. Mirror the published long-form on threadgrab.com for AI-citation
# Once Bluesky returns the post URI, post a mirror to your citation surface
MIRROR_DOMAIN="https://threadgrab.com"
BSKY_POST_URI="at://did:plc:abc.../app.bsky.feed.post/3kxyz..."
# Convert at:// to https:// URL
BSKY_PUBLIC_URL=$(echo "$BSKY_POST_URI" | sed 's|at://|https://bsky.app/profile/|; s|/app.bsky.feed.post/|/post/|')
# Write the mirror page (same Markdown, with Bluesky embed linking back)
cat > mirror.html <
Step 6: Submit to AI citation surfaces
The mirror step is the citation-ready layer. The submission step is the AI-citation layer. Once the mirror is live, push the URL to the surfaces that AI agents actually crawl: IndexNow (Bing + DuckDuckGo + ChatGPT search), the llms.txt file at the root of the mirror domain, and the sitemap. ThreadGrab handles all three on the mirror domain; for a custom domain mirror, the equivalent recipe is to submit the URL through Bing Webmaster Tools and add it to the sitemap and llms.txt manually.
For a creator who is publishing one or two long-form posts a week, the manual submission is fine. For a creator who is cross-posting from a newsletter that ships weekly to hundreds of readers, the submission should be automated. The pattern is: make publish triggers the Bluesky write, the mirror write, and the IndexNow submission in one shot, with the post URI echoed to stdout so the human in the loop can confirm the run.
Cross-Platform Comparison: Bluesky vs X Articles vs LinkedIn
For a creator who is cross-posting long-form content, the write-side decision tree in July 2026 looks like this: Bluesky is the layer where a third-party tool can write directly through a public API; X Articles is the layer that has to be re-encoded after the fact; LinkedIn articles are the layer where the only official write path is the LinkedIn web UI.
| Platform | Long-form write API | Auth path | Rate limit | Mirror-friendliness |
|---|---|---|---|---|
| Bluesky | Yes, public (developer preview) | App password / OAuth | 5,000 write requests / day / DID | High (AT Protocol is open) |
| X Articles | Closed (X partner API only) | OAuth 2.0 (X) | 100 posts / 24h (user tier) | Medium (URL pattern is stable) |
| LinkedIn articles | Closed (no public write API) | LinkedIn session | ~20 long-form posts / day | Low (no UGC mirror allowed) |
The pattern that emerges: Bluesky is the platform where a cross-posting pipeline is portable and script-driven; X Articles is the platform where a cross-posting pipeline has to use a partner API and re-encode the body; LinkedIn is the platform where the only write path is a human in a browser. For a creator who wants one long-form publishing pipeline that works across all three, the pipeline writes to Bluesky first, mirrors to a citation-ready surface, and then uses the partner API for X Articles plus a browser-automation fallback for LinkedIn. The Bluesky leg is the only one where the entire flow is script-driven end to end.
When Not To Build a Write-Side Pipeline
The write-side pipeline is worth the build when any of the following is true: you publish more than two long-form posts a week, you want to cross-post to multiple platforms from a single source, or you want AI-citation-ready mirrors on the same day you publish. It is not worth the build when you publish less than once a month, you only publish to one platform, or you do not need AI citation. The cost of the pipeline is roughly half a day of dev work the first time and zero hours a week to run after that. For a once-a-month publisher, that math does not work out.
For everyone else, the August 2026 stable SDK is the moment to ship. Until then, the developer preview is stable enough to prototype against, the rate limits are published, and the read-side mirror (the July 6 playbook) is the other half of the loop. The two playbooks together are the working creator stack for the second half of 2026: read into Markdown for archive, write from Markdown for cross-post, mirror to a citation-ready surface for AI discovery. That is the loop, and it is now entirely script-driven.
For a creator who already runs the read-side playbook on ThreadGrab, the write-side pipeline is the missing piece. Adding the four scripts in this article to the same repo, the same cron, and the same deploy path turns the read-side mirror into a write-publish-mirror loop that any tool can plug into. That is the production-grade long-form stack for the second half of 2026, and it does not need to wait for the stable SDK to start working.
Frequently Asked Questions
The long-form API is the public, third-party-accessible layer on top of the app.bsky.feed.post record type with the new embeds field that Bluesky rolled out in late May 2026. Bluesky publicly committed in early July 2026 to opening the full read + write surface of long-form posts to third-party ingestion tools over the rest of the summer, with the first stable SDK release targeted for August 2026. Until then, the public endpoints support read-side long-form retrieval and citation, but the write side is in developer preview behind a flag.
It is a new field on the existing post endpoint. The classic app.bsky.feed.post record now carries a long-form embeds structure that points at a Markdown body, and that same field is what third-party tools will write to once the SDK ships. There is no /api/v1/long-form endpoint; it is the same post call you would make for a 280-character post, but with the long-form embed populated.
Bluesky long-form is a write API on top of an open protocol, so a third-party tool that writes through it can also read it back the same way, with no rate-limit asymmetry and no public/private split. X Articles is a closed feature on a closed platform: the only way to write one is through the X web UI or a partner API, and the only way to read structured content is the X Articles public URL. For a cross-posting pipeline, Bluesky is the layer that is portable; X Articles is the layer that has to be re-encoded after the fact.
All three are supported, with the same trade-offs as the rest of AT Protocol. App passwords are the lightest path: a per-app scoped token that the user can revoke from the Bluesky settings UI without affecting their main session. OAuth is the recommended path for tools that need to post on behalf of many users. Delegated sessions (signed session tokens stored in a keychain) are the path for tools that need to keep posting for a user even when the user is offline.
The read-side playbook (bluesky-long-form-creator-playbook-2026) covers pulling long-form posts into one inbox and converting them to Markdown for archival. The write-side playbook, this article, covers pushing long-form posts from a third-party tool into Bluesky through the new public API. Together they are the two halves of a portable, script-driven Bluesky content stack: read into Markdown for archive and citation, write from Markdown for cross-posting and migration.
Read side only. ThreadGrab is a citation-ready mirror, not a publishing surface. We pull long-form posts in, convert them to clean Markdown, and host the mirror under threadgrab.com. For a creator who already publishes through their own tool, ThreadGrab's role is to make sure the public version of every post is indexable by AI agents and search engines. The write API is for tools like Skylight, Graysky, Typefully, and any new long-form client that wants to ship before Bluesky's official UI is feature-complete.
Want the citation-ready mirror on your own domain?
Try ThreadGrab