Ir al contenido

Events: federation notes

Documentación 16 min de lectura Fuente en codefloeSolo en inglés

En esta página

What Catodon sends and accepts for events, and what each piece of fediverse software it was tested against does with them. This page is for developers and administrators. For users, see Events.

Catodon follows FEP-8a8e (the draft as of October 2026). It was tested live in October 2026 against the versions in the table at the end. Where a server's behaviour is described from its source code rather than seen live, this page says so.

What Catodon sends

The event

A local event goes out as Create(Event), and an edit as Update(Event). The object carries:

  • name: the title.

  • content: the description, without the title. Most software shows name and content together, and repeating the title in content showed it twice on Mobilizon and Friendica.

  • source and _misskey_content: the description, opened by a header of the title (bold), the when-and-where lines and a link to the event. Misskey, Sharkey and Catodon releases from before events read these first and know nothing of events, so without it they showed no date (and Misskey and Sharkey no title). Mobilizon, Gancio and Friendica read content, and Mastodon none of the three, so none of them see the header.

  • catodon:eventSource: the source without that header (content empty when there is no description), which a Catodon that shows events reads instead.

  • summary: one line saying when and where, e.g. Fri, 20 Nov 2026, 20:30 – 23:00 (Europe/Athens) · Town hall, 1 Main Street, Athens. A status other than scheduled leads it (Cancelled: …). Mastodon shows only name, summary and a link for an Event, so without it Mastodon users would see no date. If the post has a content warning (the author's own or one the account must carry), the summary is <warning> — <when and where>, so the date is never lost. < and > are escaped, & is not: the Misskey family reads summary as plain text. An event that takes answers here (joinMode free or invite) adds one English sentence after the line, set off from it by a period:

    To answer from a server without events, send @events.bot@<server> a private message saying "yes" or "no" and this event's link: <link>

    It is in English on purpose, like the rest of the line: the server does not know who will read it. There is no period after the link, which some software would take as part of it, and the link is there although Mastodon shows it again just below: Hubzilla shows the summary as the post's text, and Gancio uses it as the description of an event that has none. A cancelled event leaves the sentence out (the cancellation goes out as an Update); a full or finished one keeps it, since nothing is sent when an event fills up or ends, and the account's reply says why it refuses a yes. The events account it names is created before the event goes out, if it does not exist yet; if that fails, the event goes out without the sentence.

  • startTime, endTime, timezone (IANA name). An event with no end gets endTime at the end of its start day and displayEndTime: false, since FEP-8a8e requires endTime.

  • location: one Place, or an array of them, with name, address (a PostalAddress when the parts are known), latitude, longitude and url (an online link). A place given only an address uses the address as its name: Gancio drops a place without a name, and the online links with it.

  • eventStatus (FEP-8a8e) and ical:status (what Mobilizon reads).

  • joinMode (free, external, none, or invite for a private event), externalParticipationUrl, maximumAttendeeCapacity, category (Mobilizon's category names).

  • organizers: a collection of the author, and the forum for a forum event.

  • attendees: the event's attendees collection. Its totalItems is public; its items are served to the organizer only.

Each actor also has an upcomingEvents collection.

Forum events

An event posted in a forum goes out with the forum as audience, like other forum posts. To a forum on NodeBB, Mbin or PieFed (by the remote server's NodeInfo software name) it goes out as a Page instead, with no FEP-8a8e fields and the when-and-where lines as a paragraph at the top of content: those three don't take an Event (see below). It carries no source or _misskey_content either, since those forums read Markdown source first.

Private events

A private (invite-only) event is a direct post addressed to the invitees. Each server is sent its own invitees only, in cc with to empty, so no server learns who else was invited. With a single invitee in to, Friendica took the event for a private message and dropped its date and place.

Catodon sends no Invite activity: only Create(Event) addressed to the invitees. Of the servers tested, only Hubzilla sends Invite, and for every event, public or not.

Invitations to public events

Anyone who can see a public or unlisted event may invite people to it (a private event's invitees stay its creator's to choose). Someone on another server gets a direct message from whoever invited them: a mention, the title, when and where, and the event's link. The message carries catodon:inviteTo (the event's id). A Catodon that has these invitations reads it as an invitation: it notifies the people it names ("invited you to an event"), lists the event under their unanswered invitations, and does not keep the message, so nobody is told twice. Any other server shows the message as it is. Nothing tells the inviting server whether the other end took it as an invitation, so the message is sent whatever runs there.

Answers to other servers' events

The answer goes in the dialect the event's server speaks, chosen when the event first arrives:

Join dialect Accept dialect
Used by FEP-8a8e, Mobilizon Friendica, Hubzilla
Going Join (the organizer answers Accept or Reject) Accept
Maybe not offered TentativeAccept
Not going / taking back Leave Reject, Undo of the earlier answer

Answers are sent to the organizer only. For an event that arrived inside an Invite (Hubzilla), the Accept, TentativeAccept, Reject and their Undo name the Invite's id as object, because Hubzilla files the event under it.

Text formatting

MFM emphasis goes out as strong, em and s (not b, i, del), and $[unixtime …] as its date in a span (not time). PieFed removes b, i, del and time together with the text inside them.

What Catodon accepts

  • Create, Update and Delete of an Event, and Invite(Event), which is read as a Create. An Event with catodon:eventSource takes its text from there, not from source.
  • A direct post with catodon:inviteTo naming a public or unlisted event: an invitation, as above. If the event can't be fetched, the post is kept as an ordinary direct message. An object needs name and startTime to be read as an event; without them it stays an ordinary post.
  • summary of an incoming Event is not a content warning; content is the description.
  • location as one object or an array, Place or VirtualLocation, with address as text or a PostalAddress. Status from eventStatus, then ical:status, then status. A time zone that isn't a valid IANA name is dropped, and so is an endTime not after startTime.
  • With no valid timezone, the offset startTime is written in becomes an Etc/GMT±N zone (+02:00 → Etc/GMT-2: IANA's sign is inverted), stored like any zone and labelled GMT+2 on the card and in the Mastodon text. Only whole hours have such a zone; ±HH:30/:45 give none. Z and ±00:00 give none either: Friendica converts every event to UTC and writes +00:00 (Transmitter::createEvent, PHP's 'c'), and Hubzilla writes -00:00, RFC 3339's "offset unknown", for an event with no zone, so neither says where the organizer is. The same applies to an Update.
  • Group events (Mobilizon): the member in actor is the author and the group in attributedTo is the forum. This is trusted only when the event, the member and the group are on the same server, or when the group itself Announces the event. Otherwise the event is the member's own, with no forum. A group that answers 404 or 410 is gone for good, and Mobilizon serves the events of a group it does not serve itself (a private or unlisted one): such an event is the member's own, with no forum, when the member is on the event's own server, and stays refused otherwise. A group that is only down for now (429, 5xx, or no answer at all) holds the event back to be tried again.
  • Answers to local events, in both dialects: Join and Leave; Accept, TentativeAccept, Reject, TentativeReject with the event as object; Undo of each. An event open to all accepts a Join while it has places (Accept(Join)) and refuses it when full (Reject(Join)). One that takes no answers here answers Ignore, as FEP-8a8e asks. A private event refuses anyone not invited.
  • Answers to our Join: Accept or Reject naming our Join, from the event's author, or for a group event from the group or anyone on the group's server. Mobilizon answers a group event's Join from one of the group's moderators. The local user is notified (eventRsvpAnswered).

Per software

Mobilizon (5.1.5, mobilizon.us)

  • Its events here: personal and group events arrive with title, description, times, time zone, place with address and coordinates, category and join mode. A cancellation arrives as an Update and is shown as one.
  • Following: Mobilizon accepts follows of groups and of the instance only (transmogrifier.ex: "Only group and instances can be followed") and never answers a follow of a person. Catodon refuses a follow of a person before sending it, and nothing is left pending. The API answers MOBILIZON_PERSON ("Mobilizon only lets you follow groups."); the web interface says "Mobilizon only lets you follow groups. To see this person's events, follow a group they organize events in."; the Mastodon API answers HTTP 400 with that first sentence in error and MOBILIZON_PERSON in error_code. A follow of a group is accepted within seconds. A follow of the instance actor (/relay, an Application) is sent; on mobilizon.us it was still pending at the end of the test, most likely waiting for its admin to approve it (not checked in Mobilizon's source). A personal event is therefore never pushed; it can be fetched by its URL. A group's events reach its followers through the group's Announce (the member's own Create is addressed to the member's followers only).
  • Answering its events: Join → Accept within seconds on an open event. On an event that approves its participants, the answer waits until a moderator approves (Accept) or rejects (Reject, which can also come after an approval), and the local user is notified either way, from the moderator who decided. An open event's quick Accept makes no notification; either answer updates the event on the user's open pages. Leave removes the participant there.
  • Our events there: the description is the post's body alone. Date, time zone, category, capacity, place, coordinates and join mode are read. Mobilizon ignores summary: read in its source, and seen live (its copy of the event has no field holding it, and its event page builds its own date-and-place line). A Mobilizon user's join of our event comes as Join and is answered; leaving comes as Leave.
  • Our private events there: stored as unlisted with join mode "invite". The invitee can open it by its address while signed in and join it, but Mobilizon tells the invitee nothing about the invitation: no notification, nothing in their participations. Once they join and we accept, Mobilizon emails them that their participation was accepted.
  • Deleting our event: Mobilizon 5.1.5 keeps its copy. We send Delete to the invitees of a private event and to the followers of a public one, but Mobilizon does not take a Delete as proof: it fetches the object again and removes its copy only if that fetch answers 410 Gone (transmogrifier.ex, group_object_gone_check). A deleted post here answers 404, as on Mastodon, and 5.1.5 drops the Delete on a 404. Seen live on three private events: each copy stayed, and the server log shows Mobilizon's fetch, answered 404, a second after the Delete. Mobilizon 5.2.0 also accepts a 404 (read in the source of the 5.2.0, 5.2.2, 5.2.4 and 5.2.5-RC.1 tags; not tested live), so a Mobilizon server on 5.2.0 or later should remove its copy.
  • Attendee count: Mobilizon sends no Update when someone joins. Our copy asks again for the event (its participantCount, which leaves out the organizer) when a signed-in user opens it or lists it on the Events page, at most every ten minutes per event while it is to come; in between, the count can be behind.

Gancio (1.28.2)

  • Its instance actor (an Application) is followed like any account; the follow is accepted at once. Its events arrive with title, description, start, end and place (address as text), and an edit arrives as an Update. Gancio sends no join mode, so its events take no answers, and no time zone. It writes startTime in the instance's offset (2026-10-03T21:00:00.000+02:00 from gancio.cisti.org), which we keep as Etc/GMT-2 (see "What Catodon accepts"), so the card shows the organizer's wall time, labelled GMT+2. (One-off check when this was built, 2026-10-17, Gancio 1.28.2: gancio.cisti.org's event 7412 showed "14:00 GMT+2 – 21:00 GMT+2", with the viewer's own time under it.) It is the offset of the event's start: an event spanning a daylight-saving change shows its end at that offset too, which is the right moment, labelled with the start's offset. Events stored before this keep no zone (the offset was lost) until Gancio sends an Update of them.
  • Gancio logs a delivery as failed unless the answer's Content-Type contains "json" (server/federation/helpers.js). Our inbox answered 202 with none (the deliveries succeeded anyway); it now answers application/activity+json with {}. Not re-tested live since.
  • From its source, not tested live: Gancio drops a place without a name, and uses summary as the description when there is no content.

Friendica (2026.05)

  • Its events here: arrive as events, answered in the accept dialect. Our going, maybe and not-going answers reach it, the previous one undone.
  • Our events there: stored as calendar events. Friendica's own users' going / maybe / not going reach us. Friendica batches deliveries every few minutes, so answers can take that long.
  • Private events: one invitee or more, stored as a private event the invitee can answer (since invitees are in cc).
  • Limits on Friendica's side:
    • It drops the location of every incoming event, ours and Mobilizon's alike (Receiver.php reads location/@value from an already-flattened string).
    • It stores our summary as the post's content warning. Its web interface shows it as a summary line, but its Mastodon API serves it as spoiler_text, so Mastodon apps on Friendica collapse the description behind the date line.

Hubzilla (11.4.1)

  • Its events here: arrive as Invite(Event), answered in the accept dialect, naming the Invite (see above).
  • Our events there: plain posts with the title and the when-and-where line; the description is folded behind "View article", because Hubzilla treats summary as a teaser. They are not calendar entries: Hubzilla never reads a foreign Event's startTime (Activity.php tests the wrong end of the string for Z), so the summary line is the only date it shows. Mobilizon's events have the same problem there.
  • Hubzilla users' answers to our events (accept, tentative accept, reject, each with Undo) reach us. Private events arrive as private items the invitee can answer.

Mastodon (4.5.11; 4.6 rc read in source)

  • Mastodon converts an Event to a status showing name, then summary, then a link to the event. It ignores content. So Mastodon users see the title, the when-and-where line and a link, never the description.
  • A private event is a direct status with a mention notification, with the same title, line and link (the link needs signing in here).
  • Mastodon sends no events and no answers.
  • A direct message from a Mastodon user to an account here arrives whether or not the sender follows anyone here (seen live, 4.5.11, 2026-10-24). It is a Create of a Note with to holding only the mentioned actor, cc empty, one Mention in tag, and inReplyTo null unless it is a reply. The text starts with the mention, shown as the bare username (@carol, without the server). Replying to a direct message in Mastodon's web interface prefills @<author>@<server> and keeps the reply direct.
  • Mastodon 4.5's default notification policy filters private mentions from accounts the recipient does not follow into "notification requests", out of the notifications list. A direct message that replies to one where the recipient mentioned the sender is let through (seen live). So a direct message sent from here to a Mastodon user who wrote first is only seen promptly if it is a reply to theirs.
  • A Mastodon user answers one of our events by sending a private mention to @events.bot@<server> containing "yes" or "no" (or a few other words, see Events: for administrators) and the event's link (https://<server>/notes/<id>) or its id, in any order. A reply to one of the account's replies needs no link. The account replies into the message's thread, which is what keeps the reply out of Mastodon's notification requests. No activity goes back: no Accept, no Reject, since the organizer is on this server and Mastodon would ignore one anyway. The answer is recorded under the message's id, so deleting the message (a Delete) takes the answer back. It works for this server's events only.
  • Mastodon shows the summary sentence telling how to answer (see "The event" above) between the when-and-where line and the event's link.

Lemmy (1.0.0-beta.2)

  • A forum event, sent as Event, is accepted as a post into the community, both when our user posts it there and when our forum announces it. Lemmy keeps the title and description and drops the date and place.
  • Lemmy 0.19 has the same Event post type in its source; it was not run live.

NodeBB (7.3.1), Mbin, PieFed (1.9.0-dev)

  • None of them takes an Event: NodeBB drops it silently, Mbin logs "unknown type Event" and ignores it, and PieFed fails on it (it reads its own event keys without checking they exist). Forum events go to them as a Page with the date and place at the top, and arrive as an ordinary topic or thread.
  • PieFed also removes b, i, del and time with their text, hence the formatting rules above.

Misskey, Sharkey and Catodon before 26.10.0

  • They read an Event as a post, take summary as a content warning and ignore name. Our events show there as the when-and-where line as a content warning, with the source behind it: the title, when and where, the link, and the description. On an event that takes answers, the warning also holds the sentence telling Mastodon users how to answer by message: a longer warning, which is the cost of the one place Mastodon shows.
  • Catodon 26.10.0 and 26.10.1 do not take summary as a content warning and do show name, so they show the title, then the source header (the title again, when and where, the link), then the description.
  • They send no events and no answers.

Versions tested

Software Version How
Mobilizon 5.1.5 live, mobilizon.us (re-tested 2026-10-17)
Gancio 1.28.2 live, gancio.cisti.org and a local install
Friendica 2026.05 local install
Hubzilla 11.4.1 local install (pubcrawl)
Mastodon 4.5.11 local install; 4.6 rc in source
Lemmy 1.0.0-beta.2 local install
NodeBB 7.3.1 local install
Mbin current image, October 2026 local install
PieFed 1.9.0-dev local install