← Knowledge

Bluesky Protocol Services

Bluesky's public infrastructure layer for ATProto developers, including Jetstream v2 network replay, typed SDKs, and the Bluesky HTTP reference.

Bluesky Protocol Services is the public infrastructure and developer-documentation layer that Bluesky operates for the AT Protocol network. Launched on August 13, 2026, it gives this infrastructure a distinct home from the protocol specification and the Bluesky application. The documented services include relays, Jetstream instances, application programming interfaces (APIs), and software development kits (SDKs).

The launch also introduced Jetstream v2 network replay, new TypeScript and Go Jetstream clients, and a Bluesky TypeScript SDK built on @atproto/lex. Together, these releases make it easier to move from an ATProto record schema to a typed application that can index both historical and live network data.

A service layer above the protocol

ATProto defines portable identity, account repositories, record schemas called Lexicons, repository synchronization, and network APIs. Those specifications do not require Bluesky to host every relay, index, or developer endpoint.

Bluesky Protocol Services documents the infrastructure that Bluesky chooses to operate on the open network. The public documentation now has four distinct homes:

  • atproto.com defines protocol behavior for identity, repositories, Lexicons, synchronization, and XRPC.
  • bsky.network documents Bluesky-operated services such as Jetstream, relays, and hosted API endpoints.
  • The Bluesky API guides cover feeds, profiles, moderation, chat, and the app.bsky.* data model.
  • endpoints.bsky.app provides machine-readable schemas for the Bluesky application, core ATProto methods, chat, moderation, and Jetstream v2.

This separation does not make Bluesky's infrastructure part of the protocol. Developers can self-host Jetstream, consume the lower-level firehose, or build services around other Lexicon namespaces.

Jetstream turns the network into JSON

Jetstream consumes ATProto's repository event stream and emits simpler JSON events over a WebSocket. A consumer can filter commits by an exact collection name or a namespace wildcard such as app.bsky.feed.*. A DID filter restricts all event kinds to specific accounts. These filters avoid decoding the firehose's binary repository blocks.

Jetstream events include record creates, updates, and deletes. Account, identity, and synchronization events bypass collection filters and also reach the consumer. These markers carry account deletion, handle-change, and repository-divergence information outside any one record collection. Consumers fold the ordered events into their own index and should make writes idempotent because delivery is at least once.

The trade-off is verification. Jetstream is a convenient projection of repository activity, not a complete replacement for the ATProto sync protocol. Applications that need binary repository blocks or independent verification of repository state should consume the firehose or fetch the underlying repositories.

Network replay joins history to the live tail

Earlier Jetstream instances provided a live tail and a limited lookback window, but not historical archive replay. An application that needed older records had to backfill repositories separately, then coordinate the handoff to the WebSocket without dropping events.

Network Replay moves that handoff into Jetstream v2. A replay consumer follows three steps:

  1. One or more planSnapshot calls select work for exact DIDs, collection names or namespace wildcards, and an optional sequence range. Each page pins the same sealed archive tip.
  2. The consumer downloads full segments or candidate block ranges over HTTP, then applies the exact filters while decoding because the plan may include false positives.
  3. The consumer connects to the live WebSocket at the sealed archive tip and deduplicates the inclusive boundary event.

The server keeps no cursor or subscription state for each consumer. Planned downloads are checksummed, cacheable, and resumable with HTTP range requests. Sealed segment files remain immutable between compactions, but the server can later rewrite them to remove deleted records and assign new checksums. Archive mirrors therefore need to re-list segments rather than assume a checksum will exist forever.

Bluesky's hosted archive requests require an API key and are metered by compressed response bytes. The live WebSocket remains unauthenticated and unmetered. If a backfill runs past the hosted socket's current 36-hour lookback window, the client plans another archive range rather than silently skipping the gap. The archive is also available as an HTTP-only snapshot when an application needs a bounded dataset rather than a live index.

Replay is an event log, not a current-state dump

Replay returns creates, updates, deletes, and account-level changes from the archive currently retained by the service. It does not hide a superseded record before the corresponding update or delete arrives. A consumer reconstructs current state by applying events in sequence:

  • create adds a record;
  • update replaces the record at the same at:// URI;
  • delete removes it;
  • an account deletion or sync-divergence marker removes the affected account's records.

The hosted archive is not a permanent audit log. Compaction can physically remove deleted records from sealed segments. ATProto Records and Provenance describes a related identity distinction: an AT URI identifies a logical record path, while a content identifier (CID) identifies exact record bytes. A replay index can key current state by AT URI, but it must still apply sequence order correctly. Systems that review, quote, or audit a specific version should also preserve its CID.

The SDKs share one typed path

The TypeScript `@bsky/jetstream` package and the Go client in the Jetstream project expose live, replay, and snapshot modes through asynchronous iteration. They handle reconnection, deduplication, archive download, and the transition from replay to the live stream. An application supplies a cursor store when progress must survive a process restart.

The TypeScript package also includes LexIndexer and JetstreamRunner. These higher-level components validate records against Lexicons, preserve per-record ordering under bounded concurrency, and coordinate cursor checkpoints.

The new `@bsky/sdk` package supplies Bluesky Lexicons, typed actions, rich-text utilities, and moderation helpers. It uses `@atproto/lex` for schema installation, generated TypeScript types, runtime validation, XRPC calls, and record operations. OAuth and app-password sessions come from separate session packages. @atproto/lex remains a preview package, so its API may change before a stable release.

This is Bluesky's new recommended path from protocol data to application helpers. Existing @atproto/api code still works, but Bluesky no longer maintains parallel legacy paths for its helpers, and the new documentation uses the @atproto/lex stack.

What the launch changes

The main change is operational rather than conceptual. ATProto applications have always been able to read shared repositories and build their own views. Bluesky Protocol Services makes the Bluesky-hosted path legible and gives historical replay, live indexing, typed schemas, and API reference a coherent contract.

A small application can now begin with a collection filter and replay the matching history available in a Jetstream v2 archive. It can continue into live events and validate each record against its Lexicon without operating a relay or writing a separate repository backfill. On Bluesky's hosted service, that convenience depends on an API key, byte quota, and the archive's retained range. The application still owns its database, event-folding rules, moderation policy, retries, and decisions about when Jetstream's simplified projection is sufficient.

Sources

  1. Introducing Bluesky Protocol Services
  2. Bluesky Protocol Services
  3. Network Replay with Jetstream
  4. Jetstream SDK
  5. Bluesky HTTP API Reference
  6. @atproto/lex
  7. @bsky/sdk

Connections

Related

Suggest a correction ↗