Platforms
Supported platforms
Each platform maps ActivityStreams 2.0 onto a specific network. Same JSON envelope on the way in, same shape on the way back. If you need more, the platform interface is small enough to implement in an afternoon.
IRC
Chat and channels on the original open protocol.
Speak to any IRC network — Libera, OFTC, your local. Sockethub handles reconnects, PINGs, and nick collision for you.
The full IRC flow is
credentials → connect → join → send.
Each envelope shares the same @context; only
type and the target change.
1. Credentials
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://sockethub.org/ns/context/v1.jsonld",
"https://sockethub.org/ns/context/platform/irc/v1.jsonld"
],
"type": "credentials",
"actor": {
"id": "alice@irc.libera.chat",
"type": "person"
},
"object": {
"type": "credentials",
"nick": "alice",
"server": "irc.libera.chat",
"port": 6697,
"secure": true,
"token": "…"
}
}
2. Connect
{
"@context": [ /* as above */ ],
"type": "connect",
"actor": { "id": "alice@irc.libera.chat", "type": "person" }
}
3. Join a channel
{
"@context": [ /* as above */ ],
"type": "join",
"actor": { "id": "alice@irc.libera.chat", "type": "person" },
"target": { "id": "#sockethub@irc.libera.chat", "type": "room" }
}
4. Send a message
{
"@context": [ /* as above */ ],
"type": "send",
"actor": { "id": "alice@irc.libera.chat", "type": "person" },
"target": { "id": "#sockethub@irc.libera.chat", "type": "room" },
"object": { "type": "message", "content": "hey everyone" }
}
XMPP
Federated messaging, rooms, and presence.
Connect to any XMPP service — public or self-hosted. Multi-user chat, direct messages, presence, and roster updates all come through as ActivityStreams objects.
Full XMPP MUC flow is
credentials → connect → join → send. For a 1:1
message to a contact, skip join and target the
person JID directly (shown at the end).
1. Credentials
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://sockethub.org/ns/context/v1.jsonld",
"https://sockethub.org/ns/context/platform/xmpp/v1.jsonld"
],
"type": "credentials",
"actor": {
"id": "alice@chat.example",
"type": "person"
},
"object": {
"type": "credentials",
"userAddress": "alice@chat.example",
"password": "…",
"server": "chat.example",
"resource": "sockethub"
}
}
2. Connect
{
"@context": [ /* as above */ ],
"type": "connect",
"actor": { "id": "alice@chat.example", "type": "person" }
}
3. Join a room (MUC)
{
"@context": [ /* as above */ ],
"type": "join",
"actor": { "id": "alice@chat.example", "type": "person" },
"target": { "id": "sockethub@conference.chat.example", "type": "room" }
}
4a. Send to the room
{
"@context": [ /* as above */ ],
"type": "send",
"actor": { "id": "alice@chat.example", "type": "person" },
"target": { "id": "sockethub@conference.chat.example", "type": "room" },
"object": { "type": "message", "content": "hey everyone" }
}
4b. Send 1:1 to a contact (no join needed)
{
"@context": [ /* as above */ ],
"type": "send",
"actor": { "id": "alice@chat.example", "type": "person" },
"target": { "id": "bob@chat.example", "type": "person" },
"object": { "type": "message", "content": "ping" }
}
RSS / Atom
Fetch, parse, and stream updates from feeds.
Point the feeds platform at any RSS or Atom URL and it returns normalized entries as ActivityStreams objects. Useful for reader apps, dashboards, or anywhere you'd otherwise reach for a polling cron.
Fetch once
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://sockethub.org/ns/context/v1.jsonld",
"https://sockethub.org/ns/context/platform/feeds/v1.jsonld"
],
"type": "fetch",
"actor": { "id": "https://example.org/reader", "type": "person" },
"target": { "id": "https://blog.example/feed.xml", "type": "feed" }
}
Metadata
Link previews and structured-data extraction.
Fetch a URL, extract Open Graph, oEmbed, microformats2, and JSON-LD, and hand back a single normalized object. Built for chat link previews and reader summaries.
Fetch metadata for a URL
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://sockethub.org/ns/context/v1.jsonld",
"https://sockethub.org/ns/context/platform/metadata/v1.jsonld"
],
"type": "fetch",
"actor": { "id": "https://example.org/reader", "type": "person" },
"target": { "id": "https://blog.example/article", "type": "link" }
}
CalDAV
Calendars, events, and tasks on any CalDAV server.
Discover calendars, then read, create, update, and delete events
(VEVENT) and tasks (VTODO) on any CalDAV
server — Nextcloud, Radicale, Fastmail, and friends. Every write is
guarded by an ETag check, so you never silently overwrite a change
made by another client.
The full CalDAV flow is
credentials → fetch → query / create / update / delete.
fetch discovers your calendars; every later request
targets one of the discovered calendar URLs.
1. Credentials
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://sockethub.org/ns/context/v1.jsonld",
"https://sockethub.org/ns/context/platform/caldav/v1.jsonld"
],
"type": "credentials",
"actor": {
"id": "caldav:alice",
"type": "person"
},
"object": {
"type": "credentials",
"url": "https://calendar.example/dav/",
"token": "…"
}
}
token is sent as an HTTP Bearer token (your app runs the
OAuth flow itself). For Basic auth — typically an app password —
replace it with username and password. The
URL can be a service root; discovery also tries
/.well-known/caldav.
2. Discover calendars
{
"@context": [ /* as above */ ],
"type": "fetch",
"actor": { "id": "caldav:alice", "type": "person" }
}
The response lists your calendars as objects with an id
(the calendar URL), a name, a color, and
which components they support (event,
task).
3. Query events in a date range
{
"@context": [ /* as above */ ],
"type": "query",
"actor": { "id": "caldav:alice", "type": "person" },
"target": {
"id": "https://calendar.example/calendars/alice/personal/",
"type": "calendar"
},
"object": {
"type": "event",
"startTime": "2026-08-01T00:00:00Z",
"endTime": "2026-09-01T00:00:00Z"
}
}
Each returned item carries its resource id,
uid, and etag — keep the ETag for later
update or delete requests.
4. Create an event
{
"@context": [ /* as above */ ],
"type": "create",
"actor": { "id": "caldav:alice", "type": "person" },
"target": {
"id": "https://calendar.example/calendars/alice/personal/",
"type": "calendar"
},
"object": {
"type": "event",
"name": "Project planning",
"startTime": "2026-08-03T15:00:00",
"endTime": "2026-08-03T16:00:00",
"timeZone": "Europe/Prague"
}
}
Events and tasks support recurrence, attendees, reminders, and
attachments. update and delete send the
item's etag; if another client changed it in the
meantime you get caldav:conflict back — query again and
retry with the fresh ETag.
Want to add another protocol? Platform interface Get started