The AT Protocol at:// (Authenticated Transfer Protocol, or atproto) is a standard for public conversation and an open-source framework for building social apps.
It creates a standard format for user identity, follows, and data on social apps, allowing apps to interoperate and users to move across them freely. It is a federated network with account portability.
Used by Bluesky. Frontpage and Smoke Signal (see below ).
Read Basic Concepts, Identity, Data repositories, Federation and more.
Besides the dedicated tools to Bluesky, here are the more related to extract and ATProto.
# Web Applications
# Data Analysis & Processing
Jetstream Tools:Data Tools & Tutorials:Dashboards
# Data Access & Querying
DuckDB Resources:Hive Catalog - Access via https://hive.buz.dev/bluesky/catalog or via select * from read_parquet('https://hive.buz.dev/bluesky/jetstream/latest.parquet') by Jake ThomasSkyfirehose - Query Jetstream with DuckDB
Firehose Access:
Based on Jetstream: Shrinking the AT Proto Firehose by >99% · Jaz’s Blog, it’s better to access data through their Firehose protocol rather than REST APIs.
# DuckDB
But there’s a browser for checking your content:
# Bsky Engagement Stats
or stats (origin on bsky):

# Query
1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738
| -- Charting bars with engagement metricsWITH raw_data AS ( SELECT * FROM read_json_auto('https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=did:plc:edglm4muiyzty2snc55ysuqx&limit=100')),unnested_feed AS ( SELECT unnest(feed) as post_data FROM raw_data),engagement_data AS ( SELECT RIGHT(post_data.post.uri, 13) as post_uri, --post_data.post.uri as post_uri, post_data.post.author.handle, LEFT(post_data.post.record.text, 50) as post_text, post_data.post.record.createdAt as created_at, (post_data.post.replyCount + post_data.post.repostCount + post_data.post.likeCount + post_data.post.quoteCount) as total_engagement, post_data.post.replyCount as replies, post_data.post.repostCount as reposts, post_data.post.likeCount as likes, post_data.post.quoteCount as quotes, FROM unnested_feed)SELECT post_uri, created_at, total_engagement, bar(total_engagement, 0, (SELECT MAX(total_engagement) FROM engagement_data), 30) as engagement_chart, replies, reposts, likes, quotes, post_text,FROM engagement_dataWHERE handle = 'ssp.sh'ORDER BY total_engagement DESCLIMIT 30;
|
# Reading Posts
Bsky and GitHub Gist
# Query
or reading the posts:
1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445
| -- Query the API directly and flatten the nested JSON structureWITH raw_data AS ( SELECT * FROM read_json_auto('https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=did:plc:edglm4muiyzty2snc55ysuqx&limit=10')),unnested_feed AS ( SELECT unnest(feed) as post_data FROM raw_data)SELECT -- Post basics post_data.post.uri as post_uri, post_data.post.author.handle as author_handle, post_data.post.author.displayName as display_name, -- Post content post_data.post.record.text as post_text, post_data.post.record.createdAt as created_at, -- Engagement metrics post_data.post.replyCount as replies, post_data.post.repostCount as reposts, post_data.post.likeCount as likes, post_data.post.quoteCount as quotes, -- Embedded content (if available) CASE WHEN post_data.post.embed IS NOT NULL AND post_data.post.embed['$type'] = 'app.bsky.embed.external#view' THEN post_data.post.embed.external.uri ELSE NULL END as embedded_link, CASE WHEN post_data.post.embed IS NOT NULL AND post_data.post.embed['$type'] = 'app.bsky.embed.external#view' THEN post_data.post.embed.external.title ELSE NULL END as embedded_title, -- Total engagement score (post_data.post.replyCount + post_data.post.repostCount + post_data.post.likeCount + post_data.post.quoteCount) as total_engagementFROM unnested_feedORDER BY created_at DESC;
|
Uploaded to Reading bsky posts with DuckDB example. · GitHub, too.
# Get Unique ID
Get the Unique ID of my User through public API using HTTPS community extension
1 2 3 4 5 6 7 8 910111213
| D WITH __input AS ( SELECT http_get('https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=ssp.sh') AS res ) SELECT res::json->>'body' as identity_json FROM __input;┌────────────────────────────────────────────┐│ identity_json ││ varchar │├────────────────────────────────────────────┤│ {"did":"did:plc:edglm4muiyzty2snc55ysuqx"} │└────────────────────────────────────────────┘
|
# Graph: Accounts within 5 hops
Interesting discovery: there are roughly 9,000 accounts within 5 hops of those I currently follow! 🚀 (I assume I didn’t mess up the data gathering) Powered by duckdb with the seamless
SQL / PGQ syntax supported in the DuckPGQ extension. Amazing what you can uncover with the right tools! Post by @dtenwolde.bsky.social — Blueskhttps://www.ssp.sh/brain/AT%20Protocol-20241030173449539.webpAT%20Protocol-20241030173449539.webp">
Check some stuff on Future of Web, and Bluesky
Just wapping the relevant macros to do the queries. pivot_table – DuckDB Community Extensions (by @a13x.bsky.social ) is a good example of an extension that just exposes a bunch of SQL macros, chsql – DuckDB Community Extensions is another cool one in that vibe. Post by @carlopi.bsky.social — Bluesky
Origin: Bluesky protocol
References:
Created 2024-10-30