jonathanwarden.com
@jonathanwarden.com
I've recently been thinking along similar lines:

bsky.app/profile/jona...
I've been thinking about how oEmbed could work for ATProto records.

Currently, you can embed a Bluesky post on any website by passing the post's bsky.app. URL to the oEmbed service. It would be nice if you could also embed records from other ATProto lexicons.

Here's a possible solution...
(1/8)
December 10, 2025 at 11:23 AM
Alternatively, to keep web stuff out of schma defs, this could be a separate record, e.g. com.atproto.lexicon.web.

So if you use a lexicon you don't control, you'd have to really trust the publisher. But that's already the case.

Thoughts anyone? Could this work? What should I do with this?
(8/8)
December 10, 2025 at 10:36 AM
So for example, the schema record for app.bsky.feed.post could be updated with an optional "web" field, like this:

{
"id": "app.bsky.feed.post",
+ "web": {
+ "url_scheme": "https://bsky.app/profile/{DID_OR_HANDLE}/post/{RKEY}",
+ "oembed_api": "https://embed.bsky.app/oembed"
+ }
...
(7/8)
December 10, 2025 at 10:36 AM
oEmbed works with HTTP URLs only, so the lexicon publisher would need to provide information to map an ATProto record to an HTTP URL (a nice bonus).

This information naturally should be published in/alongside the com.atproto.lexicon.schema record.
(6/8)
December 10, 2025 at 10:35 AM
The Lexicon publisher? This makes the most sense. For example, Bluesky authored the app.bsky.feed.post lexicon and are the authority on what a Bluesky post should look like. And indeed Bluesky already hosts an oEmbed service for Bluesky posts.
(5/8)
December 10, 2025 at 10:34 AM
The PDS? "This is how I want my personal posts to be displayed." No, this is not a personal decision -- there should be a standard for how Bluesky posts are displayed.

The App View? "This is how to display posts you fetch from my app view." Hmm, no, that's not the App View's role either.

(4/8)
December 10, 2025 at 10:25 AM
- Who should host the oEmbed service that knows how to produce oEmbeds for an ATProto record of a given type?

- More specifically, who should decide how, visually, an ATProto record of that type should be displayed?

(3/8)
December 10, 2025 at 10:24 AM
Allow a com.atproto.lexicon.schema record to include an optional config that tells how records of that type can be displayed on the web. It should include 1) a scheme/template for converting an ATProto URI into an HTTP URL and 2) an oEmbed service URL.

Here's the line of thinking:
(2/8)
December 10, 2025 at 10:22 AM
beautiful!
November 23, 2025 at 5:33 PM
Yes it’s true, Bluesky controls what users of the Bluesky app see, which means they control what most people on the atproto network see. But it’s still possible to build atproto apps that are totally independent of Bluesky. Of course, it is possible nobody will use many of those apps…
November 23, 2025 at 5:10 PM
I see your point. But Bluesky has actually made a point of making it possible to build on ATProto while being independent of Bluesky.
November 22, 2025 at 12:21 PM
$3/day is not much for a well-funded project. There are probably projects that are already doing embeddings on the entire firehouse. But once you add images and video, or larger models, costs could easily increase by orders of magnitude. Then the economics of a shared service makes a lot of sense.
November 21, 2025 at 11:52 AM
Ahah! Thank you that clarifies things for me.
November 19, 2025 at 7:14 PM
And you can watch all this happen in the "Network" tab of dev tools when you load this page: bluenotes.social/community-no...

You'll see calls to the app.bsky.feed.getFeed (the Bluesky app view), which returns posts with the 'annotation' label, then calls to org.opencommunitynotes.getProposals
Bluenotes
bluenotes.social
October 25, 2025 at 8:24 PM
Oh and a tip. Frontends should pass the DID of the Bluenotes labeler in the 'Atproto-accept-labelers' header when making calls to the Bluesky app view. This way, users don't have to describe to the labeler.
October 25, 2025 at 8:18 PM