forked from
microcosm.blue/microcosm-rs
Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm
1{% extends "base.html.j2" %}
2{% import "try-it-macros.html.j2" as try_it %}
3
4{% block title %}Hello!{% endblock %}
5{% block body_classes %}home{% endblock %}
6
7{% block content %}
8
9 <p>Constellation is a self-hosted JSON API to an atproto-wide index of PDS record back-links, so you can query social interactions in real time. It can answer questions like:</p>
10
11 <ul>
12 <li><a href="/links/count/distinct-dids?target={{ "at://did:plc:44ybard66vv44zksje25o7dz/app.bsky.feed.post/3lhhz7k2yqk2h"|urlencode }}&collection=app.bsky.feed.like&path=.subject.uri">How many people liked a liked a bluesky post?</a></li>
13 <li><a href="/links/distinct-dids?target=did:plc:oky5czdrnfjpqslsw2a5iclo&collection=app.bsky.graph.follow&path=.subject">Who are all the bluesky followers of an identity?</a></li>
14 <li><a href="/links?target=at://did:plc:nlromb2qyyl6rszaluwhfy6j/fyi.unravel.frontpage.post/3lhd2ivyc422n&collection=fyi.unravel.frontpage.comment&path=.post.uri">What are all the replies to a Frontpage submission?</a></li>
15 <li><a href="/links/all?target=did:plc:vc7f4oafdgxsihk4cry2xpze">What are <em>all</em> the sources of links to an identity?</a></li>
16 <li>and more</li>
17 </ul>
18
19 <p>It works by recursively walking <em>all</em> records coming through the firehose, searching for anything that looks like a link. Links are indexed by the target they point at, the collection the record came from, and the JSON path to the link in that record.</p>
20
21 <p>
22 This server has indexed <span class="stat">{{ stats.linking_records|human_number }}</span> links between <span class="stat">{{ stats.targetables|human_number }}</span> targets and sources from <span class="stat">{{ stats.dids|human_number }}</span> identities over <span class="stat">
23 {%- if let Some(days) = days_indexed %}
24 {{ days|human_number }}
25 {% else %}
26 ???
27 {% endif -%}
28 </span> days.<br/>
29 <small>(indexing new records in real time, backfill coming soon!)</small>
30 </p>
31
32 {# {% for k, v in stats.other_data.iter() %}
33 <p><strong>{{ k }}</strong>: {{ v }}</p>
34 {% endfor %} #}
35
36 <p>You're welcome to use this public instance! Please do not build the torment nexus. If you want to be nice, put your project name and bsky username (or email) in your user-agent header for api requests.</p>
37
38
39 <h2>API Endpoints</h2>
40
41 <h3 class="route"><code>GET /xrpc/blue.microcosm.links.getBacklinks</code></h3>
42
43 <p>A list of records linking to any record, identity, or uri.</p>
44
45 <h4>Query parameters:</h4>
46
47 <ul>
48 <li><p><code>subject</code>: required, must url-encode. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></p></li>
49 <li><p><code>source</code>: required. Example: <code>app.bsky.feed.like:subject.uri</code></p></li>
50 <li><p><code>did</code>: optional, filter links to those from specific users. Include multiple times to filter by multiple users. Example: <code>did=did:plc:vc7f4oafdgxsihk4cry2xpze&did=did:plc:vc7f4oafdgxsihk4cry2xpze</code></p></li>
51 <li><p><code>limit</code>: optional. Default: <code>16</code>. Maximum: <code>100</code></p></li>
52 </ul>
53
54 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
55 {% call try_it::get_backlinks("at://did:plc:a4pqq234yw7fqbddawjo7y35/app.bsky.feed.post/3m237ilwc372e", "app.bsky.feed.like:subject.uri", [""], 16) %}
56
57
58 <h3 class="route"><code>GET /xrpc/blue.microcosm.links.getManyToManyCounts</code></h3>
59
60 <p>TODO: description</p>
61
62 <h4>Query parameters:</h4>
63
64 <ul>
65 <li><p><code>subject</code>: required, must url-encode. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></p></li>
66 <li><p><code>source</code>: required. Example: <code>app.bsky.feed.like:subject.uri</code></p></li>
67 <li><p><code>pathToOther</code>: required. Path to the secondary link in the many-to-many record. Example: <code>otherThing.uri</code></p></li>
68 <li><p><code>did</code>: optional, filter links to those from specific users. Include multiple times to filter by multiple users. Example: <code>did=did:plc:vc7f4oafdgxsihk4cry2xpze&did=did:plc:vc7f4oafdgxsihk4cry2xpze</code></p></li>
69 <li><p><code>otherSubject</code>: optional, filter secondary links to specific subjects. Include multiple times to filter by multiple users. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></p></li>
70 <li><p><code>limit</code>: optional. Default: <code>16</code>. Maximum: <code>100</code></p></li>
71 </ul>
72
73 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
74 {% call try_it::get_many_to_many_counts(
75 "at://did:plc:wshs7t2adsemcrrd4snkeqli/sh.tangled.label.definition/good-first-issue",
76 "sh.tangled.label.op:add[].key",
77 "subject",
78 [""],
79 [""],
80 25,
81 ) %}
82
83
84 <h3 class="route"><code>GET /links</code></h3>
85
86 <p>A list of records linking to a target.</p>
87
88 <p>[DEPRECATED]: use <code>GET /xrpc/blue.microcosm.links.getBacklinks</code>. New apps should avoid it, but this endpoint <strong>will</strong> remain supported for the forseeable future.</p>
89
90 <h4>Query parameters:</h4>
91
92 <ul>
93 <li><p><code>target</code>: required, must url-encode. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></p></li>
94 <li><p><code>collection</code>: required. Example: <code>app.bsky.feed.like</code></p></li>
95 <li><p><code>path</code>: required, must url-encode. Example: <code>.subject.uri</code></p></li>
96 <li><p><code>did</code>: optional, filter links to those from specific users. Include multiple times to filter by multiple users. Example: <code>did=did:plc:vc7f4oafdgxsihk4cry2xpze&did=did:plc:vc7f4oafdgxsihk4cry2xpze</code></p></li>
97 <li><p><code>from_dids</code> [deprecated]: optional. Use <code>did</code> instead. Example: <code>from_dids=did:plc:vc7f4oafdgxsihk4cry2xpze,did:plc:vc7f4oafdgxsihk4cry2xpze</code></p></li>
98 <li><p><code>limit</code>: optional. Default: <code>16</code>. Maximum: <code>100</code></p></li>
99 </ul>
100
101 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
102 {% call try_it::links("at://did:plc:a4pqq234yw7fqbddawjo7y35/app.bsky.feed.post/3m237ilwc372e", "app.bsky.feed.like", ".subject.uri", [""], 16) %}
103
104
105 <h3 class="route"><code>GET /links/distinct-dids</code></h3>
106
107 <p>A list of distinct DIDs (identities) with links to a target.</p>
108
109 <h4>Query parameters:</h4>
110
111 <ul>
112 <li><code>target</code>: required, must url-encode. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></li>
113 <li><code>collection</code>: required. Example: <code>app.bsky.feed.like</code></li>
114 <li><code>path</code>: required, must url-encode. Example: <code>.subject.uri</code></li>
115 </ul>
116
117 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
118 {% call try_it::dids("at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r", "app.bsky.feed.like", ".subject.uri") %}
119
120
121 <h3 class="route"><code>GET /links/count</code></h3>
122
123 <p>The total number of links pointing at a given target.</p>
124
125 <h4>Query parameters:</h4>
126
127 <ul>
128 <li><code>target</code>: required, must url-encode. Example: <code>did:plc:vc7f4oafdgxsihk4cry2xpze</code></li>
129 <li><code>collection</code>: required. Example: <code>app.bsky.graph.block</code></li>
130 <li><code>path</code>: required, must url-encode. Example: <code>.subject</code></li>
131 <li><code>cursor</code>: optional, see Definitions.</li>
132 </ul>
133
134 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
135 {% call try_it::links_count("did:plc:vc7f4oafdgxsihk4cry2xpze", "app.bsky.graph.block", ".subject") %}
136
137
138 <h3 class="route"><code>GET /links/count/distinct-dids</code></h3>
139
140 <p>The total number of DIDs (identities) with links to at a given target.</p>
141
142 <h4>Query parameters:</h4>
143
144 <ul>
145 <li><code>target</code>: required, must url-encode. Example: <code>did:plc:vc7f4oafdgxsihk4cry2xpze</code></li>
146 <li><code>collection</code>: required. Example: <code>app.bsky.graph.block</code></li>
147 <li><code>path</code>: required, must url-encode. Example: <code>.subject</code></li>
148 <li><code>cursor</code>: optional, see Definitions.</li>
149 </ul>
150
151 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
152 {% call try_it::dids_count("did:plc:vc7f4oafdgxsihk4cry2xpze", "app.bsky.graph.block", ".subject") %}
153
154
155 <h3 class="route"><code>GET /links/all</code></h3>
156
157 <p>Show all sources with links to a target, including linking record counts and distinct linking DIDs</p>
158
159 <h4>Query parameters:</h4>
160
161 <ul>
162 <li><code>target</code>: required, must url-encode. Example: <code>did:plc:oky5czdrnfjpqslsw2a5iclo</code></li>
163 </ul>
164
165 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
166 {% call try_it::explore_links("did:plc:oky5czdrnfjpqslsw2a5iclo") %}
167
168
169 <h3 class="route deprecated"><code>[deprecated] GET /links/all/count</code></h3>
170
171 <p>The total counts of all links pointing at a given target, by collection and path.</p>
172
173 <p>DEPRECATED: Use <code>GET /links/all</code> instead.</p>
174
175 <h4>Query parameters:</h4>
176
177 <ul>
178 <li><code>target</code>: required, must url-encode. Example: <code>did:plc:oky5czdrnfjpqslsw2a5iclo</code></li>
179 </ul>
180
181 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
182 {% call try_it::links_all_count("did:plc:oky5czdrnfjpqslsw2a5iclo") %}
183
184
185 <h2>Definitions</h2>
186
187 <h3>Target</h3>
188
189 <p>A DID like <code>did:plc:hdhoaan3xa3jiuq4fg4mefid</code>, or an AT-URI like <code>at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3lgu4lg6j2k2v</code>, or a URI like <code>https://example.com</code>.</p>
190
191 <h3>Collection</h3>
192
193 <p>A record NSID like <code>app.bsky.feed.like</code>.</p>
194
195 <h3>Path</h3>
196
197 <p>A (currently-very-very-hacky) json-path-ish representation of the source of a link in a record. Records may contain multiple links with different meanings, so this specifies which specific link is of interest. Like <code>.subject.uri</code>.</p>
198
199 <h3>Cursor</h3>
200
201 <p>Paged responses include a <code>cursor</code> property. When it's <code>null</code>, no more data is available. If it's not null, you can repeat the request with <code>&cursor=<cursor></code> in the URL query to get the next set of responses.</p>
202
203
204{% endblock %}