A small tool to view real-world ActivityPub objects as JSON! Enter a URL
or username from Mastodon or a similar service below, and we'll send a
request with
the right
Accept
header
to the server to view the underlying object.
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"ostatus": "http://ostatus.org#",
"atomUri": "ostatus:atomUri",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"conversation": "ostatus:conversation",
"sensitive": "as:sensitive",
"toot": "http://joinmastodon.org/ns#",
"votersCount": "toot:votersCount",
"litepub": "http://litepub.social/ns#",
"directMessage": "litepub:directMessage",
"blurhash": "toot:blurhash",
"focalPoint": {
"@container": "@list",
"@id": "toot:focalPoint"
}
}
],
"id": "https://infosec.exchange/users/tychotithonus/collections/featured",
"type": "OrderedCollection",
"totalItems": 5,
"orderedItems": [
{
"id": "https://infosec.exchange/users/tychotithonus/statuses/112346738155571973",
"type": "Note",
"summary": null,
"inReplyTo": null,
"published": "2024-04-28T03:32:59Z",
"url": "https://infosec.exchange/@tychotithonus/112346738155571973",
"attributedTo": "https://infosec.exchange/users/tychotithonus",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://infosec.exchange/users/tychotithonus/followers"
],
"sensitive": false,
"atomUri": "https://infosec.exchange/users/tychotithonus/statuses/112346738155571973",
"inReplyToAtomUri": null,
"conversation": "tag:infosec.exchange,2024-04-28:objectId=154331494:objectType=Conversation",
"content": "<p>Standing invitation for any Mastodonians I've interacted with - if you're visiting Anchorage and need any tourist tips, or might enjoy a meetup ... send me a DM! The security-key museum, the Alaskan license-plate museum, and the SPAM museum are colocated. ;)</p>",
"contentMap": {
"en": "<p>Standing invitation for any Mastodonians I've interacted with - if you're visiting Anchorage and need any tourist tips, or might enjoy a meetup ... send me a DM! The security-key museum, the Alaskan license-plate museum, and the SPAM museum are colocated. ;)</p>"
},
"updated": "2024-04-28T20:09:21Z",
"attachment": [
{
"type": "Document",
"mediaType": "image/jpeg",
"url": "https://media.infosec.exchange/infosec.exchange/media_attachments/files/112/346/742/823/885/703/original/485bf8a25c73b7c8.jpeg",
"name": "Five rows of security keys in a wall-mounted case. Approximately 20 keys or ephemera per row.",
"blurhash": "UVFO=UMxoJoeD%ofj@oy~Wo0WVofn+ayWBof",
"focalPoint": [
0,
0
],
"width": 1663,
"height": 1247
},
{
"type": "Document",
"mediaType": "image/jpeg",
"url": "https://media.infosec.exchange/infosec.exchange/media_attachments/files/112/346/746/681/026/508/original/83f8cb617b74474d.jpeg",
"name": "A variety of Alaskan license plates on a garage wall, with other garage items strewn about. The \"run\" (as collectors call it) represents as many types as feasible that could theoretically still be \"on the road\" in Alaska.",
"blurhash": "UGHK,-D%XTsS~Us-xuo00gt8w@NHo~M|M|ad",
"focalPoint": [
0,
0
],
"width": 1663,
"height": 1247
},
{
"type": "Document",
"mediaType": "image/jpeg",
"url": "https://media.infosec.exchange/infosec.exchange/media_attachments/files/112/346/752/012/107/805/original/d18e04dfe35438ef.jpg",
"name": "Royce's collection of SPAM cans as of 2015. Along with standard-sized cans in a variety of US domestic and international flavors, small round cans, half-height cans, and packets are also featured.",
"blurhash": "UGF~BNtT%Nxv~p-;XA%M$*xuM{ozD*M{t3M{",
"focalPoint": [
0,
0
],
"width": 461,
"height": 800
}
],
"tag": [],
"replies": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/112346738155571973/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://infosec.exchange/users/tychotithonus/statuses/112346738155571973/replies?only_other_accounts=true&page=true",
"partOf": "https://infosec.exchange/users/tychotithonus/statuses/112346738155571973/replies",
"items": []
}
},
"likes": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/112346738155571973/likes",
"type": "Collection",
"totalItems": 33
},
"shares": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/112346738155571973/shares",
"type": "Collection",
"totalItems": 2
}
},
{
"id": "https://infosec.exchange/users/tychotithonus/statuses/110956256810149912",
"type": "Note",
"summary": "A question for new followers: why the follow?",
"inReplyTo": null,
"published": "2023-08-26T13:55:17Z",
"url": "https://infosec.exchange/@tychotithonus/110956256810149912",
"attributedTo": "https://infosec.exchange/users/tychotithonus",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://infosec.exchange/users/tychotithonus/followers"
],
"sensitive": true,
"atomUri": "https://infosec.exchange/users/tychotithonus/statuses/110956256810149912",
"inReplyToAtomUri": null,
"conversation": "tag:infosec.exchange,2023-08-26:objectId=90193369:objectType=Conversation",
"content": "<p>If you followed me recently ... can you reply here saying why (or liking the reply that matches your reason)?</p>",
"contentMap": {
"en": "<p>If you followed me recently ... can you reply here saying why (or liking the reply that matches your reason)?</p>"
},
"updated": "2023-10-24T17:55:11Z",
"attachment": [],
"tag": [],
"replies": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/110956256810149912/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://infosec.exchange/users/tychotithonus/statuses/110956256810149912/replies?only_other_accounts=true&page=true",
"partOf": "https://infosec.exchange/users/tychotithonus/statuses/110956256810149912/replies",
"items": []
}
},
"likes": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/110956256810149912/likes",
"type": "Collection",
"totalItems": 10
},
"shares": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/110956256810149912/shares",
"type": "Collection",
"totalItems": 0
}
},
{
"id": "https://infosec.exchange/users/tychotithonus/statuses/111019275557643551",
"type": "Note",
"summary": "Why my 'likes' may seem fast, yet intermittent:",
"inReplyTo": null,
"published": "2023-09-06T17:01:47Z",
"url": "https://infosec.exchange/@tychotithonus/111019275557643551",
"attributedTo": "https://infosec.exchange/users/tychotithonus",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://infosec.exchange/users/tychotithonus/followers"
],
"sensitive": true,
"atomUri": "https://infosec.exchange/users/tychotithonus/statuses/111019275557643551",
"inReplyToAtomUri": null,
"conversation": "tag:infosec.exchange,2023-09-06:objectId=92860412:objectType=Conversation",
"content": "<p>My Mastodon setup - multi-column, multiple curated lists, slow mode, heavily filtered - is optimized for real-time monitoring for breaking security-relevant info.</p><p>But I also see random posts about daily life flowing by at the same rate - so I often 'like' posts within <em>seconds</em> of their creation. From the follow's perspective, it can look like I'm camping on their account. I swear I'm not! 😅 </p><p>But since a lot of ordinary chatter is automatically filtered, I might not see some posts until after the work day ... or ever. So my pattern of 'likes' must seem strangely distributed. :D</p>",
"contentMap": {
"en": "<p>My Mastodon setup - multi-column, multiple curated lists, slow mode, heavily filtered - is optimized for real-time monitoring for breaking security-relevant info.</p><p>But I also see random posts about daily life flowing by at the same rate - so I often 'like' posts within <em>seconds</em> of their creation. From the follow's perspective, it can look like I'm camping on their account. I swear I'm not! 😅 </p><p>But since a lot of ordinary chatter is automatically filtered, I might not see some posts until after the work day ... or ever. So my pattern of 'likes' must seem strangely distributed. :D</p>"
},
"updated": "2024-12-08T14:58:40Z",
"attachment": [],
"tag": [],
"replies": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/111019275557643551/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://infosec.exchange/users/tychotithonus/statuses/111019275557643551/replies?only_other_accounts=true&page=true",
"partOf": "https://infosec.exchange/users/tychotithonus/statuses/111019275557643551/replies",
"items": []
}
},
"likes": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/111019275557643551/likes",
"type": "Collection",
"totalItems": 13
},
"shares": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/111019275557643551/shares",
"type": "Collection",
"totalItems": 0
}
},
{
"id": "https://infosec.exchange/users/tychotithonus/statuses/110838547200953177",
"type": "Note",
"summary": "Mastodon filter backup howto (API + curl):",
"inReplyTo": null,
"published": "2023-08-05T19:00:11Z",
"url": "https://infosec.exchange/@tychotithonus/110838547200953177",
"attributedTo": "https://infosec.exchange/users/tychotithonus",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://infosec.exchange/users/tychotithonus/followers"
],
"sensitive": true,
"atomUri": "https://infosec.exchange/users/tychotithonus/statuses/110838547200953177",
"inReplyToAtomUri": null,
"conversation": "tag:infosec.exchange,2023-08-05:objectId=84890340:objectType=Conversation",
"content": "<p>If you have a non-trivial amount of effort invested in your Mastodon filters, and want to regularly grab a manual full JSON backup:</p><p>First, get your access token:</p><ol><li><p>Go to the \"Development\" area of your individual preferences on your instance.</p></li><li><p>Click on \"New application\".</p></li><li><p>For \"Application name\", give your \"application\" a simple descriptive name (I chose \"filter-backup-ro\", where \"ro\" means \"read only\"),</p></li><li><p>For \"Application website\", a URL to your own website or whatever is fine - anything will do.</p></li><li><p>For \"Redirect URI\", leave the default \"urn:ietf:wg:oauth:2.0:oob\", which is for \"local tests\".</p></li><li><p>Under \"Scopes\", uncheck all the (few) default checked items, then check 'read:filters'.</p></li><li><p>Hit 'Submit'.</p></li><li><p>Go back into your newly created application and note/copy its 'Access token'.</p></li></ol><p>Then, on the command line:</p><p>curl -X GET \\<br> -H \"Authorization: Bearer [your-token-here]\" \\<br> <a href=\"https://inst.example/api/v2/filters\" target=\"_blank\" rel=\"nofollow noopener\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"\">inst.example/api/v2/filters</span><span class=\"invisible\"></span></a> \\<br> > filters-backup.json</p><p>Note that some instances may have an API endpoint hostname that's different from the main domain (for example, crank.infosec.exchange).</p><p>You can pipe the output to <code>python -m json.tool</code> if you want the JSON to be human-readable.</p><p>NOTE: If you change your app's permissions, the access token will be automatically regenerated!</p><p>And since the permissions are so nicely granular ... dropping your access token into a script, and adding a little extra to automatically name the file uniquely based on datestamp, makes for a low-risk, quick, convenient backup: <a href=\"https://gist.github.com/roycewilliams/d6462a23cbee520848a3c7c33c5fe870\" target=\"_blank\" rel=\"nofollow noopener\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">gist.github.com/roycewilliams/</span><span class=\"invisible\">d6462a23cbee520848a3c7c33c5fe870</span></a></p>",
"contentMap": {
"en": "<p>If you have a non-trivial amount of effort invested in your Mastodon filters, and want to regularly grab a manual full JSON backup:</p><p>First, get your access token:</p><ol><li><p>Go to the \"Development\" area of your individual preferences on your instance.</p></li><li><p>Click on \"New application\".</p></li><li><p>For \"Application name\", give your \"application\" a simple descriptive name (I chose \"filter-backup-ro\", where \"ro\" means \"read only\"),</p></li><li><p>For \"Application website\", a URL to your own website or whatever is fine - anything will do.</p></li><li><p>For \"Redirect URI\", leave the default \"urn:ietf:wg:oauth:2.0:oob\", which is for \"local tests\".</p></li><li><p>Under \"Scopes\", uncheck all the (few) default checked items, then check 'read:filters'.</p></li><li><p>Hit 'Submit'.</p></li><li><p>Go back into your newly created application and note/copy its 'Access token'.</p></li></ol><p>Then, on the command line:</p><p>curl -X GET \\<br> -H \"Authorization: Bearer [your-token-here]\" \\<br> <a href=\"https://inst.example/api/v2/filters\" target=\"_blank\" rel=\"nofollow noopener\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"\">inst.example/api/v2/filters</span><span class=\"invisible\"></span></a> \\<br> > filters-backup.json</p><p>Note that some instances may have an API endpoint hostname that's different from the main domain (for example, crank.infosec.exchange).</p><p>You can pipe the output to <code>python -m json.tool</code> if you want the JSON to be human-readable.</p><p>NOTE: If you change your app's permissions, the access token will be automatically regenerated!</p><p>And since the permissions are so nicely granular ... dropping your access token into a script, and adding a little extra to automatically name the file uniquely based on datestamp, makes for a low-risk, quick, convenient backup: <a href=\"https://gist.github.com/roycewilliams/d6462a23cbee520848a3c7c33c5fe870\" target=\"_blank\" rel=\"nofollow noopener\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">gist.github.com/roycewilliams/</span><span class=\"invisible\">d6462a23cbee520848a3c7c33c5fe870</span></a></p>"
},
"updated": "2023-10-16T01:45:56Z",
"attachment": [
{
"type": "Document",
"mediaType": "image/jpeg",
"url": "https://media.infosec.exchange/infosec.exchange/media_attachments/files/110/838/651/642/632/443/original/709810de732109ed.jpg",
"name": "Output from example backup script, showing filename and size, and a count of filters (540) and keywords (10,160) in the filter set.",
"blurhash": "U24_%^?cxuxu_3t7M{RjRj%Mofay9F%M%Mof",
"focalPoint": [
0,
0
],
"width": 762,
"height": 152
}
],
"tag": [],
"replies": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/110838547200953177/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://infosec.exchange/users/tychotithonus/statuses/110838547200953177/replies?only_other_accounts=true&page=true",
"partOf": "https://infosec.exchange/users/tychotithonus/statuses/110838547200953177/replies",
"items": []
}
},
"likes": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/110838547200953177/likes",
"type": "Collection",
"totalItems": 11
},
"shares": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/110838547200953177/shares",
"type": "Collection",
"totalItems": 1
}
},
{
"id": "https://infosec.exchange/users/tychotithonus/statuses/109450611057236855",
"type": "Note",
"summary": "Why Mastodon filters are the killer app:",
"inReplyTo": null,
"published": "2022-12-03T16:09:46Z",
"url": "https://infosec.exchange/@tychotithonus/109450611057236855",
"attributedTo": "https://infosec.exchange/users/tychotithonus",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://infosec.exchange/users/tychotithonus/followers"
],
"sensitive": true,
"atomUri": "https://infosec.exchange/users/tychotithonus/statuses/109450611057236855",
"inReplyToAtomUri": null,
"conversation": "tag:infosec.exchange,2022-12-03:objectId=26343246:objectType=Conversation",
"content": "<p>Whoever created the Mastodon filtering feature set that allows a \"This post was filtered by these five filters, click here to show the post anyway\" approach was a <em>genius</em>.</p><p>Any platform that doesn't have this functionality no longer interests me. It has permanently altered my perspective on input triage.</p><p>It's not perfect - I have spent a lot of time sampling filtered messages to reduce false positives. And some clients can't handle 6000¹ filter keywords(!). </p><p>There's also a very real danger of sticking your head in the sand - constructing your own de-facto social media bubble. So it's important to make a habit of sampling posts on important filtered topics.</p><p>And all that work is also at risk - there's currently no in-app Mastodon way to export filters or back them up (without backend database access or API calls).</p><p>But even if my filters vanished today, I would <em>immediately</em> start reconstructing them.</p><p>Mastodon filters are like TiVo - now that I've experienced the world with them, I'll never go back. And any platform that lacks this feature set is ... broken.</p><p>¹As of 2024-10:<br>Filters: 802; Keywords: 25036</p>",
"contentMap": {
"en": "<p>Whoever created the Mastodon filtering feature set that allows a \"This post was filtered by these five filters, click here to show the post anyway\" approach was a <em>genius</em>.</p><p>Any platform that doesn't have this functionality no longer interests me. It has permanently altered my perspective on input triage.</p><p>It's not perfect - I have spent a lot of time sampling filtered messages to reduce false positives. And some clients can't handle 6000¹ filter keywords(!). </p><p>There's also a very real danger of sticking your head in the sand - constructing your own de-facto social media bubble. So it's important to make a habit of sampling posts on important filtered topics.</p><p>And all that work is also at risk - there's currently no in-app Mastodon way to export filters or back them up (without backend database access or API calls).</p><p>But even if my filters vanished today, I would <em>immediately</em> start reconstructing them.</p><p>Mastodon filters are like TiVo - now that I've experienced the world with them, I'll never go back. And any platform that lacks this feature set is ... broken.</p><p>¹As of 2024-10:<br>Filters: 802; Keywords: 25036</p>"
},
"updated": "2024-10-22T15:43:30Z",
"attachment": [
{
"type": "Document",
"mediaType": "image/png",
"url": "https://media.infosec.exchange/infosec.exchange/media_attachments/files/109/450/551/610/412/361/original/fea7c1ac54407922.png",
"name": "A screenshot from mobile where an entire screenful of Mastodon posts has been filtered by a variety of topics, from movies to politics to the fediverse to general chatter. Since multiple filters can match, some posts match five topics or more, allowing you to make a pretty good guess about the content, and decide whether or not you want to read it.",
"blurhash": "U05E]bRf9DtBogWTohjvWCawohaxj]awj]j^",
"focalPoint": [
0,
0
],
"width": 1030,
"height": 2013
}
],
"tag": [],
"replies": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/109450611057236855/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://infosec.exchange/users/tychotithonus/statuses/109450611057236855/replies?min_id=113068944765848255&page=true",
"partOf": "https://infosec.exchange/users/tychotithonus/statuses/109450611057236855/replies",
"items": [
"https://infosec.exchange/users/tychotithonus/statuses/109450642984598211",
"https://infosec.exchange/users/tychotithonus/statuses/113068944765848255"
]
}
},
"likes": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/109450611057236855/likes",
"type": "Collection",
"totalItems": 27
},
"shares": {
"id": "https://infosec.exchange/users/tychotithonus/statuses/109450611057236855/shares",
"type": "Collection",
"totalItems": 10
}
}
]
}