diff --git a/js/src/common.scss b/js/src/common.scss
index db448b2f5..f739115fc 100644
--- a/js/src/common.scss
+++ b/js/src/common.scss
@@ -1,24 +1,14 @@
+@import "variables.scss";
+
 a {
+  color: $violet-2;
+}
+
+a.out,
+.content a {
   text-decoration: underline;
   text-decoration-color: #ed8d07;
   text-decoration-thickness: 2px;
-
-  &.navbar-item,
-  &.dropdown-item,
-  &.card,
-  &.button,
-  &[href="#comments"],
-  &.router-link-active,
-  &.comment-link,
-  &.pagination-link,
-  &.datepicker-cell,
-  &.list-item {
-    text-decoration: none;
-  }
-}
-
-nav.breadcrumb ul li a {
-  text-decoration: none;
 }
 
 input.input {
diff --git a/js/src/components/Discussion/DiscussionListItem.vue b/js/src/components/Discussion/DiscussionListItem.vue
index 280704893..ab6bc2938 100644
--- a/js/src/components/Discussion/DiscussionListItem.vue
+++ b/js/src/components/Discussion/DiscussionListItem.vue
@@ -15,8 +15,8 @@
     <div class="title-info-wrapper">
       <div class="title-and-date">
         <p class="discussion-minimalist-title">{{ discussion.title }}</p>
-        <span :title="discussion.updatedAt | formatDateTimeString">
-          {{ $timeAgo.format(new Date(discussion.updatedAt), "twitter") || $t("Right now") }}</span
+        <span :title="actualDate | formatDateTimeString">
+          {{ $timeAgo.format(new Date(actualDate), "twitter") || $t("Right now") }}</span
         >
       </div>
       <div class="has-text-grey" v-if="!discussion.lastComment.deletedAt">
@@ -46,6 +46,13 @@ export default class DiscussionListItem extends Vue {
     }
     return element.innerText;
   }
+
+  get actualDate() {
+    if (this.discussion.updatedAt === this.discussion.insertedAt && this.discussion.lastComment) {
+      return this.discussion.lastComment.publishedAt;
+    }
+    return this.discussion.updatedAt;
+  }
 }
 </script>
 <style lang="scss" scoped>
diff --git a/js/src/components/Settings/SettingsMenu.vue b/js/src/components/Settings/SettingsMenu.vue
index a901edddc..c87d3df52 100644
--- a/js/src/components/Settings/SettingsMenu.vue
+++ b/js/src/components/Settings/SettingsMenu.vue
@@ -37,6 +37,7 @@
         <SettingMenuItem :title="$t('Moderation log')" :to="{ name: RouteName.REPORT_LOGS }" />
         <SettingMenuItem :title="$t('Users')" :to="{ name: RouteName.USERS }" />
         <SettingMenuItem :title="$t('Profiles')" :to="{ name: RouteName.PROFILES }" />
+        <SettingMenuItem :title="$t('Groups')" :to="{ name: RouteName.ADMIN_GROUPS }" />
       </SettingMenuSection>
       <SettingMenuSection
         v-if="this.currentUser.role == ICurrentUserRole.ADMINISTRATOR"
diff --git a/js/src/graphql/discussion.ts b/js/src/graphql/discussion.ts
index 90c96a2f7..29d04557b 100644
--- a/js/src/graphql/discussion.ts
+++ b/js/src/graphql/discussion.ts
@@ -5,6 +5,7 @@ export const DISCUSSION_BASIC_FIELDS_FRAGMENT = gql`
     id
     title
     slug
+    insertedAt
     updatedAt
     lastComment {
       id
@@ -16,6 +17,7 @@ export const DISCUSSION_BASIC_FIELDS_FRAGMENT = gql`
           url
         }
       }
+      publishedAt
       deletedAt
     }
   }
@@ -114,6 +116,7 @@ export const GET_DISCUSSION = gql`
           insertedAt
           updatedAt
           deletedAt
+          publishedAt
         }
       }
       ...DiscussionFields
diff --git a/js/src/graphql/group.ts b/js/src/graphql/group.ts
index 7f45ccf83..1dddfe9dd 100644
--- a/js/src/graphql/group.ts
+++ b/js/src/graphql/group.ts
@@ -4,8 +4,24 @@ import { RESOURCE_METADATA_BASIC_FIELDS_FRAGMENT } from "./resources";
 import { POST_BASIC_FIELDS } from "./post";
 
 export const LIST_GROUPS = gql`
-  query {
-    groups {
+  query ListGroups(
+    $preferredUsername: String
+    $name: String
+    $domain: String
+    $local: Boolean
+    $suspended: Boolean
+    $page: Int
+    $limit: Int
+  ) {
+    groups(
+      preferredUsername: $preferredUsername
+      name: $name
+      domain: $domain
+      local: $local
+      suspended: $suspended
+      page: $page
+      limit: $limit
+    ) {
       elements {
         id
         url
@@ -34,109 +50,128 @@ export const LIST_GROUPS = gql`
   }
 `;
 
+export const GROUP_FIELDS_FRAGMENTS = gql`
+  fragment GroupFullFields on Group {
+    id
+    url
+    name
+    domain
+    summary
+    preferredUsername
+    suspended
+    visibility
+    physicalAddress {
+      description
+      street
+      locality
+      postalCode
+      region
+      country
+      geom
+      type
+      id
+      originId
+    }
+    avatar {
+      url
+    }
+    banner {
+      url
+    }
+    organizedEvents {
+      elements {
+        id
+        uuid
+        title
+        beginsOn
+      }
+      total
+    }
+    discussions {
+      total
+      elements {
+        ...DiscussionBasicFields
+      }
+    }
+    posts {
+      total
+      elements {
+        ...PostBasicFields
+      }
+    }
+    members {
+      elements {
+        role
+        actor {
+          id
+          name
+          domain
+          preferredUsername
+          avatar {
+            url
+          }
+        }
+        insertedAt
+      }
+      total
+    }
+    resources(page: 1, limit: 3) {
+      elements {
+        id
+        title
+        resourceUrl
+        summary
+        updatedAt
+        type
+        path
+        metadata {
+          ...ResourceMetadataBasicFields
+        }
+      }
+      total
+    }
+    todoLists {
+      elements {
+        id
+        title
+        todos {
+          elements {
+            id
+            title
+            status
+            dueDate
+            assignedTo {
+              id
+              preferredUsername
+            }
+          }
+          total
+        }
+      }
+      total
+    }
+  }
+`;
+
 export const FETCH_GROUP = gql`
   query($name: String!) {
     group(preferredUsername: $name) {
-      id
-      url
-      name
-      domain
-      summary
-      preferredUsername
-      suspended
-      visibility
-      physicalAddress {
-        description
-        street
-        locality
-        postalCode
-        region
-        country
-        geom
-        type
-        id
-        originId
-      }
-      avatar {
-        url
-      }
-      banner {
-        url
-      }
-      organizedEvents {
-        elements {
-          id
-          uuid
-          title
-          beginsOn
-        }
-        total
-      }
-      discussions {
-        total
-        elements {
-          ...DiscussionBasicFields
-        }
-      }
-      posts {
-        total
-        elements {
-          ...PostBasicFields
-        }
-      }
-      members {
-        elements {
-          role
-          actor {
-            id
-            name
-            domain
-            preferredUsername
-            avatar {
-              url
-            }
-          }
-          insertedAt
-        }
-        total
-      }
-      resources(page: 1, limit: 3) {
-        elements {
-          id
-          title
-          resourceUrl
-          summary
-          updatedAt
-          type
-          path
-          metadata {
-            ...ResourceMetadataBasicFields
-          }
-        }
-        total
-      }
-      todoLists {
-        elements {
-          id
-          title
-          todos {
-            elements {
-              id
-              title
-              status
-              dueDate
-              assignedTo {
-                id
-                preferredUsername
-              }
-            }
-            total
-          }
-        }
-        total
-      }
+      ...GroupFullFields
     }
   }
+  ${GROUP_FIELDS_FRAGMENTS}
+  ${DISCUSSION_BASIC_FIELDS_FRAGMENT}
+  ${POST_BASIC_FIELDS}
+  ${RESOURCE_METADATA_BASIC_FIELDS_FRAGMENT}
+`;
+
+export const GET_GROUP = gql`
+  query($id: ID!) {
+    getGroup(id: $id) {
+      ...GroupFullFields
+    }
+  }
+  ${GROUP_FIELDS_FRAGMENTS}
   ${DISCUSSION_BASIC_FIELDS_FRAGMENT}
   ${POST_BASIC_FIELDS}
   ${RESOURCE_METADATA_BASIC_FIELDS_FRAGMENT}
@@ -162,6 +197,7 @@ export const CREATE_GROUP = gql`
       id
       preferredUsername
       name
+      domain
       summary
       avatar {
         url
@@ -206,6 +242,14 @@ export const UPDATE_GROUP = gql`
   }
 `;
 
+export const DELETE_GROUP = gql`
+  mutation DeleteGroup($groupId: ID!) {
+    deleteGroup(groupId: $groupId) {
+      id
+    }
+  }
+`;
+
 export const LEAVE_GROUP = gql`
   mutation LeaveGroup($groupId: ID!) {
     leaveGroup(groupId: $groupId) {
@@ -213,3 +257,11 @@ export const LEAVE_GROUP = gql`
     }
   }
 `;
+
+export const REFRESH_PROFILE = gql`
+  mutation RefreshProfile($actorId: ID!) {
+    refreshProfile(id: $actorId) {
+      id
+    }
+  }
+`;
diff --git a/js/src/i18n/en_US.json b/js/src/i18n/en_US.json
index 9da515b2e..17aa2cb95 100644
--- a/js/src/i18n/en_US.json
+++ b/js/src/i18n/en_US.json
@@ -160,7 +160,6 @@
   "Go": "Go",
   "Going as {name}": "Going as {name}",
   "Group List": "Group List",
-  "Group full name": "Group full name",
   "Group name": "Group name",
   "Group {displayName} created": "Group {displayName} created",
   "Groups": "Groups",
@@ -766,5 +765,19 @@
   "Edited {ago}": "Edited {ago}",
   "[This comment has been deleted by it's author]": "[This comment has been deleted by it's author]",
   "Promote": "Promote",
-  "Demote": "Demote"
+  "Demote": "Demote",
+  "{number} members": "{number} members",
+  "{number} posts": "No posts|One post|{number} posts",
+  "Publication date": "Publication date",
+  "Refresh profile": "Refresh profile",
+  "Suspend group": "Suspend group",
+  "Are you sure you want to <b>suspend</b> this group? As this group originates from instance {instance}, this will only remove local members and delete the local data, as well as rejecting all the future data.": "Are you sure you want to <b>suspend</b> this group? As this group originates from instance {instance}, this will only remove local members and delete the local data, as well as rejecting all the future data.",
+  "Are you sure you want to <b>suspend</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>.": "Are you sure you want to <b>suspend</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>.",
+  "Delete group": "Delete group",
+  "Are you sure you want to <b>completely delete</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>.": "Are you sure you want to <b>completely delete</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>.",
+  "Group display name": "Group display name",
+  "Federated Group Name": "Federated Group Name",
+  "This is like your federated username (<code>{username}</code>) for groups. It will allow you to be found on the federation, and is guaranteed to be unique.": "This is like your federated username (<code>{username}</code>) for groups. It will allow you to be found on the federation, and is guaranteed to be unique.",
+  "Banner": "Banner",
+  "A group with this name already exists": "A group with this name already exists"
 }
diff --git a/js/src/i18n/fr_FR.json b/js/src/i18n/fr_FR.json
index 9c2a07a26..c6ebc90fc 100644
--- a/js/src/i18n/fr_FR.json
+++ b/js/src/i18n/fr_FR.json
@@ -243,11 +243,10 @@
   "Group List": "Liste de groupes",
   "Group Members": "Membres du groupe",
   "Group address": "Adresse du groupe",
-  "Group full name": "Nom complet du groupe",
   "Group name": "Nom du groupe",
   "Group settings": "Paramètres du groupe",
   "Group short description": "Description courte du groupe",
-  "Group visibility": "Visibility du groupe",
+  "Group visibility": "Visibilité du groupe",
   "Group {displayName} created": "Groupe {displayName} créé",
   "Groups": "Groupes",
   "Headline picture": "Image à la une",
@@ -301,7 +300,7 @@
   "Language": "Langue",
   "Last published event": "Dernier évènement publié",
   "Last week": "La semaine dernière",
-  "Latest posts": "Derniers messages publics",
+  "Latest posts": "Derniers billets",
   "Learn more": "En apprendre plus",
   "Learn more about Mobilizon": "En apprendre plus à propos de Mobilizon",
   "Leave event": "Annuler ma participation à l'évènement",
@@ -767,5 +766,19 @@
   "Edited {ago}": "Édité {ago}",
   "[This comment has been deleted by it's author]": "[Ce commentaire a été supprimé par son auteur]",
   "Promote": "Promouvoir",
-  "Demote": "Rétrograder"
+  "Demote": "Rétrograder",
+  "{number} members": "{number} membres",
+  "{number} posts": "Aucun billet|Un billet|{number} billets",
+  "Publication date": "Date de publication",
+  "Refresh profile": "Rafraîchir le profil",
+  "Suspend group": "Suspendre le groupe",
+  "Are you sure you want to <b>suspend</b> this group? As this group originates from instance {instance}, this will only remove local members and delete the local data, as well as rejecting all the future data.": "Êtes-vous certain·e de vouloir <b>suspendre</b> ce groupe ? Comme ce groupe provient de l'instance {instance}, cela supprimera seulement les membres locaux et supprimera les données locales, et rejettera également toutes les données futures.",
+  "Are you sure you want to <b>suspend</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>.": "Êtes-vous certain·e de vouloir <b>suspendre</b> ce groupe ? Tous les membres - y compris celleux sur d'autres instances - seront notifié·es et supprimé·es du groupe, et <b>toutes les données associées au groupe (événements, billets, discussions, todos…) seront irrémédiablement détruites</b>.",
+  "Delete group": "Supprimer le groupe",
+  "Are you sure you want to <b>completely delete</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>.": "Êtes-vous certain·e de vouloir <b>complètement supprimer</b> ce groupe ? Tous les membres - y compris celleux sur d'autres instances - seront notifié·es et supprimé·es du groupe, et <b>toutes les données associées au groupe (événements, billets, discussions, todos…) seront irrémédiablement détruites</b>.",
+  "Group display name": "Nom d'affichage du groupe",
+  "Federated Group Name": "Nom fédéré du groupe",
+  "This is like your federated username (<code>{username}</code>) for groups. It will allow you to be found on the federation, and is guaranteed to be unique.": "C'est comme votre addresse fédérée (<code>{username}</code>) pour les groupes. Cela vous permettra d'être trouvable sur la fédération, et est garanti d'être unique.",
+  "Banner": "Bannière",
+  "A group with this name already exists": "Un groupe avec ce nom existe déjà"
 }
diff --git a/js/src/mixins/identityEdition.ts b/js/src/mixins/identityEdition.ts
index 1d385085e..e3ecd5f04 100644
--- a/js/src/mixins/identityEdition.ts
+++ b/js/src/mixins/identityEdition.ts
@@ -1,7 +1,8 @@
 import { Component, Mixins, Vue } from "vue-property-decorator";
 import { Person } from "@/types/actor";
 
-@Component({})
+// TODO: Refactor into js/src/utils/username.ts
+@Component
 export default class IdentityEditionMixin extends Mixins(Vue) {
   identity: Person = new Person();
 
diff --git a/js/src/router/settings.ts b/js/src/router/settings.ts
index 2885bfffc..b1cf752de 100644
--- a/js/src/router/settings.ts
+++ b/js/src/router/settings.ts
@@ -16,6 +16,8 @@ import Users from "../views/Admin/Users.vue";
 import Profiles from "../views/Admin/Profiles.vue";
 import AdminProfile from "../views/Admin/AdminProfile.vue";
 import AdminUserProfile from "../views/Admin/AdminUserProfile.vue";
+import GroupProfiles from "../views/Admin/GroupProfiles.vue";
+import AdminGroupProfile from "../views/Admin/AdminGroupProfile.vue";
 
 export enum SettingsRouteName {
   SETTINGS = "SETTINGS",
@@ -33,6 +35,8 @@ export enum SettingsRouteName {
   PROFILES = "PROFILES",
   ADMIN_PROFILE = "ADMIN_PROFILE",
   ADMIN_USER_PROFILE = "ADMIN_USER_PROFILE",
+  ADMIN_GROUPS = "ADMIN_GROUPS",
+  ADMIN_GROUP_PROFILE = "ADMIN_GROUP_PROFILE",
   MODERATION = "MODERATION",
   REPORTS = "Reports",
   REPORT = "Report",
@@ -123,6 +127,20 @@ export const settingsRoutes: RouteConfig[] = [
         props: true,
         meta: { requiredAuth: true },
       },
+      {
+        path: "admin/groups",
+        name: SettingsRouteName.ADMIN_GROUPS,
+        component: GroupProfiles,
+        props: true,
+        meta: { requiredAuth: true },
+      },
+      {
+        path: "admin/groups/:id",
+        name: SettingsRouteName.ADMIN_GROUP_PROFILE,
+        component: AdminGroupProfile,
+        props: true,
+        meta: { requiredAuth: true },
+      },
       {
         path: "admin/relays",
         name: SettingsRouteName.RELAYS,
diff --git a/js/src/types/actor/actor.model.ts b/js/src/types/actor/actor.model.ts
index e1ceeb183..c4a69c203 100644
--- a/js/src/types/actor/actor.model.ts
+++ b/js/src/types/actor/actor.model.ts
@@ -60,9 +60,11 @@ export class Actor implements IActor {
   }
 }
 
-export function usernameWithDomain(actor: IActor): string {
+export function usernameWithDomain(actor: IActor, force = false): string {
   if (actor.domain) {
     return `${actor.preferredUsername}@${actor.domain}`;
+  } else if (force) {
+    return `${actor.preferredUsername}@${window.location.hostname}`;
   }
   return actor.preferredUsername;
 }
diff --git a/js/src/types/comment.model.ts b/js/src/types/comment.model.ts
index 6bac3624f..5f45f4bd7 100644
--- a/js/src/types/comment.model.ts
+++ b/js/src/types/comment.model.ts
@@ -16,6 +16,7 @@ export interface IComment {
   deletedAt?: Date | string;
   totalReplies: number;
   insertedAt?: Date | string;
+  publishedAt?: Date | string;
 }
 
 export class CommentModel implements IComment {
diff --git a/js/src/types/discussions.ts b/js/src/types/discussions.ts
index 202691610..caf66b133 100644
--- a/js/src/types/discussions.ts
+++ b/js/src/types/discussions.ts
@@ -10,6 +10,8 @@ export interface IDiscussion {
   actor?: IActor;
   lastComment?: IComment;
   comments: Paginate<IComment>;
+  updatedAt: string;
+  insertedAt: string;
 }
 
 export class Discussion implements IDiscussion {
@@ -27,6 +29,10 @@ export class Discussion implements IDiscussion {
 
   lastComment?: IComment = undefined;
 
+  insertedAt: string = "";
+
+  updatedAt: string = "";
+
   constructor(hash?: IDiscussion) {
     if (!hash) return;
 
@@ -40,5 +46,7 @@ export class Discussion implements IDiscussion {
     this.creator = hash.creator;
     this.actor = hash.actor;
     this.lastComment = hash.lastComment;
+    this.insertedAt = hash.insertedAt;
+    this.updatedAt = hash.updatedAt;
   }
 }
diff --git a/js/src/utils/username.ts b/js/src/utils/username.ts
new file mode 100644
index 000000000..c565f7890
--- /dev/null
+++ b/js/src/utils/username.ts
@@ -0,0 +1,29 @@
+import { IActor } from "@/types/actor";
+
+function autoUpdateUsername(actor: IActor, newDisplayName: string | null): IActor {
+  const oldUsername = convertToUsername(actor.name);
+
+  if (actor.preferredUsername === oldUsername) {
+    actor.preferredUsername = convertToUsername(newDisplayName);
+  }
+
+  return actor;
+}
+
+function convertToUsername(value: string | null): string {
+  if (!value) return "";
+
+  // https://stackoverflow.com/a/37511463
+  return value
+    .toLocaleLowerCase()
+    .normalize("NFD")
+    .replace(/[\u0300-\u036f]/g, "")
+    .replace(/ /g, "_")
+    .replace(/[^a-z0-9_]/g, "");
+}
+
+function validateUsername(actor: IActor): boolean {
+  return actor.preferredUsername === convertToUsername(actor.preferredUsername);
+}
+
+export { autoUpdateUsername, convertToUsername, validateUsername };
diff --git a/js/src/views/Account/Register.vue b/js/src/views/Account/Register.vue
index f14775c09..3ecebad5c 100644
--- a/js/src/views/Account/Register.vue
+++ b/js/src/views/Account/Register.vue
@@ -50,11 +50,11 @@
         </form>
 
         <div v-if="validationSent && !userAlreadyActivated">
-          <b-message title="Success" type="is-success" closable="false">
+          <b-message type="is-success" closable="false">
             <h2 class="title">
               {{
                 $t("Your account is nearly ready, {username}", {
-                  username: identity.preferredUsername,
+                  username: identity.name || identity.preferredUsername,
                 })
               }}
             </h2>
diff --git a/js/src/views/Account/children/EditIdentity.vue b/js/src/views/Account/children/EditIdentity.vue
index d903cad1a..e5def75b4 100644
--- a/js/src/views/Account/children/EditIdentity.vue
+++ b/js/src/views/Account/children/EditIdentity.vue
@@ -150,6 +150,7 @@ import identityEditionMixin from "../../../mixins/identityEdition";
     },
     identity: {
       query: FETCH_PERSON,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           username: this.identityName,
diff --git a/js/src/views/Admin/AdminGroupProfile.vue b/js/src/views/Admin/AdminGroupProfile.vue
new file mode 100644
index 000000000..3c7b36ffa
--- /dev/null
+++ b/js/src/views/Admin/AdminGroupProfile.vue
@@ -0,0 +1,436 @@
+<template>
+  <div v-if="group" class="section">
+    <nav class="breadcrumb" aria-label="breadcrumbs">
+      <ul>
+        <li>
+          <router-link :to="{ name: RouteName.ADMIN }">{{ $t("Admin") }}</router-link>
+        </li>
+        <li>
+          <router-link
+            :to="{
+              name: RouteName.ADMIN_GROUPS,
+            }"
+            >{{ $t("Groups") }}</router-link
+          >
+        </li>
+        <li class="is-active">
+          <router-link
+            :to="{
+              name: RouteName.PROFILES,
+              params: { id: group.id },
+            }"
+            >{{ group.name || group.preferredUsername }}</router-link
+          >
+        </li>
+      </ul>
+    </nav>
+    <div class="actor-card">
+      <router-link
+        :to="{ name: RouteName.GROUP, params: { preferredUsername: usernameWithDomain(group) } }"
+      >
+        <actor-card :actor="group" :full="true" :popover="false" :limit="false" />
+      </router-link>
+    </div>
+    <table v-if="metadata.length > 0" class="table is-fullwidth">
+      <tbody>
+        <tr v-for="{ key, value, link } in metadata" :key="key">
+          <td>{{ key }}</td>
+          <td v-if="link">
+            <router-link :to="link">
+              {{ value }}
+            </router-link>
+          </td>
+          <td v-else>{{ value }}</td>
+        </tr>
+      </tbody>
+    </table>
+    <div class="buttons">
+      <b-button @click="confirmSuspendProfile" v-if="!group.suspended" type="is-primary">{{
+        $t("Suspend")
+      }}</b-button>
+      <b-button @click="unsuspendProfile" v-if="group.suspended" type="is-primary">{{
+        $t("Unsuspend")
+      }}</b-button>
+      <b-button @click="refreshProfile" v-if="group.domain" type="is-primary" outlined>{{
+        $t("Refresh profile")
+      }}</b-button>
+    </div>
+    <section>
+      <h2 class="subtitle">
+        {{
+          $tc("{number} members", group.members.total, {
+            number: group.members.total,
+          })
+        }}
+      </h2>
+      <b-table
+        :data="group.members.elements"
+        :loading="$apollo.queries.group.loading"
+        paginated
+        backend-pagination
+        :total="group.members.total"
+        :per-page="EVENTS_PER_PAGE"
+        @page-change="onMembersPageChange"
+      >
+        <b-table-column field="actor.preferredUsername" :label="$t('Member')" v-slot="props">
+          <article class="media">
+            <figure class="media-left image is-48x48" v-if="props.row.actor.avatar">
+              <img class="is-rounded" :src="props.row.actor.avatar.url" alt="" />
+            </figure>
+            <b-icon class="media-left" v-else size="is-large" icon="account-circle" />
+            <div class="media-content">
+              <div class="content">
+                <span v-if="props.row.actor.name">{{ props.row.actor.name }}</span
+                ><br />
+                <span class="is-size-7 has-text-grey"
+                  >@{{ usernameWithDomain(props.row.actor) }}</span
+                >
+              </div>
+            </div>
+          </article>
+        </b-table-column>
+        <b-table-column field="role" :label="$t('Role')" v-slot="props">
+          <b-tag type="is-primary" v-if="props.row.role === MemberRole.ADMINISTRATOR">
+            {{ $t("Administrator") }}
+          </b-tag>
+          <b-tag type="is-primary" v-else-if="props.row.role === MemberRole.MODERATOR">
+            {{ $t("Moderator") }}
+          </b-tag>
+          <b-tag v-else-if="props.row.role === MemberRole.MEMBER">
+            {{ $t("Member") }}
+          </b-tag>
+          <b-tag type="is-warning" v-else-if="props.row.role === MemberRole.NOT_APPROVED">
+            {{ $t("Not approved") }}
+          </b-tag>
+          <b-tag type="is-danger" v-else-if="props.row.role === MemberRole.REJECTED">
+            {{ $t("Rejected") }}
+          </b-tag>
+          <b-tag type="is-danger" v-else-if="props.row.role === MemberRole.INVITED">
+            {{ $t("Invited") }}
+          </b-tag>
+        </b-table-column>
+        <b-table-column field="insertedAt" :label="$t('Date')" v-slot="props">
+          <span class="has-text-centered">
+            {{ props.row.insertedAt | formatDateString }}<br />{{
+              props.row.insertedAt | formatTimeString
+            }}
+          </span>
+        </b-table-column>
+        <template slot="empty">
+          <section class="section">
+            <div class="content has-text-grey has-text-centered">
+              <p>{{ $t("Nothing to see here") }}</p>
+            </div>
+          </section>
+        </template>
+      </b-table>
+    </section>
+    <section>
+      <h2 class="subtitle">
+        {{
+          $tc("{number} organized events", group.organizedEvents.total, {
+            number: group.organizedEvents.total,
+          })
+        }}
+      </h2>
+      <b-table
+        :data="group.organizedEvents.elements"
+        :loading="$apollo.queries.group.loading"
+        paginated
+        backend-pagination
+        :total="group.organizedEvents.total"
+        :per-page="EVENTS_PER_PAGE"
+        @page-change="onOrganizedEventsPageChange"
+      >
+        <b-table-column field="title" :label="$t('Title')" v-slot="props">
+          <router-link :to="{ name: RouteName.EVENT, params: { uuid: props.row.uuid } }">
+            {{ props.row.title }}
+          </router-link>
+        </b-table-column>
+        <b-table-column field="beginsOn" :label="$t('Begins on')" v-slot="props">
+          {{ props.row.beginsOn | formatDateTimeString }}
+        </b-table-column>
+        <template slot="empty">
+          <section class="section">
+            <div class="content has-text-grey has-text-centered">
+              <p>{{ $t("Nothing to see here") }}</p>
+            </div>
+          </section>
+        </template>
+      </b-table>
+    </section>
+    <section>
+      <h2 class="subtitle">
+        {{
+          $tc("{number} posts", group.posts.total, {
+            number: group.posts.total,
+          })
+        }}
+      </h2>
+      <b-table
+        :data="group.posts.elements"
+        :loading="$apollo.queries.group.loading"
+        paginated
+        backend-pagination
+        :total="group.posts.total"
+        :per-page="EVENTS_PER_PAGE"
+        @page-change="onPostsPageChange"
+      >
+        <b-table-column field="title" :label="$t('Title')" v-slot="props">
+          <router-link :to="{ name: RouteName.POST, params: { slug: props.row.slug } }">
+            {{ props.row.title }}
+          </router-link>
+        </b-table-column>
+        <b-table-column field="publishAt" :label="$t('Publication date')" v-slot="props">
+          {{ props.row.publishAt | formatDateTimeString }}
+        </b-table-column>
+        <template slot="empty">
+          <section class="section">
+            <div class="content has-text-grey has-text-centered">
+              <p>{{ $t("Nothing to see here") }}</p>
+            </div>
+          </section>
+        </template>
+      </b-table>
+    </section>
+  </div>
+</template>
+<script lang="ts">
+import { Component, Vue, Prop } from "vue-property-decorator";
+import { SUSPEND_PROFILE, UNSUSPEND_PROFILE } from "../../graphql/actor";
+import { IGroup, MemberRole } from "../../types/actor";
+import { usernameWithDomain, IActor } from "../../types/actor/actor.model";
+import RouteName from "../../router/name";
+import { IEvent } from "../../types/event.model";
+import ActorCard from "../../components/Account/ActorCard.vue";
+import { GET_GROUP, REFRESH_PROFILE } from "@/graphql/group";
+
+const EVENTS_PER_PAGE = 10;
+
+@Component({
+  apollo: {
+    group: {
+      query: GET_GROUP,
+      fetchPolicy: "cache-and-network",
+      variables() {
+        return {
+          id: this.id,
+          organizedEventsPage: 1,
+          organizedEventsLimit: EVENTS_PER_PAGE,
+        };
+      },
+      skip() {
+        return !this.id;
+      },
+      update: (data) => data.getGroup,
+    },
+  },
+  components: {
+    ActorCard,
+  },
+})
+export default class AdminGroupProfile extends Vue {
+  @Prop({ required: true }) id!: string;
+
+  group!: IGroup;
+
+  usernameWithDomain = usernameWithDomain;
+
+  RouteName = RouteName;
+
+  EVENTS_PER_PAGE = EVENTS_PER_PAGE;
+
+  organizedEventsPage = 1;
+
+  membersPage = 1;
+
+  postsPage = 1;
+
+  MemberRole = MemberRole;
+
+  get metadata(): Array<object> {
+    if (!this.group) return [];
+    const res: object[] = [
+      {
+        key: this.$t("Status") as string,
+        value: this.group.suspended ? this.$t("Suspended") : this.$t("Active"),
+      },
+      {
+        key: this.$t("Domain") as string,
+        value: this.group.domain ? this.group.domain : this.$t("Local"),
+      },
+    ];
+    return res;
+  }
+
+  confirmSuspendProfile() {
+    const message = (this.group.domain
+      ? this.$t(
+          "Are you sure you want to <b>suspend</b> this group? As this group originates from instance {instance}, this will only remove local members and delete the local data, as well as rejecting all the future data.",
+          { instance: this.group.domain }
+        )
+      : this.$t(
+          "Are you sure you want to <b>suspend</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>."
+        )) as string;
+
+    this.$buefy.dialog.confirm({
+      title: this.$t("Suspend group") as string,
+      message,
+      confirmText: this.$t("Suspend group") as string,
+      cancelText: this.$t("Cancel") as string,
+      type: "is-danger",
+      hasIcon: true,
+      onConfirm: () => this.suspendProfile(),
+    });
+  }
+
+  async suspendProfile() {
+    this.$apollo.mutate<{ suspendProfile: { id: string } }>({
+      mutation: SUSPEND_PROFILE,
+      variables: {
+        id: this.id,
+      },
+      update: (store, { data }) => {
+        if (data == null) return;
+        const profileId = this.id;
+
+        const profileData = store.readQuery<{ getGroup: IGroup }>({
+          query: GET_GROUP,
+          variables: {
+            id: profileId,
+          },
+        });
+
+        if (!profileData) return;
+        const { getGroup: group } = profileData;
+        group.suspended = true;
+        group.avatar = null;
+        group.name = "";
+        group.summary = "";
+        store.writeQuery({
+          query: GET_GROUP,
+          variables: {
+            id: profileId,
+          },
+          data: { getGroup: group },
+        });
+      },
+    });
+  }
+
+  async unsuspendProfile() {
+    const profileID = this.id;
+    this.$apollo.mutate<{ unsuspendProfile: { id: string } }>({
+      mutation: UNSUSPEND_PROFILE,
+      variables: {
+        id: this.id,
+      },
+      refetchQueries: [
+        {
+          query: GET_GROUP,
+          variables: {
+            id: profileID,
+          },
+        },
+      ],
+    });
+  }
+
+  async refreshProfile() {
+    this.$apollo.mutate<{ refreshProfile: IActor }>({
+      mutation: REFRESH_PROFILE,
+      variables: {
+        actorId: this.id,
+      },
+    });
+  }
+
+  async onOrganizedEventsPageChange(page: number) {
+    this.organizedEventsPage = page;
+    await this.$apollo.queries.group.fetchMore({
+      variables: {
+        actorId: this.id,
+        organizedEventsPage: this.organizedEventsPage,
+        organizedEventsLimit: EVENTS_PER_PAGE,
+      },
+      updateQuery: (previousResult, { fetchMoreResult }) => {
+        if (!fetchMoreResult) return previousResult;
+        const newOrganizedEvents = fetchMoreResult.group.organizedEvents.elements;
+        return {
+          group: {
+            ...previousResult.group,
+            organizedEvents: {
+              __typename: previousResult.group.organizedEvents.__typename,
+              total: previousResult.group.organizedEvents.total,
+              elements: [...previousResult.group.organizedEvents.elements, ...newOrganizedEvents],
+            },
+          },
+        };
+      },
+    });
+  }
+
+  async onMembersPageChange(page: number) {
+    this.membersPage = page;
+    await this.$apollo.queries.group.fetchMore({
+      variables: {
+        actorId: this.id,
+        memberPage: this.membersPage,
+        memberLimit: EVENTS_PER_PAGE,
+      },
+      updateQuery: (previousResult, { fetchMoreResult }) => {
+        if (!fetchMoreResult) return previousResult;
+        const newMembers = fetchMoreResult.group.members.elements;
+        return {
+          group: {
+            ...previousResult.group,
+            members: {
+              __typename: previousResult.group.members.__typename,
+              total: previousResult.group.members.total,
+              elements: [...previousResult.group.members.elements, ...newMembers],
+            },
+          },
+        };
+      },
+    });
+  }
+
+  async onPostsPageChange(page: number) {
+    this.postsPage = page;
+    await this.$apollo.queries.group.fetchMore({
+      variables: {
+        actorId: this.id,
+        postsPage: this.postsPage,
+        postLimit: EVENTS_PER_PAGE,
+      },
+      updateQuery: (previousResult, { fetchMoreResult }) => {
+        if (!fetchMoreResult) return previousResult;
+        const newPosts = fetchMoreResult.group.posts.elements;
+        return {
+          group: {
+            ...previousResult.group,
+            posts: {
+              __typename: previousResult.group.posts.__typename,
+              total: previousResult.group.posts.total,
+              elements: [...previousResult.group.posts.elements, ...newPosts],
+            },
+          },
+        };
+      },
+    });
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+table,
+section {
+  margin: 2rem 0;
+}
+
+.actor-card {
+  background: #fff;
+  padding: 1.5rem;
+  border-radius: 10px;
+}
+</style>
diff --git a/js/src/views/Admin/AdminProfile.vue b/js/src/views/Admin/AdminProfile.vue
index 41be242c1..4f04b25fe 100644
--- a/js/src/views/Admin/AdminProfile.vue
+++ b/js/src/views/Admin/AdminProfile.vue
@@ -139,6 +139,7 @@ const EVENTS_PER_PAGE = 10;
   apollo: {
     person: {
       query: GET_PERSON,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           actorId: this.id,
diff --git a/js/src/views/Admin/AdminUserProfile.vue b/js/src/views/Admin/AdminUserProfile.vue
index 179af473d..846751cb1 100644
--- a/js/src/views/Admin/AdminUserProfile.vue
+++ b/js/src/views/Admin/AdminUserProfile.vue
@@ -69,6 +69,7 @@ import { IPerson } from "../../types/actor";
   apollo: {
     user: {
       query: GET_USER,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           id: this.id,
diff --git a/js/src/views/Admin/Dashboard.vue b/js/src/views/Admin/Dashboard.vue
index 2d9a4cd2d..18b55838b 100644
--- a/js/src/views/Admin/Dashboard.vue
+++ b/js/src/views/Admin/Dashboard.vue
@@ -71,6 +71,7 @@ import RouteName from "../../router/name";
   apollo: {
     dashboard: {
       query: DASHBOARD,
+      fetchPolicy: "cache-and-network",
     },
   },
   metaInfo() {
diff --git a/js/src/views/Admin/GroupProfiles.vue b/js/src/views/Admin/GroupProfiles.vue
new file mode 100644
index 000000000..da2872422
--- /dev/null
+++ b/js/src/views/Admin/GroupProfiles.vue
@@ -0,0 +1,168 @@
+<template>
+  <div>
+    <nav class="breadcrumb" aria-label="breadcrumbs">
+      <ul>
+        <li>
+          <router-link :to="{ name: RouteName.MODERATION }">{{ $t("Moderation") }}</router-link>
+        </li>
+        <li class="is-active">
+          <router-link :to="{ name: RouteName.PROFILES }">{{ $t("Groups") }}</router-link>
+        </li>
+      </ul>
+    </nav>
+    <div v-if="groups">
+      <b-switch v-model="local">{{ $t("Local") }}</b-switch>
+      <b-switch v-model="suspended">{{ $t("Suspended") }}</b-switch>
+      <b-table
+        :data="groups.elements"
+        :loading="$apollo.queries.groups.loading"
+        paginated
+        backend-pagination
+        backend-filtering
+        :total="groups.total"
+        :per-page="PROFILES_PER_PAGE"
+        @page-change="onPageChange"
+        @filters-change="onFiltersChange"
+      >
+        <b-table-column field="preferredUsername" :label="$t('Username')" searchable>
+          <template slot="searchable" slot-scope="props">
+            <b-input
+              v-model="props.filters.preferredUsername"
+              placeholder="Search..."
+              icon="magnify"
+              size="is-small"
+            />
+          </template>
+          <template v-slot:default="props">
+            <router-link
+              class="profile"
+              :to="{ name: RouteName.ADMIN_GROUP_PROFILE, params: { id: props.row.id } }"
+            >
+              <article class="media">
+                <figure class="media-left" v-if="props.row.avatar">
+                  <p class="image is-48x48">
+                    <img :src="props.row.avatar.url" />
+                  </p>
+                </figure>
+                <div class="media-content">
+                  <div class="content">
+                    <strong v-if="props.row.name">{{ props.row.name }}</strong
+                    ><br v-if="props.row.name" />
+                    <small>@{{ props.row.preferredUsername }}</small>
+                  </div>
+                </div>
+              </article>
+            </router-link>
+          </template>
+        </b-table-column>
+
+        <b-table-column field="domain" :label="$t('Domain')" searchable>
+          <template slot="searchable" slot-scope="props">
+            <b-input
+              v-model="props.filters.domain"
+              placeholder="Search..."
+              icon="magnify"
+              size="is-small"
+            />
+          </template>
+          <template v-slot:default="props">
+            {{ props.row.domain }}
+          </template>
+        </b-table-column>
+        <template slot="empty">
+          <section class="section">
+            <div class="content has-text-grey has-text-centered">
+              <p>{{ $t("No profile matches the filters") }}</p>
+            </div>
+          </section>
+        </template>
+      </b-table>
+    </div>
+  </div>
+</template>
+<script lang="ts">
+import { Component, Vue, Watch } from "vue-property-decorator";
+import { LIST_PROFILES } from "../../graphql/actor";
+import RouteName from "../../router/name";
+import { LIST_GROUPS } from "@/graphql/group";
+
+const PROFILES_PER_PAGE = 10;
+
+@Component({
+  apollo: {
+    groups: {
+      query: LIST_GROUPS,
+      fetchPolicy: "cache-and-network",
+      variables() {
+        return {
+          preferredUsername: this.preferredUsername,
+          name: this.name,
+          domain: this.domain,
+          local: this.local,
+          suspended: this.suspended,
+          page: 1,
+          limit: PROFILES_PER_PAGE,
+        };
+      },
+    },
+  },
+})
+export default class GroupProfiles extends Vue {
+  page = 1;
+
+  preferredUsername = "";
+
+  name = "";
+
+  domain = "";
+
+  local = true;
+
+  suspended = false;
+
+  PROFILES_PER_PAGE = PROFILES_PER_PAGE;
+
+  RouteName = RouteName;
+
+  async onPageChange(page: number) {
+    this.page = page;
+    await this.$apollo.queries.groups.fetchMore({
+      variables: {
+        preferredUsername: this.preferredUsername,
+        name: this.name,
+        domain: this.domain,
+        local: this.local,
+        suspended: this.suspended,
+        page: this.page,
+        limit: PROFILES_PER_PAGE,
+      },
+      updateQuery: (previousResult, { fetchMoreResult }) => {
+        if (!fetchMoreResult) return previousResult;
+        const newProfiles = fetchMoreResult.groups.elements;
+        return {
+          groups: {
+            __typename: previousResult.groups.__typename,
+            total: previousResult.groups.total,
+            elements: [...previousResult.groups.elements, ...newProfiles],
+          },
+        };
+      },
+    });
+  }
+
+  onFiltersChange({ preferredUsername, domain }: { preferredUsername: string; domain: string }) {
+    this.preferredUsername = preferredUsername;
+    this.domain = domain;
+  }
+
+  @Watch("domain")
+  domainNotLocal() {
+    this.local = this.domain === "";
+  }
+}
+</script>
+<style lang="scss" scoped>
+a.profile {
+  text-decoration: none;
+}
+</style>
diff --git a/js/src/views/Admin/Profiles.vue b/js/src/views/Admin/Profiles.vue
index 47eb44985..eb96a0536 100644
--- a/js/src/views/Admin/Profiles.vue
+++ b/js/src/views/Admin/Profiles.vue
@@ -91,6 +91,7 @@ const PROFILES_PER_PAGE = 10;
   apollo: {
     persons: {
       query: LIST_PROFILES,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           preferredUsername: this.preferredUsername,
diff --git a/js/src/views/Admin/Users.vue b/js/src/views/Admin/Users.vue
index 6d1d06381..89a51af90 100644
--- a/js/src/views/Admin/Users.vue
+++ b/js/src/views/Admin/Users.vue
@@ -103,6 +103,7 @@ const USERS_PER_PAGE = 10;
   apollo: {
     users: {
       query: LIST_USERS,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           email: this.email,
diff --git a/js/src/views/Discussions/Discussion.vue b/js/src/views/Discussions/Discussion.vue
index b5ddf54eb..68baaa109 100644
--- a/js/src/views/Discussions/Discussion.vue
+++ b/js/src/views/Discussions/Discussion.vue
@@ -120,6 +120,7 @@ import { DELETE_COMMENT, UPDATE_COMMENT } from "@/graphql/comment";
   apollo: {
     discussion: {
       query: GET_DISCUSSION,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           slug: this.slug,
diff --git a/js/src/views/Event/Event.vue b/js/src/views/Event/Event.vue
index f42a7190e..6c09af669 100644
--- a/js/src/views/Event/Event.vue
+++ b/js/src/views/Event/Event.vue
@@ -578,6 +578,7 @@ import PopoverActorCard from "../../components/Account/PopoverActorCard.vue";
   apollo: {
     event: {
       query: FETCH_EVENT,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           uuid: this.uuid,
@@ -592,6 +593,7 @@ import PopoverActorCard from "../../components/Account/PopoverActorCard.vue";
     },
     participations: {
       query: EVENT_PERSON_PARTICIPATION,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           eventId: this.event.id,
diff --git a/js/src/views/Group/Create.vue b/js/src/views/Group/Create.vue
index a2b7e05c4..f6d1a0e27 100644
--- a/js/src/views/Group/Create.vue
+++ b/js/src/views/Group/Create.vue
@@ -2,41 +2,64 @@
   <section class="section container">
     <h1>{{ $t("Create a new group") }}</h1>
 
-    <div>
-      <b-field :label="$t('Group name')">
-        <b-input aria-required="true" required v-model="group.preferredUsername" />
-      </b-field>
+    <b-message type="is-danger" v-for="(value, index) in errors" :key="index">
+      {{ value }}
+    </b-message>
 
-      <b-field :label="$t('Group full name')">
+    <form @submit.prevent="createGroup">
+      <b-field :label="$t('Group display name')">
         <b-input aria-required="true" required v-model="group.name" />
       </b-field>
 
+      <div class="field">
+        <label class="label">{{ $t("Federated Group Name") }}</label>
+        <div class="field-body">
+          <b-field>
+            <b-input aria-required="true" required expanded v-model="group.preferredUsername" />
+            <p class="control">
+              <span class="button is-static">@{{ host }}</span>
+            </p>
+          </b-field>
+        </div>
+        <p
+          v-html="
+            $t(
+              'This is like your federated username (<code>{username}</code>) for groups. It will allow you to be found on the federation, and is guaranteed to be unique.',
+              { username: usernameWithDomain(currentActor, true) }
+            )
+          "
+        />
+      </div>
+
       <b-field :label="$t('Description')">
-        <b-input aria-required="true" required v-model="group.summary" type="textarea" />
+        <b-input v-model="group.summary" type="textarea" />
       </b-field>
 
       <div>
-        Avatar
-        <picture-upload v-model="avatarFile" />
+        {{ $t("Avatar") }}
+        <picture-upload :textFallback="$t('Avatar')" v-model="avatarFile" />
       </div>
 
       <div>
-        Banner
-        <picture-upload v-model="avatarFile" />
+        {{ $t("Banner") }}
+        <picture-upload :textFallback="$t('Banner')" v-model="bannerFile" />
       </div>
 
-      <button class="button is-primary" @click="createGroup()">{{ $t("Create my group") }}</button>
-    </div>
+      <button class="button is-primary" native-type="submit">{{ $t("Create my group") }}</button>
+    </form>
   </section>
 </template>
 
 <script lang="ts">
-import { Component, Vue } from "vue-property-decorator";
-import { Group, IPerson } from "@/types/actor";
-import { CURRENT_ACTOR_CLIENT } from "@/graphql/actor";
+import { Component, Vue, Watch } from "vue-property-decorator";
+import { Group, IPerson, usernameWithDomain, MemberRole } from "@/types/actor";
+import { CURRENT_ACTOR_CLIENT, PERSON_MEMBERSHIPS } from "@/graphql/actor";
 import { CREATE_GROUP } from "@/graphql/group";
 import PictureUpload from "@/components/PictureUpload.vue";
 import RouteName from "../../router/name";
+import { mixins } from "vue-class-component";
+import IdentityEditionMixin from "@/mixins/identityEdition";
+import { convertToUsername } from "../../utils/username";
 
 @Component({
   components: {
@@ -48,7 +71,7 @@ import RouteName from "../../router/name";
     },
   },
 })
-export default class CreateGroup extends Vue {
+export default class CreateGroup extends mixins(IdentityEditionMixin) {
   currentActor!: IPerson;
 
   group = new Group();
@@ -57,19 +80,39 @@ export default class CreateGroup extends Vue {
 
   bannerFile: File | null = null;
 
+  errors: string[] = [];
+
+  usernameWithDomain = usernameWithDomain;
+
   async createGroup() {
     try {
       await this.$apollo.mutate({
         mutation: CREATE_GROUP,
         variables: this.buildVariables(),
         update: (store, { data: { createGroup } }) => {
-          // TODO: update group list cache
+          const query = {
+            query: PERSON_MEMBERSHIPS,
+            variables: {
+              id: this.currentActor.id,
+            },
+          };
+          const membershipData = store.readQuery<{ person: IPerson }>(query);
+          if (!membershipData) return;
+          const person: IPerson = membershipData.person;
+          person.memberships.elements.push({
+            parent: createGroup,
+            role: MemberRole.ADMINISTRATOR,
+            actor: this.currentActor,
+            insertedAt: new Date().toString(),
+            updatedAt: new Date().toString(),
+          });
+          store.writeQuery({ ...query, data: { person } });
         },
       });
 
       await this.$router.push({
         name: RouteName.GROUP,
-        params: { identityName: this.group.preferredUsername },
+        params: { preferredUsername: usernameWithDomain(this.group) },
       });
 
       this.$notifier.success(
@@ -82,6 +125,15 @@ export default class CreateGroup extends Vue {
     }
   }
 
+  get host(): string {
+    return window.location.hostname;
+  }
+
+  @Watch("group.name")
+  updateUsername(groupName: string): void {
+    this.group.preferredUsername = convertToUsername(groupName);
+  }
+
   private buildVariables() {
     let avatarObj = {};
     let bannerObj = {};
@@ -121,7 +173,18 @@ export default class CreateGroup extends Vue {
   }
 
   private handleError(err: any) {
-    console.error(err);
+    this.errors.push(
+      ...err.graphQLErrors.map(({ message }: { message: string }) => this.convertMessage(message))
+    );
+  }
+
+  private convertMessage(message: string): string {
+    switch (message) {
+      case "A group with this name already exists":
+        return this.$t("A group with this name already exists") as string;
+      default:
+        return message;
+    }
   }
 }
 </script>
diff --git a/js/src/views/Group/Group.vue b/js/src/views/Group/Group.vue
index d8a3b912c..bf09a7410 100644
--- a/js/src/views/Group/Group.vue
+++ b/js/src/views/Group/Group.vue
@@ -304,6 +304,7 @@ import addMinutes from "date-fns/addMinutes";
   apollo: {
     group: {
       query: FETCH_GROUP,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           name: this.preferredUsername,
@@ -312,6 +313,7 @@ import addMinutes from "date-fns/addMinutes";
     },
     person: {
       query: PERSON_MEMBERSHIPS,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           id: this.currentActor.id,
diff --git a/js/src/views/Group/GroupList.vue b/js/src/views/Group/GroupList.vue
index 0e97d1d5d..86b3fadf6 100644
--- a/js/src/views/Group/GroupList.vue
+++ b/js/src/views/Group/GroupList.vue
@@ -22,11 +22,15 @@ import { LIST_GROUPS } from "@/graphql/group";
 import { Group, IGroup } from "@/types/actor";
 import GroupMemberCard from "@/components/Group/GroupMemberCard.vue";
 import RouteName from "../../router/name";
+import { Paginate } from "@/types/paginate";
 
 @Component({
   apollo: {
     groups: {
-      query: LIST_GROUPS,
+      query: {
+        query: LIST_GROUPS,
+        fetchPolicy: "network-only",
+      },
     },
   },
   components: {
@@ -34,7 +38,7 @@ import RouteName from "../../router/name";
   },
 })
 export default class GroupList extends Vue {
-  groups: { elements: IGroup[]; total: number } = { elements: [], total: 0 };
+  groups!: Paginate<IGroup>;
 
   loading = true;
 
diff --git a/js/src/views/Group/GroupMembers.vue b/js/src/views/Group/GroupMembers.vue
index e6fa34c04..2788c4638 100644
--- a/js/src/views/Group/GroupMembers.vue
+++ b/js/src/views/Group/GroupMembers.vue
@@ -176,7 +176,7 @@ import { IMember, MemberRole } from "../../types/actor/group.model";
   apollo: {
     group: {
       query: GROUP_MEMBERS,
-      // fetchPolicy: "network-only",
+      fetchPolicy: "network-only",
       variables() {
         return {
           name: this.$route.params.preferredUsername,
diff --git a/js/src/views/Group/GroupSettings.vue b/js/src/views/Group/GroupSettings.vue
index 7e75f6234..deae0d90d 100644
--- a/js/src/views/Group/GroupSettings.vue
+++ b/js/src/views/Group/GroupSettings.vue
@@ -91,7 +91,10 @@
           :value="currentAddress"
         />
 
-        <b-button native-type="submit" type="is-primary">{{ $t("Update group") }}</b-button>
+        <div class="buttons">
+          <b-button native-type="submit" type="is-primary">{{ $t("Update group") }}</b-button>
+          <b-button @click="confirmDeleteGroup" type="is-danger">{{ $t("Delete group") }}</b-button>
+        </div>
       </form>
     </section>
   </div>
@@ -100,7 +103,7 @@
 <script lang="ts">
 import { Component, Vue } from "vue-property-decorator";
 import RouteName from "../../router/name";
-import { FETCH_GROUP, UPDATE_GROUP } from "../../graphql/group";
+import { FETCH_GROUP, UPDATE_GROUP, DELETE_GROUP } from "../../graphql/group";
 import { IGroup, usernameWithDomain } from "../../types/actor";
 import { Address, IAddress } from "../../types/address.model";
 import { IMember, Group } from "../../types/actor/group.model";
@@ -111,6 +114,7 @@ import FullAddressAutoComplete from "@/components/Event/FullAddressAutoComplete.
   apollo: {
     group: {
       query: FETCH_GROUP,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           name: this.$route.params.preferredUsername,
@@ -148,15 +152,41 @@ export default class GroupSettings extends Vue {
     // eslint-disable-next-line
     // @ts-ignore
     delete variables.__typename;
-    // eslint-disable-next-line
-    // @ts-ignore
-    delete variables.physicalAddress.__typename;
+    if (variables.physicalAddress) {
+      // eslint-disable-next-line
+      // @ts-ignore
+      delete variables.physicalAddress.__typename;
+    }
     await this.$apollo.mutate<{ updateGroup: IGroup }>({
       mutation: UPDATE_GROUP,
       variables,
     });
   }
 
+  confirmDeleteGroup() {
+    this.$buefy.dialog.confirm({
+      title: this.$t("Delete group") as string,
+      message: this.$t(
+        "Are you sure you want to <b>completely delete</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>."
+      ) as string,
+      confirmText: this.$t("Delete group") as string,
+      cancelText: this.$t("Cancel") as string,
+      type: "is-danger",
+      hasIcon: true,
+      onConfirm: () => this.deleteGroup(),
+    });
+  }
+
+  async deleteGroup() {
+    await this.$apollo.mutate<{ deleteGroup: IGroup }>({
+      mutation: DELETE_GROUP,
+      variables: {
+        groupId: this.group.id,
+      },
+    });
+    return this.$router.push({ name: RouteName.MY_GROUPS });
+  }
+
   async copyURL() {
     await window.navigator.clipboard.writeText(this.group.url);
     this.showCopiedTooltip = true;
diff --git a/js/src/views/Group/MyGroups.vue b/js/src/views/Group/MyGroups.vue
index 77f2788bb..858203400 100644
--- a/js/src/views/Group/MyGroups.vue
+++ b/js/src/views/Group/MyGroups.vue
@@ -85,7 +85,7 @@ export default class MyEvents extends Vue {
   get memberships() {
     if (!this.membershipsPages) return [];
     return this.membershipsPages.elements.filter(
-      (member: IMember) => member.role !== MemberRole.INVITED
+      (member: IMember) => ![MemberRole.INVITED, MemberRole.REJECTED].includes(member.role)
     );
   }
 }
diff --git a/js/src/views/Moderation/Logs.vue b/js/src/views/Moderation/Logs.vue
index 86ae4099b..c5369f9ec 100644
--- a/js/src/views/Moderation/Logs.vue
+++ b/js/src/views/Moderation/Logs.vue
@@ -170,6 +170,7 @@ import { displayNameAndUsername } from "../../types/actor";
   },
   apollo: {
     actionLogs: {
+      fetchPolicy: "cache-and-network",
       query: LOGS,
     },
   },
diff --git a/js/src/views/Moderation/Report.vue b/js/src/views/Moderation/Report.vue
index 67c220a1f..656e5407c 100644
--- a/js/src/views/Moderation/Report.vue
+++ b/js/src/views/Moderation/Report.vue
@@ -232,6 +232,7 @@ import RouteName from "../../router/name";
   apollo: {
     report: {
       query: REPORT,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           id: this.reportId,
diff --git a/js/src/views/Moderation/ReportList.vue b/js/src/views/Moderation/ReportList.vue
index 48a48e2ec..b4af54dc4 100644
--- a/js/src/views/Moderation/ReportList.vue
+++ b/js/src/views/Moderation/ReportList.vue
@@ -57,7 +57,7 @@ import RouteName from "../../router/name";
   apollo: {
     reports: {
       query: REPORTS,
-      fetchPolicy: "no-cache",
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           status: this.filterReports,
diff --git a/js/src/views/Posts/Edit.vue b/js/src/views/Posts/Edit.vue
index ea32807ef..8fb0aeca4 100644
--- a/js/src/views/Posts/Edit.vue
+++ b/js/src/views/Posts/Edit.vue
@@ -98,6 +98,7 @@ import RouteName from "../../router/name";
     config: CONFIG,
     post: {
       query: FETCH_POST,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           slug: this.slug,
diff --git a/js/src/views/Posts/List.vue b/js/src/views/Posts/List.vue
index e42da9f92..cbc37957f 100644
--- a/js/src/views/Posts/List.vue
+++ b/js/src/views/Posts/List.vue
@@ -57,6 +57,7 @@ import RouteName from "../../router/name";
   apollo: {
     group: {
       query: FETCH_GROUP_POSTS,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           preferredUsername: this.preferredUsername,
diff --git a/js/src/views/Posts/Post.vue b/js/src/views/Posts/Post.vue
index 46c1c0e23..95d4ed6a2 100644
--- a/js/src/views/Posts/Post.vue
+++ b/js/src/views/Posts/Post.vue
@@ -58,6 +58,7 @@ import Tag from "../../components/Tag.vue";
     currentActor: CURRENT_ACTOR_CLIENT,
     memberships: {
       query: PERSON_MEMBERSHIPS,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           id: this.currentActor.id,
@@ -70,6 +71,7 @@ import Tag from "../../components/Tag.vue";
     },
     post: {
       query: FETCH_POST,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           slug: this.slug,
diff --git a/js/src/views/Resources/ResourceFolder.vue b/js/src/views/Resources/ResourceFolder.vue
index 9d38db9e5..2140bb752 100644
--- a/js/src/views/Resources/ResourceFolder.vue
+++ b/js/src/views/Resources/ResourceFolder.vue
@@ -218,6 +218,7 @@ import ResourceSelector from "../../components/Resource/ResourceSelector.vue";
   apollo: {
     resource: {
       query: GET_RESOURCE,
+      fetchPolicy: "cache-and-network",
       variables() {
         let path = Array.isArray(this.$route.params.path)
           ? this.$route.params.path.join("/")
diff --git a/js/src/views/Search.vue b/js/src/views/Search.vue
index a7583efbb..95e048c9f 100644
--- a/js/src/views/Search.vue
+++ b/js/src/views/Search.vue
@@ -1,9 +1,9 @@
 <template>
   <div class="section container">
     <h1 class="title">{{ $t("Explore") }}</h1>
-    <section v-if="actualTag">
+    <section v-if="tag">
       <i18n path="Events tagged with {tag}">
-        <b-tag slot="tag" type="is-light">{{ $t("#{tag}", { tag: actualTag }) }}</b-tag>
+        <b-tag slot="tag" type="is-light">{{ $t("#{tag}", { tag }) }}</b-tag>
       </i18n>
     </section>
     <section class="hero is-light" v-else>
@@ -49,7 +49,7 @@
         </form>
       </div>
     </section>
-    <section class="events-featured" v-if="!actualTag && searchEvents.initial">
+    <section class="events-featured" v-if="!tag && searchEvents.initial">
       <b-loading :active.sync="$apollo.loading"></b-loading>
       <h2 class="title">{{ $t("Featured events") }}</h2>
       <div v-if="events.length > 0" class="columns is-multiline">
@@ -163,10 +163,11 @@ const tabsName: { events: number; groups: number } = {
     events: FETCH_EVENTS,
     searchEvents: {
       query: SEARCH_EVENTS,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           term: this.search,
-          tags: this.actualTag,
+          tags: this.tag,
           location: this.geohash,
           beginsOn: this.start,
           endsOn: this.end,
@@ -175,11 +176,12 @@ const tabsName: { events: number; groups: number } = {
       },
       debounce: 300,
       skip() {
-        return !this.search && !this.actualTag && !this.geohash && this.end === null;
+        return !this.search && !this.tag && !this.geohash && this.end === null;
       },
     },
     searchGroups: {
       query: SEARCH_GROUPS,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           term: this.search,
@@ -213,7 +215,6 @@ export default class Search extends Vue {
   activeTab: SearchTabs = tabsName[this.$route.query.searchType as "events" | "groups"] || 0;
 
   location: IAddress = new Address();
-  actualTag: string = this.tag;
 
   options: ISearchTimeOption[] = [
     {
diff --git a/js/src/views/Todos/Todo.vue b/js/src/views/Todos/Todo.vue
index b578e01ba..0aa5a5d70 100644
--- a/js/src/views/Todos/Todo.vue
+++ b/js/src/views/Todos/Todo.vue
@@ -40,6 +40,7 @@ import RouteName from "../../router/name";
   apollo: {
     todo: {
       query: GET_TODO,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           id: this.$route.params.todoId,
diff --git a/js/src/views/Todos/TodoList.vue b/js/src/views/Todos/TodoList.vue
index bac1c79b2..44e0855eb 100644
--- a/js/src/views/Todos/TodoList.vue
+++ b/js/src/views/Todos/TodoList.vue
@@ -56,6 +56,7 @@ import RouteName from "../../router/name";
   apollo: {
     todoList: {
       query: FETCH_TODO_LIST,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           id: this.$route.params.id,
diff --git a/js/src/views/Todos/TodoLists.vue b/js/src/views/Todos/TodoLists.vue
index eba76d1a9..ac4fa94a5 100644
--- a/js/src/views/Todos/TodoLists.vue
+++ b/js/src/views/Todos/TodoLists.vue
@@ -55,6 +55,7 @@ import RouteName from "../../router/name";
   apollo: {
     group: {
       query: FETCH_GROUP,
+      fetchPolicy: "cache-and-network",
       variables() {
         return {
           name: this.$route.params.preferredUsername,
diff --git a/lib/federation/activity_pub/activity_pub.ex b/lib/federation/activity_pub/activity_pub.ex
index 4afd7e8c5..d6447d88f 100644
--- a/lib/federation/activity_pub/activity_pub.ex
+++ b/lib/federation/activity_pub/activity_pub.ex
@@ -96,20 +96,26 @@ defmodule Mobilizon.Federation.ActivityPub do
       {:existing, entity} ->
         Logger.debug("Entity is already existing")
 
-        entity =
+        res =
           if force_fetch and not are_same_origin?(url, Endpoint.url()) do
             Logger.debug("Entity is external and we want a force fetch")
 
-            with {:ok, _activity, entity} <- Fetcher.fetch_and_update(url, options) do
-              entity
+            case Fetcher.fetch_and_update(url, options) do
+              {:ok, _activity, entity} ->
+                {:ok, entity}
+
+              {:error, "Gone"} ->
+                {:error, "Gone", entity}
             end
           else
-            entity
+            {:ok, entity}
           end
 
-        Logger.debug("Going to preload an existing entity")
+        with {:ok, entity} <- res do
+          Logger.debug("Going to preload an existing entity")
 
-        Preloader.maybe_preload(entity)
+          Preloader.maybe_preload(entity)
+        end
 
       e ->
         Logger.warn("Something failed while fetching url #{inspect(e)}")
@@ -333,9 +339,9 @@ defmodule Mobilizon.Federation.ActivityPub do
     end
   end
 
-  def delete(object, actor, local \\ true) do
+  def delete(object, actor, local \\ true, additional \\ %{}) do
     with {:ok, activity_data, actor, object} <-
-           Managable.delete(object, actor, local),
+           Managable.delete(object, actor, local, additional),
          group <- Ownable.group_actor(object),
          :ok <- check_for_actor_key_rotation(actor),
          {:ok, activity} <- create_activity(activity_data, local),
@@ -417,12 +423,14 @@ defmodule Mobilizon.Federation.ActivityPub do
         %Actor{type: :Group, id: group_id, url: group_url, members_url: group_members_url},
         %Actor{id: actor_id, url: actor_url},
         local,
-        _additional
+        additional
       ) do
     with {:member, {:ok, %Member{id: member_id} = member}} <-
            {:member, Actors.get_member(actor_id, group_id)},
-         {:is_only_admin, false} <-
-           {:is_only_admin, Actors.is_only_administrator?(member_id, group_id)},
+         {:is_not_only_admin, true} <-
+           {:is_not_only_admin,
+            Map.get(additional, :force_member_removal, false) ||
+              !Actors.is_only_administrator?(member_id, group_id)},
          {:delete, {:ok, %Member{} = member}} <- {:delete, Actors.delete_member(member)},
          leave_data <- %{
            "to" => [group_members_url],
@@ -639,6 +647,19 @@ defmodule Mobilizon.Federation.ActivityPub do
     end)
   end
 
+  defp convert_followers_in_recipients(recipients) do
+    Enum.reduce(recipients, {recipients, []}, fn recipient, {recipients, follower_actors} = acc ->
+      case Actors.get_group_by_followers_url(recipient) do
+        %Actor{} = group ->
+          {Enum.filter(recipients, fn recipient -> recipient != group.followers_url end),
+           follower_actors ++ Actors.list_external_followers_for_actor(group)}
+
+        _ ->
+          acc
+      end
+    end)
+  end
+
   # @spec is_announce_activity?(Activity.t()) :: boolean
   # defp is_announce_activity?(%Activity{data: %{"type" => "Announce"}}), do: true
   # defp is_announce_activity?(_), do: false
@@ -661,13 +682,7 @@ defmodule Mobilizon.Federation.ActivityPub do
       Relay.publish(activity)
     end
 
-    {recipients, followers} =
-      if actor.followers_url in activity.recipients do
-        {Enum.filter(recipients, fn recipient -> recipient != actor.followers_url end),
-         Actors.list_external_followers_for_actor(actor)}
-      else
-        {recipients, []}
-      end
+    {recipients, followers} = convert_followers_in_recipients(recipients)
 
     {recipients, members} = convert_members_in_recipients(recipients)
 
@@ -858,7 +873,7 @@ defmodule Mobilizon.Federation.ActivityPub do
        ) do
     with %Actor{} = inviter <- Actors.get_actor(invited_by_id),
          %Actor{url: actor_url} <- Actors.get_actor(actor_id),
-         {:ok, %Member{url: member_url, id: member_id} = member} <-
+         {:ok, %Member{id: member_id} = member} <-
            Actors.update_member(member, %{role: :member}),
          accept_data <- %{
            "type" => "Accept",
@@ -866,7 +881,7 @@ defmodule Mobilizon.Federation.ActivityPub do
            "to" => [inviter.url, member.parent.members_url],
            "cc" => [member.parent.url],
            "actor" => actor_url,
-           "object" => member_url,
+           "object" => Convertible.model_to_as(member),
            "id" => "#{Endpoint.url()}/accept/invite/member/#{member_id}"
          } do
       {:ok, member, accept_data}
diff --git a/lib/federation/activity_pub/fetcher.ex b/lib/federation/activity_pub/fetcher.ex
index 256b65c97..6b6f859af 100644
--- a/lib/federation/activity_pub/fetcher.ex
+++ b/lib/federation/activity_pub/fetcher.ex
@@ -27,6 +27,12 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
          {:ok, %Tesla.Env{body: data, status: code}} when code in 200..299 <-
            ActivityPubClient.get(client, url) do
       {:ok, data}
+    else
+      {:ok, %Tesla.Env{status: 410}} ->
+        {:error, "Gone"}
+
+      {:ok, %Tesla.Env{} = res} ->
+        {:error, res}
     end
   end
 
@@ -47,6 +53,9 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
       {:origin_check, false} ->
         Logger.warn("Object origin check failed")
         {:error, "Object origin check failed"}
+
+      {:error, err} ->
+        {:error, err}
     end
   end
 
@@ -67,6 +76,9 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
       {:origin_check, false} ->
         Logger.warn("Object origin check failed")
         {:error, "Object origin check failed"}
+
+      {:error, err} ->
+        {:error, err}
     end
   end
 end
diff --git a/lib/federation/activity_pub/refresher.ex b/lib/federation/activity_pub/refresher.ex
index 021742d9c..3e4de5fd4 100644
--- a/lib/federation/activity_pub/refresher.ex
+++ b/lib/federation/activity_pub/refresher.ex
@@ -3,11 +3,33 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
   Module that provides functions to explore and fetch collections on a group
   """
 
+  alias Mobilizon.Actors
   alias Mobilizon.Actors.Actor
   alias Mobilizon.Federation.ActivityPub
-  alias Mobilizon.Federation.ActivityPub.{Fetcher, Transmogrifier}
+  alias Mobilizon.Federation.ActivityPub.{Fetcher, Relay, Transmogrifier}
   require Logger
 
+  def refresh_profile(%Actor{domain: nil}), do: {:error, "Can only refresh remote actors"}
+
+  def refresh_profile(%Actor{type: :Group, url: url, id: group_id} = group) do
+    on_behalf_of =
+      case Actors.get_single_group_member_actor(group_id) do
+        %Actor{} = member_actor ->
+          member_actor
+
+        _ ->
+          Relay.get_actor()
+      end
+
+    with :ok <- fetch_group(url, on_behalf_of) do
+      {:ok, group}
+    end
+  end
+
+  def refresh_profile(%Actor{type: :Person, url: url}) do
+    ActivityPub.make_actor_from_url(url)
+  end
+
   @spec fetch_group(String.t(), Actor.t()) :: :ok
   def fetch_group(group_url, %Actor{} = on_behalf_of) do
     with {:ok,
@@ -20,14 +42,15 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
             discussions_url: discussions_url,
             events_url: events_url
           }} <-
-           ActivityPub.get_or_fetch_actor_by_url(group_url) do
-      fetch_collection(outbox_url, on_behalf_of)
-      fetch_collection(members_url, on_behalf_of)
-      fetch_collection(resources_url, on_behalf_of)
-      fetch_collection(posts_url, on_behalf_of)
-      fetch_collection(todos_url, on_behalf_of)
-      fetch_collection(discussions_url, on_behalf_of)
-      fetch_collection(events_url, on_behalf_of)
+           ActivityPub.make_actor_from_url(group_url),
+         :ok <- fetch_collection(outbox_url, on_behalf_of),
+         :ok <- fetch_collection(members_url, on_behalf_of),
+         :ok <- fetch_collection(resources_url, on_behalf_of),
+         :ok <- fetch_collection(posts_url, on_behalf_of),
+         :ok <- fetch_collection(todos_url, on_behalf_of),
+         :ok <- fetch_collection(discussions_url, on_behalf_of),
+         :ok <- fetch_collection(events_url, on_behalf_of) do
+      :ok
     end
   end
 
@@ -37,9 +60,10 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
     Logger.debug("Fetching and preparing collection from url")
     Logger.debug(inspect(collection_url))
 
-    with {:ok, data} <- Fetcher.fetch(collection_url, on_behalf_of: on_behalf_of) do
-      Logger.debug("Fetch ok, passing to process_collection")
-      process_collection(data, on_behalf_of)
+    with {:ok, data} <- Fetcher.fetch(collection_url, on_behalf_of: on_behalf_of),
+         :ok <- Logger.debug("Fetch ok, passing to process_collection"),
+         :ok <- process_collection(data, on_behalf_of) do
+      :ok
     end
   end
 
@@ -68,6 +92,7 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
     Logger.debug(inspect(items))
 
     Enum.each(items, &handling_element/1)
+    :ok
   end
 
   defp process_collection(%{"type" => "OrderedCollection", "first" => first}, on_behalf_of)
@@ -84,7 +109,15 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
     end
   end
 
+  defp process_collection(_, _), do: :error
+
   defp handling_element(data) when is_map(data) do
+    id = Map.get(data, "id")
+
+    if id do
+      Mobilizon.Tombstone.delete_uri_tombstone(id)
+    end
+
     activity = %{
       "type" => "Create",
       "to" => data["to"],
diff --git a/lib/federation/activity_pub/transmogrifier.ex b/lib/federation/activity_pub/transmogrifier.ex
index a82dfc48e..5c4a39e0b 100644
--- a/lib/federation/activity_pub/transmogrifier.ex
+++ b/lib/federation/activity_pub/transmogrifier.ex
@@ -131,15 +131,18 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
     Logger.info("Handle incoming to create a member")
 
     with object_data when is_map(object_data) <-
-           object |> Converter.Member.as_to_model_data(),
-         {:existing_member, nil} <-
-           {:existing_member, Actors.get_member_by_url(object_data.url)},
-         {:ok, %Activity{} = activity, %Member{} = member} <-
-           ActivityPub.join_group(object_data, false) do
-      {:ok, activity, member}
-    else
-      {:existing_member, %Member{} = member} ->
-        {:ok, nil, member}
+           object |> Converter.Member.as_to_model_data() do
+      with {:existing_member, nil} <-
+             {:existing_member, Actors.get_member_by_url(object_data.url)},
+           {:ok, %Activity{} = activity, %Member{} = member} <-
+             ActivityPub.join_group(object_data, false) do
+        {:ok, activity, member}
+      else
+        {:existing_member, %Member{} = member} ->
+          {:ok, %Member{} = member} = Actors.update_member(member, object_data)
+
+          {:ok, nil, member}
+      end
     end
   end
 
@@ -502,7 +505,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
     with actor_url <- Utils.get_actor(data),
          {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor_url),
          object_id <- Utils.get_url(object),
-         {:ok, object} <- ActivityPub.fetch_object_from_url(object_id),
+         {:error, "Gone", object} <- ActivityPub.fetch_object_from_url(object_id, force: true),
          {:origin_check, true} <-
            {:origin_check,
             Utils.origin_check_from_id?(actor_url, object_id) ||
@@ -515,7 +518,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
         :error
 
       e ->
-        Logger.debug(inspect(e))
+        Logger.error(inspect(e))
         :error
     end
   end
diff --git a/lib/federation/activity_pub/types/actors.ex b/lib/federation/activity_pub/types/actors.ex
index c9360959e..824bb3b3d 100644
--- a/lib/federation/activity_pub/types/actors.ex
+++ b/lib/federation/activity_pub/types/actors.ex
@@ -38,29 +38,55 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
     end
   end
 
+  @public_ap "https://www.w3.org/ns/activitystreams#Public"
+
   @impl Entity
   def delete(
-        %Actor{followers_url: followers_url, url: target_actor_url} = target_actor,
-        %Actor{url: actor_url} = actor,
-        local
+        %Actor{
+          followers_url: followers_url,
+          members_url: members_url,
+          url: target_actor_url,
+          type: type,
+          domain: domain
+        } = target_actor,
+        %Actor{url: actor_url, id: author_id} = actor,
+        _local,
+        additionnal
       ) do
+    to = [@public_ap, followers_url]
+
+    {to, cc} =
+      if type == :Group do
+        {to ++ [members_url], [target_actor_url]}
+      else
+        {to, []}
+      end
+
     activity_data = %{
       "type" => "Delete",
       "actor" => actor_url,
       "object" => Convertible.model_to_as(target_actor),
       "id" => target_actor_url <> "/delete",
-      "to" => [followers_url, "https://www.w3.org/ns/activitystreams#Public"]
+      "to" => to,
+      "cc" => cc
     }
 
-    # We completely delete the actor if activity is remote
-    with {:ok, %Oban.Job{}} <- Actors.delete_actor(target_actor, reserve_username: local) do
+    suspension = Map.get(additionnal, :suspension, false)
+
+    with {:ok, %Oban.Job{}} <-
+           Actors.delete_actor(target_actor,
+             # We completely delete the actor if the actor is remote
+             reserve_username: is_nil(domain),
+             suspension: suspension,
+             author_id: author_id
+           ) do
       {:ok, activity_data, actor, target_actor}
     end
   end
 
   def actor(%Actor{} = actor), do: actor
 
-  def group_actor(%Actor{} = _actor), do: nil
+  def group_actor(%Actor{} = actor), do: actor
 
   defp prepare_args_for_actor(args) do
     with preferred_username <-
diff --git a/lib/federation/activity_pub/types/comments.ex b/lib/federation/activity_pub/types/comments.ex
index c7f6cead9..1c1f04f6d 100644
--- a/lib/federation/activity_pub/types/comments.ex
+++ b/lib/federation/activity_pub/types/comments.ex
@@ -53,8 +53,15 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
   end
 
   @impl Entity
-  @spec delete(Comment.t(), Actor.t(), boolean) :: {:ok, Comment.t()}
-  def delete(%Comment{url: url} = comment, %Actor{} = actor, _local) do
+  @spec delete(Comment.t(), Actor.t(), boolean, map()) :: {:ok, Comment.t()}
+  def delete(
+        %Comment{url: url, id: comment_id},
+        %Actor{} = actor,
+        _local,
+        options \\ %{}
+      ) do
+    comment = Discussions.get_comment_with_preload(comment_id)
+
     activity_data = %{
       "type" => "Delete",
       "actor" => actor.url,
@@ -63,16 +70,17 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
       "to" => ["https://www.w3.org/ns/activitystreams#Public"]
     }
 
+    force_deletion = Map.get(options, :force, false)
+
     with audience <-
            Audience.calculate_to_and_cc_from_mentions(comment),
-         {:ok, %Comment{} = comment} <- Discussions.delete_comment(comment),
-         # Preload to be sure
-         %Comment{} = comment <- Discussions.get_comment_with_preload(comment.id),
+         {:ok, %Comment{} = updated_comment} <-
+           Discussions.delete_comment(comment, force: force_deletion),
          {:ok, true} <- Cachex.del(:activity_pub, "comment_#{comment.uuid}"),
          {:ok, %Tombstone{} = _tombstone} <-
            Tombstone.create_tombstone(%{uri: comment.url, actor_id: actor.id}) do
       Share.delete_all_by_uri(comment.url)
-      {:ok, Map.merge(activity_data, audience), actor, comment}
+      {:ok, Map.merge(activity_data, audience), actor, updated_comment}
     end
   end
 
diff --git a/lib/federation/activity_pub/types/discussions.ex b/lib/federation/activity_pub/types/discussions.ex
index a27d3c2cf..0d5248f0e 100644
--- a/lib/federation/activity_pub/types/discussions.ex
+++ b/lib/federation/activity_pub/types/discussions.ex
@@ -5,9 +5,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
   alias Mobilizon.Actors.Actor
   alias Mobilizon.Discussions.{Comment, Discussion}
   alias Mobilizon.Federation.ActivityPub.Audience
-  alias Mobilizon.Federation.ActivityPub.Types.{Comments, Entity}
+  alias Mobilizon.Federation.ActivityPub.Types.Entity
   alias Mobilizon.Federation.ActivityStream.Convertible
-  alias Mobilizon.Storage.Repo
   alias Mobilizon.Web.Endpoint
   import Mobilizon.Federation.ActivityPub.Utils, only: [make_create_data: 2, make_update_data: 2]
   require Logger
@@ -65,28 +64,14 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
   end
 
   @impl Entity
-  @spec delete(Discussion.t(), Actor.t(), boolean) :: {:ok, Discussion.t()}
-  def delete(%Discussion{actor: group, url: url} = discussion, %Actor{} = actor, _local) do
-    stream =
-      discussion.comments
-      |> Enum.map(
-        &Repo.preload(&1, [
-          :actor,
-          :attributed_to,
-          :in_reply_to_comment,
-          :mentions,
-          :origin_comment,
-          :discussion,
-          :tags,
-          :replies
-        ])
-      )
-      |> Enum.map(&Map.put(&1, :event, nil))
-      |> Task.async_stream(fn comment -> Comments.delete(comment, actor, nil) end)
-
-    Stream.run(stream)
-
-    with {:ok, %Discussion{}} <- Discussions.delete_discussion(discussion) do
+  @spec delete(Discussion.t(), Actor.t(), boolean, map()) :: {:ok, Discussion.t()}
+  def delete(
+        %Discussion{actor: group, url: url} = discussion,
+        %Actor{} = actor,
+        _local,
+        _additionnal
+      ) do
+    with {:ok, _} <- Discussions.delete_discussion(discussion) do
       # This is just fake
       activity_data = %{
         "type" => "Delete",
diff --git a/lib/federation/activity_pub/types/entity.ex b/lib/federation/activity_pub/types/entity.ex
index e0ec694fa..ffb3974c4 100644
--- a/lib/federation/activity_pub/types/entity.ex
+++ b/lib/federation/activity_pub/types/entity.ex
@@ -35,7 +35,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Entity do
   @callback update(struct :: t(), attrs :: map(), additionnal :: map()) ::
               {:ok, t(), ActivityStream.t()}
 
-  @callback delete(struct :: t(), Actor.t(), local :: boolean()) ::
+  @callback delete(struct :: t(), Actor.t(), local :: boolean(), map()) ::
               {:ok, ActivityStream.t(), Actor.t(), t()}
 end
 
@@ -50,10 +50,10 @@ defprotocol Mobilizon.Federation.ActivityPub.Types.Managable do
   """
   def update(entity, attrs, additionnal)
 
-  @spec delete(Entity.t(), Actor.t(), boolean()) ::
+  @spec delete(Entity.t(), Actor.t(), boolean(), map()) ::
           {:ok, ActivityStream.t(), Actor.t(), Entity.t()}
   @doc "Deletes an entity and returns the activitystream representation for it"
-  def delete(entity, actor, local)
+  def delete(entity, actor, local, additionnal)
 end
 
 defprotocol Mobilizon.Federation.ActivityPub.Types.Ownable do
@@ -68,7 +68,7 @@ end
 
 defimpl Managable, for: Event do
   defdelegate update(entity, attrs, additionnal), to: Events
-  defdelegate delete(entity, actor, local), to: Events
+  defdelegate delete(entity, actor, local, additionnal), to: Events
 end
 
 defimpl Ownable, for: Event do
@@ -78,7 +78,7 @@ end
 
 defimpl Managable, for: Comment do
   defdelegate update(entity, attrs, additionnal), to: Comments
-  defdelegate delete(entity, actor, local), to: Comments
+  defdelegate delete(entity, actor, local, additionnal), to: Comments
 end
 
 defimpl Ownable, for: Comment do
@@ -88,7 +88,7 @@ end
 
 defimpl Managable, for: Post do
   defdelegate update(entity, attrs, additionnal), to: Posts
-  defdelegate delete(entity, actor, local), to: Posts
+  defdelegate delete(entity, actor, local, additionnal), to: Posts
 end
 
 defimpl Ownable, for: Post do
@@ -98,7 +98,7 @@ end
 
 defimpl Managable, for: Actor do
   defdelegate update(entity, attrs, additionnal), to: Actors
-  defdelegate delete(entity, actor, local), to: Actors
+  defdelegate delete(entity, actor, local, additionnal), to: Actors
 end
 
 defimpl Ownable, for: Actor do
@@ -108,7 +108,7 @@ end
 
 defimpl Managable, for: TodoList do
   defdelegate update(entity, attrs, additionnal), to: TodoLists
-  defdelegate delete(entity, actor, local), to: TodoLists
+  defdelegate delete(entity, actor, local, additionnal), to: TodoLists
 end
 
 defimpl Ownable, for: TodoList do
@@ -118,7 +118,7 @@ end
 
 defimpl Managable, for: Todo do
   defdelegate update(entity, attrs, additionnal), to: Todos
-  defdelegate delete(entity, actor, local), to: Todos
+  defdelegate delete(entity, actor, local, additionnal), to: Todos
 end
 
 defimpl Ownable, for: Todo do
@@ -128,7 +128,7 @@ end
 
 defimpl Managable, for: Resource do
   defdelegate update(entity, attrs, additionnal), to: Resources
-  defdelegate delete(entity, actor, local), to: Resources
+  defdelegate delete(entity, actor, local, additionnal), to: Resources
 end
 
 defimpl Ownable, for: Resource do
@@ -138,7 +138,7 @@ end
 
 defimpl Managable, for: Discussion do
   defdelegate update(entity, attrs, additionnal), to: Discussions
-  defdelegate delete(entity, actor, local), to: Discussions
+  defdelegate delete(entity, actor, local, additionnal), to: Discussions
 end
 
 defimpl Ownable, for: Discussion do
@@ -153,5 +153,5 @@ end
 
 defimpl Managable, for: Member do
   defdelegate update(entity, attrs, additionnal), to: Members
-  defdelegate delete(entity, actor, local), to: Members
+  defdelegate delete(entity, actor, local, additionnal), to: Members
 end
diff --git a/lib/federation/activity_pub/types/events.ex b/lib/federation/activity_pub/types/events.ex
index ea9082661..7fe63a2f7 100644
--- a/lib/federation/activity_pub/types/events.ex
+++ b/lib/federation/activity_pub/types/events.ex
@@ -53,8 +53,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
   end
 
   @impl Entity
-  @spec delete(Event.t(), Actor.t(), boolean) :: {:ok, Event.t()}
-  def delete(%Event{url: url} = event, %Actor{} = actor, _local) do
+  @spec delete(Event.t(), Actor.t(), boolean, map()) :: {:ok, Event.t()}
+  def delete(%Event{url: url} = event, %Actor{} = actor, _local, _additionnal) do
     activity_data = %{
       "type" => "Delete",
       "actor" => actor.url,
diff --git a/lib/federation/activity_pub/types/members.ex b/lib/federation/activity_pub/types/members.ex
index 98f6f1dad..cb1c7ae97 100644
--- a/lib/federation/activity_pub/types/members.ex
+++ b/lib/federation/activity_pub/types/members.ex
@@ -2,6 +2,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Members do
   @moduledoc false
   alias Mobilizon.Actors
   alias Mobilizon.Actors.{Actor, Member}
+  alias Mobilizon.Federation.ActivityPub
   alias Mobilizon.Federation.ActivityStream.Convertible
   require Logger
   import Mobilizon.Federation.ActivityPub.Utils, only: [make_update_data: 2]
@@ -38,8 +39,16 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Members do
     end
   end
 
-  # Delete member is not used, see ActivityPub.leave/4 and ActivityPub.remove/5 instead
-  def delete(_, _, _), do: :error
+  # Used only when a group is suspended
+  def delete(
+        %Member{parent: %Actor{} = group, actor: %Actor{} = actor} = _member,
+        %Actor{},
+        local,
+        _additionnal
+      ) do
+    Logger.debug("Deleting a member")
+    ActivityPub.leave(group, actor, local, %{force_member_removal: true})
+  end
 
   def actor(%Member{actor_id: actor_id}),
     do: Actors.get_actor(actor_id)
diff --git a/lib/federation/activity_pub/types/posts.ex b/lib/federation/activity_pub/types/posts.ex
index 51f3aadf2..f7cd1104a 100644
--- a/lib/federation/activity_pub/types/posts.ex
+++ b/lib/federation/activity_pub/types/posts.ex
@@ -69,7 +69,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Posts do
           attributed_to: %Actor{url: group_url}
         } = post,
         %Actor{url: actor_url} = actor,
-        _local
+        _local,
+        _additionnal
       ) do
     activity_data = %{
       "actor" => actor_url,
diff --git a/lib/federation/activity_pub/types/resources.ex b/lib/federation/activity_pub/types/resources.ex
index 06a213096..025b8af21 100644
--- a/lib/federation/activity_pub/types/resources.ex
+++ b/lib/federation/activity_pub/types/resources.ex
@@ -131,7 +131,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Resources do
   def delete(
         %Resource{url: url, actor: %Actor{url: group_url, members_url: members_url}} = resource,
         %Actor{url: actor_url} = actor,
-        _local
+        _local,
+        _additionnal
       ) do
     Logger.debug("Building Delete Resource activity")
 
diff --git a/lib/federation/activity_pub/types/todo_lists.ex b/lib/federation/activity_pub/types/todo_lists.ex
index dedf9e489..b2b170f16 100644
--- a/lib/federation/activity_pub/types/todo_lists.ex
+++ b/lib/federation/activity_pub/types/todo_lists.ex
@@ -40,19 +40,20 @@ defmodule Mobilizon.Federation.ActivityPub.Types.TodoLists do
   end
 
   @impl Entity
-  @spec delete(TodoList.t(), Actor.t(), boolean()) ::
+  @spec delete(TodoList.t(), Actor.t(), boolean(), map()) ::
           {:ok, ActivityStream.t(), Actor.t(), TodoList.t()}
   def delete(
         %TodoList{url: url, actor: %Actor{url: group_url}} = todo_list,
         %Actor{url: actor_url} = actor,
-        _local
+        _local,
+        _additionnal
       ) do
     Logger.debug("Building Delete TodoList activity")
 
     activity_data = %{
       "actor" => actor_url,
       "type" => "Delete",
-      "object" => Convertible.model_to_as(url),
+      "object" => Convertible.model_to_as(todo_list),
       "id" => url <> "/delete",
       "to" => [group_url]
     }
diff --git a/lib/federation/activity_pub/types/todos.ex b/lib/federation/activity_pub/types/todos.ex
index dcf635f5c..50e573eb9 100644
--- a/lib/federation/activity_pub/types/todos.ex
+++ b/lib/federation/activity_pub/types/todos.ex
@@ -44,11 +44,13 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Todos do
   end
 
   @impl Entity
-  @spec delete(Todo.t(), Actor.t(), boolean()) :: {:ok, ActivityStream.t(), Actor.t(), Todo.t()}
+  @spec delete(Todo.t(), Actor.t(), boolean(), map()) ::
+          {:ok, ActivityStream.t(), Actor.t(), Todo.t()}
   def delete(
         %Todo{url: url, creator: %Actor{url: group_url}} = todo,
         %Actor{url: actor_url} = actor,
-        _local
+        _local,
+        _additionnal
       ) do
     Logger.debug("Building Delete Todo activity")
 
diff --git a/lib/federation/activity_pub/utils.ex b/lib/federation/activity_pub/utils.ex
index 0bd7d1a8f..ee763bb32 100644
--- a/lib/federation/activity_pub/utils.ex
+++ b/lib/federation/activity_pub/utils.ex
@@ -143,7 +143,9 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do
     do_maybe_relay_if_group_activity(object, attributed_to_url)
   end
 
-  def maybe_relay_if_group_activity(_, _), do: :ok
+  def maybe_relay_if_group_activity(_activity, _attributedTo) do
+    :ok
+  end
 
   defp do_maybe_relay_if_group_activity(object, attributed_to) when is_list(attributed_to),
     do: do_maybe_relay_if_group_activity(object, hd(attributed_to))
diff --git a/lib/federation/activity_stream/converter/comment.ex b/lib/federation/activity_stream/converter/comment.ex
index 98fd2eaf1..e2e45cb6d 100644
--- a/lib/federation/activity_stream/converter/comment.ex
+++ b/lib/federation/activity_stream/converter/comment.ex
@@ -135,6 +135,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Comment do
   def model_to_as(%CommentModel{} = comment) do
     Convertible.model_to_as(%TombstoneModel{
       uri: comment.url,
+      actor: comment.actor,
       inserted_at: comment.deleted_at
     })
   end
diff --git a/lib/federation/activity_stream/converter/discussion.ex b/lib/federation/activity_stream/converter/discussion.ex
index 514e0dfa2..819b0a2da 100644
--- a/lib/federation/activity_stream/converter/discussion.ex
+++ b/lib/federation/activity_stream/converter/discussion.ex
@@ -39,6 +39,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Discussion do
       "actor" => discussion.creator.url,
       "attributedTo" => discussion.actor.url,
       "id" => discussion.url,
+      "publishedAt" => discussion.inserted_at,
       "context" => discussion.url
     }
   end
diff --git a/lib/federation/activity_stream/converter/tombstone.ex b/lib/federation/activity_stream/converter/tombstone.ex
index 642e26485..155658fbd 100644
--- a/lib/federation/activity_stream/converter/tombstone.ex
+++ b/lib/federation/activity_stream/converter/tombstone.ex
@@ -28,7 +28,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Tombstone do
     %{
       "type" => "Tombstone",
       "id" => tombstone.uri,
-      "actor" => tombstone.actor.url,
+      "actor" => if(tombstone.actor, do: tombstone.actor.url, else: nil),
       "deleted" => tombstone.inserted_at
     }
   end
diff --git a/lib/graphql/api/groups.ex b/lib/graphql/api/groups.ex
index e813d0041..dfa61b1e8 100644
--- a/lib/graphql/api/groups.ex
+++ b/lib/graphql/api/groups.ex
@@ -18,7 +18,7 @@ defmodule Mobilizon.GraphQL.API.Groups do
     with preferred_username <-
            args |> Map.get(:preferred_username) |> HTML.strip_tags() |> String.trim(),
          {:existing_group, nil} <-
-           {:existing_group, Actors.get_local_group_by_title(preferred_username)},
+           {:existing_group, Actors.get_local_actor_by_name(preferred_username)},
          args <- args |> Map.put(:type, :Group),
          {:ok, %Activity{} = activity, %Actor{} = group} <-
            ActivityPub.create(:actor, args, true, %{"actor" => args.creator_actor.url}) do
diff --git a/lib/graphql/resolvers/actor.ex b/lib/graphql/resolvers/actor.ex
new file mode 100644
index 000000000..dd9e950c9
--- /dev/null
+++ b/lib/graphql/resolvers/actor.ex
@@ -0,0 +1,104 @@
+defmodule Mobilizon.GraphQL.Resolvers.Actor do
+  @moduledoc """
+  Handles the group-related GraphQL calls.
+  """
+
+  import Mobilizon.Users.Guards
+  alias Mobilizon.{Actors, Admin, Users}
+  alias Mobilizon.Actors.Actor
+  alias Mobilizon.Federation.ActivityPub
+  alias Mobilizon.Federation.ActivityPub.Refresher
+  alias Mobilizon.Users.User
+
+  require Logger
+
+  def refresh_profile(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}})
+      when is_admin(role) do
+    case Actors.get_actor(id) do
+      %Actor{domain: domain} = actor when not is_nil(domain) ->
+        Refresher.refresh_profile(actor)
+        {:ok, actor}
+
+      %Actor{} ->
+        {:error, "Only remote actors may be refreshed"}
+
+      _ ->
+        {:error, "No actor found with this ID"}
+    end
+  end
+
+  def suspend_profile(_parent, %{id: id}, %{
+        context: %{current_user: %User{role: role} = user}
+      })
+      when is_moderator(role) do
+    with {:moderator_actor, %Actor{} = moderator_actor} <-
+           {:moderator_actor, Users.get_actor_for_user(user)},
+         %Actor{suspended: false} = actor <- Actors.get_actor_with_preload(id) do
+      case actor do
+        # Suspend a group on this instance
+        %Actor{type: :Group, domain: nil} ->
+          Logger.debug("We're suspending a group on this very instance")
+          ActivityPub.delete(actor, moderator_actor, true, %{suspension: true})
+          Admin.log_action(moderator_actor, "suspend", actor)
+          {:ok, actor}
+
+        # Delete a remote actor
+        %Actor{domain: domain} when not is_nil(domain) ->
+          Logger.debug("We're just deleting a remote instance")
+          Actors.delete_actor(actor, suspension: true)
+          Admin.log_action(moderator_actor, "suspend", actor)
+          {:ok, actor}
+
+        %Actor{domain: nil} ->
+          {:error, "No remote profile found with this ID"}
+      end
+    else
+      {:moderator_actor, nil} ->
+        {:error, "No actor found for the moderator user"}
+
+      %Actor{suspended: true} ->
+        {:error, "Actor already suspended"}
+
+      {:error, _} ->
+        {:error, "Error while performing background task"}
+    end
+  end
+
+  def suspend_profile(_parent, _args, _resolution) do
+    {:error, "Only moderators and administrators can suspend a profile"}
+  end
+
+  def unsuspend_profile(_parent, %{id: id}, %{
+        context: %{current_user: %User{role: role} = user}
+      })
+      when is_moderator(role) do
+    with {:moderator_actor, %Actor{} = moderator_actor} <-
+           {:moderator_actor, Users.get_actor_for_user(user)},
+         %Actor{suspended: true} = actor <-
+           Actors.get_actor_with_preload(id, true),
+         {:delete_tombstones, {_, nil}} <-
+           {:delete_tombstones, Mobilizon.Tombstone.delete_actor_tombstones(id)},
+         {:ok, %Actor{} = actor} <- Actors.update_actor(actor, %{suspended: false}),
+         {:ok, %Actor{} = actor} <- refresh_if_remote(actor),
+         {:ok, _} <- Admin.log_action(moderator_actor, "unsuspend", actor) do
+      {:ok, actor}
+    else
+      {:moderator_actor, nil} ->
+        {:error, "No actor found for the moderator user"}
+
+      nil ->
+        {:error, "No remote profile found with this ID"}
+
+      {:error, _} ->
+        {:error, "Error while performing background task"}
+    end
+  end
+
+  def unsuspend_profile(_parent, _args, _resolution) do
+    {:error, "Only moderators and administrators can unsuspend a profile"}
+  end
+
+  @spec refresh_if_remote(Actor.t()) :: {:ok, Actor.t()}
+  defp refresh_if_remote(%Actor{domain: nil} = actor), do: {:ok, actor}
+  defp refresh_if_remote(%Actor{} = actor), do: Refresher.refresh_profile(actor)
+end
diff --git a/lib/graphql/resolvers/discussion.ex b/lib/graphql/resolvers/discussion.ex
index cc0010dfb..300a98e68 100644
--- a/lib/graphql/resolvers/discussion.ex
+++ b/lib/graphql/resolvers/discussion.ex
@@ -20,8 +20,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
         }
       ) do
     with {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
-         {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do
-      {:ok, Discussions.find_discussions_for_actor(group_id)}
+         {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
+         {:ok, %Actor{type: :Group} = group} <- Actors.get_group_by_actor_id(group_id) do
+      {:ok, Discussions.find_discussions_for_actor(group)}
     else
       {:member, false} ->
         {:ok, %Page{total: 0, elements: []}}
@@ -174,6 +175,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
          {:ok, _activity, %Discussion{} = discussion} <-
            ActivityPub.delete(discussion, actor) do
       {:ok, discussion}
+    else
+      {:no_discussion, _} ->
+        {:error, "No discussion with ID #{discussion_id}"}
+
+      {:member, _} ->
+        {:error, "You are not a member of the group the discussion belongs to"}
     end
   end
 end
diff --git a/lib/graphql/resolvers/group.ex b/lib/graphql/resolvers/group.ex
index fe4489f0e..6bbf276f6 100644
--- a/lib/graphql/resolvers/group.ex
+++ b/lib/graphql/resolvers/group.ex
@@ -3,6 +3,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
   Handles the group-related GraphQL calls.
   """
 
+  import Mobilizon.Users.Guards
   alias Mobilizon.{Actors, Events, Users}
   alias Mobilizon.Actors.{Actor, Member}
   alias Mobilizon.Federation.ActivityPub
@@ -54,13 +55,46 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
     end
   end
 
+  @doc """
+  Get a group
+  """
+  def get_group(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}}) do
+    with %Actor{type: :Group, suspended: suspended} = actor <-
+           Actors.get_actor_with_preload(id, true),
+         true <- suspended == false or is_moderator(role) do
+      {:ok, actor}
+    else
+      _ ->
+        {:error, "Group with ID #{id} not found"}
+    end
+  end
+
   @doc """
   Lists all groups
   """
-  def list_groups(_parent, %{page: page, limit: limit}, _resolution) do
-    {:ok, Actors.list_groups(page, limit)}
+  def list_groups(
+        _parent,
+        %{
+          preferred_username: preferred_username,
+          name: name,
+          domain: domain,
+          local: local,
+          suspended: suspended,
+          page: page,
+          limit: limit
+        },
+        %{
+          context: %{current_user: %User{role: role}}
+        }
+      )
+      when is_moderator(role) do
+    {:ok,
+     Actors.list_actors(:Group, preferred_username, name, domain, local, suspended, page, limit)}
   end
 
+  def list_groups(_parent, _args, _resolution),
+    do: {:error, "You may not list groups unless moderator."}
+
   @doc """
   Create a new group. The creator is automatically added as admin
   """
@@ -127,28 +161,23 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
   """
   def delete_group(
         _parent,
-        %{group_id: group_id, actor_id: actor_id},
+        %{group_id: group_id},
         %{
           context: %{
             current_user: user
           }
         }
       ) do
-    with {actor_id, ""} <- Integer.parse(actor_id),
-         {group_id, ""} <- Integer.parse(group_id),
+    with %Actor{id: actor_id} = actor <- Users.get_actor_for_user(user),
          {:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
-         {:is_owned, %Actor{}} <- User.owns_actor(user, actor_id),
          {:ok, %Member{} = member} <- Actors.get_member(actor_id, group.id),
          {:is_admin, true} <- {:is_admin, Member.is_administrator(member)},
-         group <- Actors.delete_group!(group) do
+         {:ok, _activity, group} <- ActivityPub.delete(group, actor, true) do
       {:ok, %{id: group.id}}
     else
       {:error, :group_not_found} ->
         {:error, "Group not found"}
 
-      {:is_owned, nil} ->
-        {:error, "Actor id is not owned by authenticated user"}
-
       {:error, :member_not_found} ->
         {:error, "Actor id is not a member of this group"}
 
@@ -231,7 +260,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
       {:group, nil} ->
         {:error, "Group not found"}
 
-      {:is_only_admin, true} ->
+      {:is_not_only_admin, false} ->
         {:error, "You can't leave this group because you are the only administrator"}
     end
   end
@@ -245,12 +274,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
         _args,
         %{
           context: %{
-            current_user: %User{} = user
+            current_user: %User{role: user_role} = user
           }
         }
       ) do
     with {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)},
-         {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do
+         {:member, true} <-
+           {:member, Actors.is_member?(actor_id, group_id) or is_moderator(user_role)} do
       # TODO : Handle public / restricted to group members events
       {:ok, Events.list_organized_events_for_group(group)}
     else
diff --git a/lib/graphql/resolvers/member.ex b/lib/graphql/resolvers/member.ex
index 2af731bcc..387355502 100644
--- a/lib/graphql/resolvers/member.ex
+++ b/lib/graphql/resolvers/member.ex
@@ -3,6 +3,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
   Handles the member-related GraphQL calls
   """
 
+  import Mobilizon.Users.Guards
   alias Mobilizon.{Actors, Users}
   alias Mobilizon.Actors.{Actor, Member}
   alias Mobilizon.Federation.ActivityPub
@@ -19,11 +20,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
         %Actor{id: group_id} = group,
         %{page: page, limit: limit, roles: roles},
         %{
-          context: %{current_user: %User{} = user}
+          context: %{current_user: %User{role: user_role} = user}
         } = _resolution
       ) do
     with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
-         {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do
+         {:member, true} <-
+           {:member, Actors.is_member?(actor_id, group_id) or is_moderator(user_role)} do
       roles =
         case roles do
           "" ->
@@ -167,9 +169,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
       {:error, :member_not_found} ->
         true
 
-      err ->
-        require Logger
-        Logger.error(inspect(err))
+      _err ->
         false
     end
   end
diff --git a/lib/graphql/resolvers/person.ex b/lib/graphql/resolvers/person.ex
index edc46fc02..d5e0b07a8 100644
--- a/lib/graphql/resolvers/person.ex
+++ b/lib/graphql/resolvers/person.ex
@@ -7,7 +7,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
 
   alias Mobilizon.Actors
   alias Mobilizon.Actors.Actor
-  alias Mobilizon.Admin
   alias Mobilizon.Events
   alias Mobilizon.Events.Participant
   alias Mobilizon.Storage.Page
@@ -321,64 +320,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
     end
   end
 
-  def suspend_profile(_parent, %{id: id}, %{
-        context: %{current_user: %User{role: role} = user}
-      })
-      when is_moderator(role) do
-    with {:moderator_actor, %Actor{} = moderator_actor} <-
-           {:moderator_actor, Users.get_actor_for_user(user)},
-         %Actor{suspended: false} = actor <- Actors.get_remote_actor_with_preload(id),
-         {:ok, _} <- Actors.delete_actor(actor),
-         {:ok, _} <- Admin.log_action(moderator_actor, "suspend", actor) do
-      {:ok, actor}
-    else
-      {:moderator_actor, nil} ->
-        {:error, "No actor found for the moderator user"}
-
-      %Actor{suspended: true} ->
-        {:error, "Actor already suspended"}
-
-      nil ->
-        {:error, "No remote profile found with this ID"}
-
-      {:error, _} ->
-        {:error, "Error while performing background task"}
-    end
-  end
-
-  def suspend_profile(_parent, _args, _resolution) do
-    {:error, "Only moderators and administrators can suspend a profile"}
-  end
-
-  def unsuspend_profile(_parent, %{id: id}, %{
-        context: %{current_user: %User{role: role} = user}
-      })
-      when is_moderator(role) do
-    with {:moderator_actor, %Actor{} = moderator_actor} <-
-           {:moderator_actor, Users.get_actor_for_user(user)},
-         %Actor{preferred_username: preferred_username, domain: domain} = actor <-
-           Actors.get_remote_actor_with_preload(id, true),
-         {:ok, _} <- Actors.update_actor(actor, %{suspended: false}),
-         {:ok, %Actor{} = actor} <-
-           ActivityPub.make_actor_from_nickname("#{preferred_username}@#{domain}"),
-         {:ok, _} <- Admin.log_action(moderator_actor, "unsuspend", actor) do
-      {:ok, actor}
-    else
-      {:moderator_actor, nil} ->
-        {:error, "No actor found for the moderator user"}
-
-      nil ->
-        {:error, "No remote profile found with this ID"}
-
-      {:error, _} ->
-        {:error, "Error while performing background task"}
-    end
-  end
-
-  def unsuspend_profile(_parent, _args, _resolution) do
-    {:error, "Only moderators and administrators can unsuspend a profile"}
-  end
-
   # We check that the actor is not the last administrator/creator of a group
   @spec last_admin_of_a_group?(integer()) :: boolean()
   defp last_admin_of_a_group?(actor_id) do
diff --git a/lib/graphql/resolvers/post.ex b/lib/graphql/resolvers/post.ex
index 5e1dfa2be..f71da254a 100644
--- a/lib/graphql/resolvers/post.ex
+++ b/lib/graphql/resolvers/post.ex
@@ -3,6 +3,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
   Handles the posts-related GraphQL calls
   """
 
+  import Mobilizon.Users.Guards
   alias Mobilizon.{Actors, Posts, Users}
   alias Mobilizon.Actors.Actor
   alias Mobilizon.Federation.ActivityPub
@@ -24,12 +25,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
         %{page: page, limit: limit} = args,
         %{
           context: %{
-            current_user: %User{} = user
+            current_user: %User{role: user_role} = user
           }
         } = _resolution
       ) do
     with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
-         {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
+         {:member, true} <-
+           {:member, Actors.is_member?(actor_id, group_id) or is_moderator(user_role)},
          %Page{} = page <- Posts.get_posts_for_group(group, page, limit) do
       {:ok, page}
     else
diff --git a/lib/graphql/schema.ex b/lib/graphql/schema.ex
index 545605d73..6b987b7c4 100644
--- a/lib/graphql/schema.ex
+++ b/lib/graphql/schema.ex
@@ -175,6 +175,7 @@ defmodule Mobilizon.GraphQL.Schema do
     import_fields(:discussion_mutations)
     import_fields(:resource_mutations)
     import_fields(:post_mutations)
+    import_fields(:actor_mutations)
   end
 
   @desc """
diff --git a/lib/graphql/schema/actor.ex b/lib/graphql/schema/actor.ex
index 162b9c60a..7e22d3d84 100644
--- a/lib/graphql/schema/actor.ex
+++ b/lib/graphql/schema/actor.ex
@@ -5,6 +5,7 @@ defmodule Mobilizon.GraphQL.Schema.ActorInterface do
   use Absinthe.Schema.Notation
 
   alias Mobilizon.Actors.Actor
+  alias Mobilizon.GraphQL.Resolvers.Actor, as: ActorResolver
   alias Mobilizon.GraphQL.Schema
 
   import_types(Schema.Actors.FollowerType)
@@ -59,4 +60,21 @@ defmodule Mobilizon.GraphQL.Schema.ActorInterface do
     value(:Organization, description: "An ActivityPub Organization")
     value(:Service, description: "An ActivityPub Service")
   end
+
+  object :actor_mutations do
+    field :suspend_profile, :deleted_object do
+      arg(:id, non_null(:id), description: "The profile ID to suspend")
+      resolve(&ActorResolver.suspend_profile/3)
+    end
+
+    field :unsuspend_profile, :actor do
+      arg(:id, non_null(:id), description: "The profile ID to unsuspend")
+      resolve(&ActorResolver.unsuspend_profile/3)
+    end
+
+    field :refresh_profile, :actor do
+      arg(:id, non_null(:id))
+      resolve(&ActorResolver.refresh_profile/3)
+    end
+  end
 end
diff --git a/lib/graphql/schema/actors/group.ex b/lib/graphql/schema/actors/group.ex
index d9685d40c..3a357d46c 100644
--- a/lib/graphql/schema/actors/group.ex
+++ b/lib/graphql/schema/actors/group.ex
@@ -130,11 +130,22 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
   object :group_queries do
     @desc "Get all groups"
     field :groups, :paginated_group_list do
+      arg(:preferred_username, :string, default_value: "")
+      arg(:name, :string, default_value: "")
+      arg(:domain, :string, default_value: "")
+      arg(:local, :boolean, default_value: true)
+      arg(:suspended, :boolean, default_value: false)
       arg(:page, :integer, default_value: 1)
       arg(:limit, :integer, default_value: 10)
       resolve(&Group.list_groups/3)
     end
 
+    @desc "Get a group by its ID"
+    field :get_group, :group do
+      arg(:id, non_null(:id))
+      resolve(&Group.get_group/3)
+    end
+
     @desc "Get a group by its preferred username"
     field :group, :group do
       arg(:preferred_username, non_null(:string))
@@ -199,7 +210,6 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
     @desc "Delete a group"
     field :delete_group, :deleted_object do
       arg(:group_id, non_null(:id))
-      arg(:actor_id, non_null(:id))
 
       resolve(&Group.delete_group/3)
     end
diff --git a/lib/graphql/schema/actors/person.ex b/lib/graphql/schema/actors/person.ex
index 0727a5182..e082f7b2a 100644
--- a/lib/graphql/schema/actors/person.ex
+++ b/lib/graphql/schema/actors/person.ex
@@ -188,16 +188,6 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
 
       resolve(handle_errors(&Person.register_person/3))
     end
-
-    field :suspend_profile, :deleted_object do
-      arg(:id, :id, description: "The profile ID to suspend")
-      resolve(&Person.suspend_profile/3)
-    end
-
-    field :unsuspend_profile, :person do
-      arg(:id, :id, description: "The profile ID to unsuspend")
-      resolve(&Person.unsuspend_profile/3)
-    end
   end
 
   object :person_subscriptions do
diff --git a/lib/graphql/schema/discussions/comment.ex b/lib/graphql/schema/discussions/comment.ex
index d08e1fb27..6103076b0 100644
--- a/lib/graphql/schema/discussions/comment.ex
+++ b/lib/graphql/schema/discussions/comment.ex
@@ -33,6 +33,7 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
     field(:inserted_at, :datetime)
     field(:updated_at, :datetime)
     field(:deleted_at, :datetime)
+    field(:published_at, :datetime)
   end
 
   @desc "The list of visibility options for a comment"
diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex
index 3ba8f7429..3dc37df7f 100644
--- a/lib/mobilizon/actors/actors.ex
+++ b/lib/mobilizon/actors/actors.ex
@@ -13,13 +13,12 @@ defmodule Mobilizon.Actors do
   alias Mobilizon.Actors.{Actor, Bot, Follower, Member}
   alias Mobilizon.Addresses.Address
   alias Mobilizon.{Crypto, Events}
+  alias Mobilizon.Federation.ActivityPub
   alias Mobilizon.Media.File
   alias Mobilizon.Service.Workers
   alias Mobilizon.Storage.{Page, Repo}
   alias Mobilizon.Users
-
-  alias Mobilizon.Federation.ActivityPub
-
+  alias Mobilizon.Web.Email.Group
   alias Mobilizon.Web.Upload
 
   require Logger
@@ -249,23 +248,19 @@ defmodule Mobilizon.Actors do
   """
   @spec upsert_actor(map, boolean) :: {:ok, Actor.t()} | {:error, Ecto.Changeset.t()}
   def upsert_actor(
-        %{keys: keys, name: name, summary: summary, avatar: avatar, banner: banner} = data,
+        data,
         preload \\ false
       ) do
+    # data =
+    #   data
+    #   |> Map.put(:avatar, transform_media_file(data.avatar))
+    #   |> Map.put(:banner, transform_media_file(data.banner))
+
     insert =
       data
       |> Actor.remote_actor_creation_changeset()
       |> Repo.insert(
-        on_conflict: [
-          set: [
-            keys: keys,
-            name: name,
-            summary: summary,
-            avatar: transform_media_file(avatar),
-            banner: transform_media_file(banner),
-            last_refreshed_at: DateTime.utc_now()
-          ]
-        ],
+        on_conflict: {:replace_all_except, [:id, :url, :preferred_username, :domain]},
         conflict_target: [:url]
       )
 
@@ -282,26 +277,28 @@ defmodule Mobilizon.Actors do
     end
   end
 
-  defp transform_media_file(nil), do: nil
+  # defp transform_media_file(nil), do: nil
 
-  defp transform_media_file(file) do
-    file = for({key, val} <- file, into: %{}, do: {String.to_atom(key), val})
+  # defp transform_media_file(file) do
+  #   file = for({key, val} <- file, into: %{}, do: {String.to_atom(key), val})
 
-    if is_nil(file) do
-      nil
-    else
-      struct(Mobilizon.Media.File, file)
-    end
-  end
+  #   if is_nil(file) do
+  #     nil
+  #   else
+  #     struct(Mobilizon.Media.File, file)
+  #   end
+  # end
 
-  @delete_actor_default_options [reserve_username: true]
+  @delete_actor_default_options [reserve_username: true, suspension: false]
 
   def delete_actor(%Actor{} = actor, options \\ @delete_actor_default_options) do
     delete_actor_options = Keyword.merge(@delete_actor_default_options, options)
 
     Workers.Background.enqueue("delete_actor", %{
       "actor_id" => actor.id,
-      "reserve_username" => Keyword.get(delete_actor_options, :reserve_username, true)
+      "author_id" => Keyword.get(delete_actor_options, :author_id),
+      "reserve_username" => Keyword.get(delete_actor_options, :reserve_username, true),
+      "suspension" => Keyword.get(delete_actor_options, :suspension, false)
     })
   end
 
@@ -309,11 +306,16 @@ defmodule Mobilizon.Actors do
   Deletes an actor.
   """
   @spec perform(atom(), Actor.t()) :: {:ok, Actor.t()} | {:error, Ecto.Changeset.t()}
-  def perform(:delete_actor, %Actor{} = actor, options \\ @delete_actor_default_options) do
+  def perform(:delete_actor, %Actor{type: type} = actor, options \\ @delete_actor_default_options) do
     Logger.info("Going to delete actor #{actor.url}")
     actor = Repo.preload(actor, @actor_preloads)
 
     delete_actor_options = Keyword.merge(@delete_actor_default_options, options)
+    Logger.debug(inspect(delete_actor_options))
+
+    if type == :Group do
+      delete_eventual_local_members(actor, delete_actor_options)
+    end
 
     multi =
       Multi.new()
@@ -322,6 +324,31 @@ defmodule Mobilizon.Actors do
       |> Multi.run(:remove_banner, fn _, _ -> remove_banner(actor) end)
       |> Multi.run(:remove_avatar, fn _, _ -> remove_avatar(actor) end)
 
+    multi =
+      if type == :Group do
+        multi
+        |> Multi.run(:delete_remote_members, fn _, _ ->
+          delete_group_elements(actor, :remote_members)
+        end)
+        |> Multi.run(:delete_group_organized_events, fn _, _ ->
+          delete_group_elements(actor, :events)
+        end)
+        |> Multi.run(:delete_group_posts, fn _, _ ->
+          delete_group_elements(actor, :posts)
+        end)
+        |> Multi.run(:delete_group_resources, fn _, _ ->
+          delete_group_elements(actor, :resources)
+        end)
+        |> Multi.run(:delete_group_todo_lists, fn _, _ ->
+          delete_group_elements(actor, :todo_lists)
+        end)
+        |> Multi.run(:delete_group_discussions, fn _, _ ->
+          delete_group_elements(actor, :discussions)
+        end)
+      else
+        multi
+      end
+
     multi =
       if Keyword.get(delete_actor_options, :reserve_username, true) do
         Multi.update(multi, :actor, Actor.delete_changeset(actor))
@@ -329,6 +356,8 @@ defmodule Mobilizon.Actors do
         Multi.delete(multi, :actor, actor)
       end
 
+    Logger.debug("Going to run the transaction")
+
     case Repo.transaction(multi) do
       {:ok, %{actor: %Actor{} = actor}} ->
         {:ok, true} = Cachex.del(:activity_pub, "actor_#{actor.preferred_username}")
@@ -357,7 +386,16 @@ defmodule Mobilizon.Actors do
   @doc """
   Returns the list of actors.
   """
-  @spec list_actors(String.t(), String.t(), boolean, boolean, integer, integer) :: Page.t()
+  @spec list_actors(
+          atom(),
+          String.t(),
+          String.t(),
+          String.t(),
+          boolean,
+          boolean,
+          integer,
+          integer
+        ) :: Page.t()
   def list_actors(
         type \\ :Person,
         preferred_username \\ "",
@@ -380,12 +418,41 @@ defmodule Mobilizon.Actors do
         limit
       ) do
     person_query()
+    |> filter_actors(preferred_username, name, domain, local, suspended)
+    |> Page.build_page(page, limit)
+  end
+
+  def list_actors(
+        :Group,
+        preferred_username,
+        name,
+        domain,
+        local,
+        suspended,
+        page,
+        limit
+      ) do
+    group_query()
+    |> filter_actors(preferred_username, name, domain, local, suspended)
+    |> Page.build_page(page, limit)
+  end
+
+  @spec filter_actors(Ecto.Query.t(), String.t(), String.t(), String.t(), boolean(), boolean()) ::
+          Ecto.Query.t()
+  defp filter_actors(
+         query,
+         preferred_username,
+         name,
+         domain,
+         local,
+         suspended
+       ) do
+    query
     |> filter_suspended(suspended)
     |> filter_preferred_username(preferred_username)
     |> filter_name(name)
     |> filter_domain(domain)
     |> filter_remote(local)
-    |> Page.build_page(page, limit)
   end
 
   defp filter_preferred_username(query, ""), do: query
@@ -406,6 +473,7 @@ defmodule Mobilizon.Actors do
   defp filter_remote(query, true), do: filter_local(query)
   defp filter_remote(query, false), do: filter_external(query)
 
+  @spec filter_suspended(Ecto.Query.t(), boolean()) :: Ecto.Query.t()
   defp filter_suspended(query, true), do: where(query, [a], a.suspended)
   defp filter_suspended(query, false), do: where(query, [a], not a.suspended)
 
@@ -440,6 +508,7 @@ defmodule Mobilizon.Actors do
     |> actor_by_username_or_name_query(term)
     |> actors_for_location(args)
     |> filter_by_types(types)
+    |> filter_suspended(false)
     |> Page.build_page(page, limit)
   end
 
@@ -492,6 +561,13 @@ defmodule Mobilizon.Actors do
     |> Repo.one()
   end
 
+  @spec get_group_by_followers_url(String.t()) :: Actor.t()
+  def get_group_by_followers_url(followers_url) do
+    group_query()
+    |> where([q], q.followers_url == ^followers_url)
+    |> Repo.one()
+  end
+
   @doc """
   Creates a group.
 
@@ -702,6 +778,28 @@ defmodule Mobilizon.Actors do
     |> Page.build_page(page, limit)
   end
 
+  @spec list_local_members_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  def list_local_members_for_group(
+        %Actor{id: group_id, type: :Group} = _group,
+        page \\ nil,
+        limit \\ nil
+      ) do
+    group_id
+    |> group_internal_member_query()
+    |> Page.build_page(page, limit)
+  end
+
+  @spec list_remote_members_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  def list_remote_members_for_group(
+        %Actor{id: group_id, type: :Group} = _group,
+        page \\ nil,
+        limit \\ nil
+      ) do
+    group_id
+    |> group_external_member_query()
+    |> Page.build_page(page, limit)
+  end
+
   @doc """
   Returns the list of members for a group.
   """
@@ -1283,6 +1381,26 @@ defmodule Mobilizon.Actors do
     |> select([_m, a], a)
   end
 
+  @spec group_external_member_query(integer()) :: Ecto.Query.t()
+  defp group_external_member_query(group_id) do
+    Member
+    |> where([m], m.parent_id == ^group_id)
+    |> join(:inner, [m], a in Actor, on: m.actor_id == a.id)
+    |> where([_m, a], not is_nil(a.domain))
+    |> preload([m], [:parent, :actor])
+    |> select([m, _a], m)
+  end
+
+  @spec group_internal_member_query(integer()) :: Ecto.Query.t()
+  defp group_internal_member_query(group_id) do
+    Member
+    |> where([m], m.parent_id == ^group_id)
+    |> join(:inner, [m], a in Actor, on: m.actor_id == a.id)
+    |> where([_m, a], is_nil(a.domain))
+    |> preload([m], [:parent, :actor])
+    |> select([m, _a], m)
+  end
+
   @spec filter_member_role(Ecto.Query.t(), list(atom()) | atom()) :: Ecto.Query.t()
   def filter_member_role(query, []), do: query
 
@@ -1497,4 +1615,72 @@ defmodule Mobilizon.Actors do
       {:error, res}
     end
   end
+
+  defp delete_group_elements(%Actor{type: :Group} = actor, type) do
+    Logger.debug("delete_group_elements #{inspect(type)}")
+
+    method =
+      case type do
+        :remote_members -> &list_remote_members_for_group/3
+        :events -> &Events.list_organized_events_for_group/3
+        :posts -> &Mobilizon.Posts.get_posts_for_group/3
+        :resources -> &Mobilizon.Resources.get_resources_for_group/3
+        :todo_lists -> &Mobilizon.Todos.get_todo_lists_for_group/3
+        :discussions -> &Mobilizon.Discussions.find_discussions_for_actor/3
+      end
+
+    res =
+      actor
+      |> accumulate_paginated_elements(method)
+      |> Enum.map(fn element -> ActivityPub.delete(element, actor, false) end)
+
+    if Enum.all?(res, fn {status, _, _} -> status == :ok end) do
+      Logger.debug("Return OK for all #{to_string(type)}")
+      {:ok, res}
+    else
+      Logger.debug("Something failed #{inspect(res)}")
+      {:error, res}
+    end
+  end
+
+  defp accumulate_paginated_elements(
+         %Actor{} = actor,
+         method,
+         elements \\ [],
+         page \\ 1,
+         limit \\ 10
+       ) do
+    Logger.debug("accumulate_paginated_elements")
+    %Page{total: total, elements: new_elements} = page = method.(actor, page, limit)
+    elements = elements ++ new_elements
+    count = length(elements)
+
+    if count < total do
+      accumulate_paginated_elements(actor, method, elements, page + 1, limit)
+    else
+      Logger.debug("Found #{count} group elements to delete")
+      elements
+    end
+  end
+
+  # This one is not in the Multi transaction because it sends activities
+  defp delete_eventual_local_members(%Actor{} = group, options) do
+    suspended? = Keyword.get(options, :suspension, false)
+
+    group
+    |> accumulate_paginated_elements(&list_local_members_for_group/3)
+    |> Enum.map(fn member ->
+      if suspended? do
+        Group.send_group_suspension_notification(member)
+      else
+        with author_id when not is_nil(author_id) <- Keyword.get(options, :author_id),
+             %Actor{} = author <- get_actor(author_id) do
+          Group.send_group_deletion_notification(member, author)
+        end
+      end
+
+      member
+    end)
+    |> Enum.map(fn member -> ActivityPub.delete(member, group, false) end)
+  end
 end
diff --git a/lib/mobilizon/discussions/discussions.ex b/lib/mobilizon/discussions/discussions.ex
index 7d9bc97e2..cfc79d7e5 100644
--- a/lib/mobilizon/discussions/discussions.ex
+++ b/lib/mobilizon/discussions/discussions.ex
@@ -94,6 +94,7 @@ defmodule Mobilizon.Discussions do
   @spec get_comment!(integer | String.t()) :: Comment.t()
   def get_comment!(id), do: Repo.get!(Comment, id)
 
+  @spec get_comment_with_preload(String.t() | integer() | nil) :: Comment.t() | nil
   def get_comment_with_preload(nil), do: nil
 
   def get_comment_with_preload(id) do
@@ -214,11 +215,20 @@ defmodule Mobilizon.Discussions do
 
   But actually just empty the fields so that threads are not broken.
   """
-  @spec delete_comment(Comment.t()) :: {:ok, Comment.t()} | {:error, Changeset.t()}
-  def delete_comment(%Comment{} = comment) do
-    comment
-    |> Comment.delete_changeset()
-    |> Repo.update()
+  @spec delete_comment(Comment.t(), Keyword.t()) :: {:ok, Comment.t()} | {:error, Changeset.t()}
+  def delete_comment(%Comment{} = comment, options \\ []) do
+    if Keyword.get(options, :force, false) == false do
+      with {:ok, %Comment{} = comment} <-
+             comment
+             |> Comment.delete_changeset()
+             |> Repo.update(),
+           %Comment{} = comment <- get_comment_with_preload(comment.id) do
+        {:ok, comment}
+      end
+    else
+      comment
+      |> Repo.delete()
+    end
   end
 
   @doc """
@@ -289,8 +299,8 @@ defmodule Mobilizon.Discussions do
     |> Repo.preload(@discussion_preloads)
   end
 
-  @spec find_discussions_for_actor(integer, integer | nil, integer | nil) :: Page.t()
-  def find_discussions_for_actor(actor_id, page \\ nil, limit \\ nil) do
+  @spec find_discussions_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  def find_discussions_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do
     Discussion
     |> where([c], c.actor_id == ^actor_id)
     |> preload(^@discussion_preloads)
@@ -372,9 +382,13 @@ defmodule Mobilizon.Discussions do
   Delete a discussion.
   """
   @spec delete_discussion(Discussion.t()) :: {:ok, Discussion.t()} | {:error, Changeset.t()}
-  def delete_discussion(%Discussion{} = discussion) do
-    discussion
-    |> Repo.delete()
+  def delete_discussion(%Discussion{id: discussion_id}) do
+    Multi.new()
+    |> Multi.delete_all(:comments, fn _ ->
+      where(Comment, [c], c.discussion_id == ^discussion_id)
+    end)
+    # |> Multi.delete(:discussion, discussion)
+    |> Repo.transaction()
   end
 
   defp public_comments_for_actor_query(actor_id) do
@@ -402,7 +416,4 @@ defmodule Mobilizon.Discussions do
 
   @spec preload_for_comment(Ecto.Query.t()) :: Ecto.Query.t()
   defp preload_for_comment(query), do: preload(query, ^@comment_preloads)
-
-  #  @spec preload_for_discussion(Ecto.Query.t()) :: Ecto.Query.t()
-  #  defp preload_for_discussion(query), do: preload(query, ^@discussion_preloads)
 end
diff --git a/lib/mobilizon/posts/posts.ex b/lib/mobilizon/posts/posts.ex
index 7d1a7d179..da9189b16 100644
--- a/lib/mobilizon/posts/posts.ex
+++ b/lib/mobilizon/posts/posts.ex
@@ -46,13 +46,6 @@ defmodule Mobilizon.Posts do
     |> Page.build_page(page, limit)
   end
 
-  def do_get_posts_for_group(group_id) do
-    Post
-    |> where(attributed_to_id: ^group_id)
-    |> order_by(desc: :inserted_at)
-    |> preload([p], [:author, :attributed_to, :picture])
-  end
-
   @doc """
   Get a post by it's ID
   """
@@ -144,4 +137,11 @@ defmodule Mobilizon.Posts do
   defp filter_public(query) do
     where(query, [p], p.visibility == ^:public and not p.draft)
   end
+
+  defp do_get_posts_for_group(group_id) do
+    Post
+    |> where(attributed_to_id: ^group_id)
+    |> order_by(desc: :inserted_at)
+    |> preload([p], [:author, :attributed_to, :picture])
+  end
 end
diff --git a/lib/mobilizon/tombstone.ex b/lib/mobilizon/tombstone.ex
index 864228cca..85e8ff9a5 100644
--- a/lib/mobilizon/tombstone.ex
+++ b/lib/mobilizon/tombstone.ex
@@ -7,6 +7,7 @@ defmodule Mobilizon.Tombstone do
   import Ecto.Changeset
   alias Mobilizon.Actors.Actor
   alias Mobilizon.Storage.Repo
+  require Ecto.Query
 
   @type t :: %__MODULE__{
           uri: String.t(),
@@ -42,4 +43,17 @@ defmodule Mobilizon.Tombstone do
   def find_tombstone(uri) do
     Repo.get_by(__MODULE__, uri: uri)
   end
+
+  @spec delete_actor_tombstones(String.t() | integer()) :: {integer(), nil}
+  def delete_actor_tombstones(actorId) do
+    __MODULE__
+    |> Ecto.Query.where(actor_id: ^actorId)
+    |> Repo.delete_all()
+  end
+
+  def delete_uri_tombstone(uri) do
+    __MODULE__
+    |> Ecto.Query.where(uri: ^uri)
+    |> Repo.delete_all()
+  end
 end
diff --git a/lib/web/email/group.ex b/lib/web/email/group.ex
index 7e0e612e5..f81044d62 100644
--- a/lib/web/email/group.ex
+++ b/lib/web/email/group.ex
@@ -7,7 +7,7 @@ defmodule Mobilizon.Web.Email.Group do
   import Bamboo.Phoenix
   import Mobilizon.Web.Gettext
 
-  alias Mobilizon.{Actors, Users}
+  alias Mobilizon.{Actors, Config, Users}
   alias Mobilizon.Actors.{Actor, Member}
   alias Mobilizon.Users.User
   alias Mobilizon.Web.{Email, Gettext}
@@ -68,7 +68,7 @@ defmodule Mobilizon.Web.Email.Group do
       |> assign(:locale, locale)
       |> assign(:group, group)
       |> assign(:subject, subject)
-      |> render(:group_removal)
+      |> render(:group_member_removal)
       |> Email.Mailer.deliver_later()
 
       :ok
@@ -76,4 +76,83 @@ defmodule Mobilizon.Web.Email.Group do
   end
 
   # TODO : def send_confirmation_to_inviter()
+
+  @member_roles [:administrator, :moderator, :member]
+  def send_group_suspension_notification(%Member{actor: %Actor{user_id: nil}}), do: :ok
+
+  def send_group_suspension_notification(%Member{role: role}) when role not in @member_roles,
+    do: :ok
+
+  def send_group_suspension_notification(%Member{
+        actor: %Actor{user_id: user_id},
+        parent: %Actor{domain: nil} = group,
+        role: member_role
+      }) do
+    with %User{email: email, locale: locale} <- Users.get_user!(user_id) do
+      Gettext.put_locale(locale)
+      instance = Config.instance_name()
+
+      subject =
+        gettext(
+          "The group %{group} has been suspended on %{instance}",
+          group: group.name,
+          instance: instance
+        )
+
+      Email.base_email(to: email, subject: subject)
+      |> assign(:locale, locale)
+      |> assign(:group, group)
+      |> assign(:role, member_role)
+      |> assign(:subject, subject)
+      |> assign(:instance, instance)
+      |> render(:group_suspension)
+      |> Email.Mailer.deliver_later()
+
+      :ok
+    end
+  end
+
+  def send_group_deletion_notification(%Member{actor: %Actor{user_id: nil}}, _author), do: :ok
+
+  def send_group_deletion_notification(%Member{role: role}, _author)
+      when role not in @member_roles,
+      do: :ok
+
+  def send_group_deletion_notification(
+        %Member{
+          actor: %Actor{user_id: user_id, id: actor_id},
+          parent: %Actor{domain: nil} = group,
+          role: member_role
+        },
+        %Actor{id: author_id} = author
+      ) do
+    with %User{email: email, locale: locale} <- Users.get_user!(user_id),
+         {:member_not_author, true} <- {:member_not_author, author_id !== actor_id} do
+      Gettext.put_locale(locale)
+      instance = Config.instance_name()
+
+      subject =
+        gettext(
+          "The group %{group} has been deleted on %{instance}",
+          group: group.name,
+          instance: instance
+        )
+
+      Email.base_email(to: email, subject: subject)
+      |> assign(:locale, locale)
+      |> assign(:group, group)
+      |> assign(:role, member_role)
+      |> assign(:subject, subject)
+      |> assign(:instance, instance)
+      |> assign(:author, author)
+      |> render(:group_deletion)
+      |> Email.Mailer.deliver_later()
+
+      :ok
+    else
+      # Skip if it's the author itself
+      {:member_not_author, _} ->
+        :ok
+    end
+  end
 end
diff --git a/lib/web/templates/email/group_deletion.html.eex b/lib/web/templates/email/group_deletion.html.eex
new file mode 100644
index 000000000..da88eff37
--- /dev/null
+++ b/lib/web/templates/email/group_deletion.html.eex
@@ -0,0 +1,51 @@
+<!-- HERO -->
+<tr>
+  <td bgcolor="#474467" align="center" style="padding: 0px 10px 0px 10px;">
+    <!--[if (gte mso 9)|(IE)]>
+      <table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
+        <tr>
+          <td align="center" valign="top" width="600">
+    <![endif]-->
+    <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
+      <tr>
+        <td bgcolor="#ffffff" align="center" valign="top" style="padding: 40px 20px 20px 20px; border-radius: 4px 4px 0px 0px; color: #3A384C; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 48px; font-weight: 400; line-height: 48px;">
+          <h1 style="font-size: 48px; font-weight: 400; margin: 0;">
+            <%= gettext "The group %{group} was deleted on %{instance}!", group: (@group.name || @group.preferred_username), instance: @instance %>
+          </h1>
+        </td>
+      </tr>
+    </table>
+    <!--[if (gte mso 9)|(IE)]>
+    </td>
+  </tr>
+</table>
+    <![endif]-->
+  </td>
+</tr>
+<!-- COPY BLOCK -->
+<tr>
+  <td bgcolor="#E6E4F4" align="center" style="padding: 0px 10px 0px 10px;">
+    <!--[if (gte mso 9)|(IE)]>
+      <table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
+        <tr>
+          <td align="center" valign="top" width="600">
+    <![endif]-->
+    <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
+      <!-- COPY -->
+      <tr>
+        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 0px 30px; color: #474467; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;" >
+          <p style="margin: 0;">
+            <%= gettext "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted.",
+  author: Mobilizon.Actors.Actor.display_name_and_username(@author),
+  group: Mobilizon.Actors.Actor.display_name_and_username(@group) %>
+          </p>
+        </td>
+      </tr>
+    </table>
+    <!--[if (gte mso 9)|(IE)]>
+    </td>
+  </tr>
+</table>
+    <![endif]-->
+  </td>
+</tr>
diff --git a/lib/web/templates/email/group_deletion.text.eex b/lib/web/templates/email/group_deletion.text.eex
new file mode 100644
index 000000000..511cd64b9
--- /dev/null
+++ b/lib/web/templates/email/group_deletion.text.eex
@@ -0,0 +1,5 @@
+<%= gettext "The group %{group} was deleted on %{instance}!", group: (@group.name || @group.preferred_username), instance: @instance %>
+==
+<%= gettext "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted.",
+  author: Mobilizon.Actors.Actor.display_name_and_username(@author),
+  group: Mobilizon.Actors.Actor.display_name_and_username(@group) %>
diff --git a/lib/web/templates/email/group_removal.html.eex b/lib/web/templates/email/group_member_removal.html.eex
similarity index 100%
rename from lib/web/templates/email/group_removal.html.eex
rename to lib/web/templates/email/group_member_removal.html.eex
diff --git a/lib/web/templates/email/group_removal.text.eex b/lib/web/templates/email/group_member_removal.text.eex
similarity index 100%
rename from lib/web/templates/email/group_removal.text.eex
rename to lib/web/templates/email/group_member_removal.text.eex
diff --git a/lib/web/templates/email/group_suspension.html.eex b/lib/web/templates/email/group_suspension.html.eex
new file mode 100644
index 000000000..1780fe19b
--- /dev/null
+++ b/lib/web/templates/email/group_suspension.html.eex
@@ -0,0 +1,66 @@
+<!-- HERO -->
+<tr>
+  <td bgcolor="#474467" align="center" style="padding: 0px 10px 0px 10px;">
+    <!--[if (gte mso 9)|(IE)]>
+      <table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
+        <tr>
+          <td align="center" valign="top" width="600">
+    <![endif]-->
+    <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
+      <tr>
+        <td bgcolor="#ffffff" align="center" valign="top" style="padding: 40px 20px 20px 20px; border-radius: 4px 4px 0px 0px; color: #3A384C; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 48px; font-weight: 400; line-height: 48px;">
+          <h1 style="font-size: 48px; font-weight: 400; margin: 0;">
+            <%= gettext "The group %{group} has been suspended on %{instance}!", group: (@group.name || @group.preferred_username), instance: @instance %>
+          </h1>
+        </td>
+      </tr>
+    </table>
+    <!--[if (gte mso 9)|(IE)]>
+    </td>
+  </tr>
+</table>
+    <![endif]-->
+  </td>
+</tr>
+<!-- COPY BLOCK -->
+<tr>
+  <td bgcolor="#E6E4F4" align="center" style="padding: 0px 10px 0px 10px;">
+    <!--[if (gte mso 9)|(IE)]>
+      <table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
+        <tr>
+          <td align="center" valign="top" width="600">
+    <![endif]-->
+    <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
+      <!-- COPY -->
+      <tr>
+        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 0px 30px; color: #474467; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;" >
+          <p style="margin: 0;">
+            <%= gettext "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group.", group_name: @group.name, group_address: if @group.domain, do: "@#{@group.preferred_username}@#{@group.domain}", else: "@#{@group.preferred_username}" %>
+          </p>
+        </td>
+      </tr>
+      <%= if is_nil(@group.domain) do %>
+        <tr>
+          <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #474467; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;" >
+            <p style="margin: 0">
+              <%= gettext "As this group was located on this instance, all of it's data has been irretrievably deleted." %>
+            </p>
+          </td>
+        </tr>
+      <% else %>
+        <tr>
+          <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #474467; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;" >
+            <p style="margin: 0">
+              <%= gettext "As this group was located on another instance, it will continue to work for other instances than this one." %>
+            </p>
+          </td>
+        </tr>
+      <% end %>
+    </table>
+    <!--[if (gte mso 9)|(IE)]>
+    </td>
+  </tr>
+</table>
+    <![endif]-->
+  </td>
+</tr>
diff --git a/lib/web/templates/email/group_suspension.text.eex b/lib/web/templates/email/group_suspension.text.eex
new file mode 100644
index 000000000..02b870c65
--- /dev/null
+++ b/lib/web/templates/email/group_suspension.text.eex
@@ -0,0 +1,8 @@
+<%= gettext "The group %{group} has been suspended on %{instance}!", group: (@group.name || @group.preferred_username), instance: @instance %>
+==
+<%= gettext "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group.", group_name: @group.name, group_address: if @group.domain, do: "@#{@group.preferred_username}@#{@group.domain}", else: "@#{@group.preferred_username}" %>
+<%= if is_nil(@group.domain) do %>
+  <%= gettext "As this group was located on this instance, all of it's data has been irretrievably deleted." %>
+<% else %>
+  <%= gettext "As this group was located on another instance, it will continue to work for other instances than this one." %>
+<% end %>
diff --git a/lib/web/views/activity_pub/actor_view.ex b/lib/web/views/activity_pub/actor_view.ex
index 5e536dd7d..23f9913f9 100644
--- a/lib/web/views/activity_pub/actor_view.ex
+++ b/lib/web/views/activity_pub/actor_view.ex
@@ -88,7 +88,7 @@ defmodule Mobilizon.Web.ActivityPub.ActorView do
   end
 
   defp fetch_collection(:discussions, actor, page) do
-    Discussions.find_discussions_for_actor(actor.id, page)
+    Discussions.find_discussions_for_actor(actor, page)
   end
 
   defp fetch_collection(:posts, actor, page) do
diff --git a/priv/gettext/ar/LC_MESSAGES/default.po b/priv/gettext/ar/LC_MESSAGES/default.po
index b75bd2789..984eba998 100644
--- a/priv/gettext/ar/LC_MESSAGES/default.po
+++ b/priv/gettext/ar/LC_MESSAGES/default.po
@@ -407,7 +407,7 @@ msgid "View the event on: %{link}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1209,33 +1209,79 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/be/LC_MESSAGES/default.po b/priv/gettext/be/LC_MESSAGES/default.po
index 5f46370f3..14194ac4f 100644
--- a/priv/gettext/be/LC_MESSAGES/default.po
+++ b/priv/gettext/be/LC_MESSAGES/default.po
@@ -398,7 +398,7 @@ msgid "View the event on: %{link}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1185,33 +1185,79 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/ca/LC_MESSAGES/default.po b/priv/gettext/ca/LC_MESSAGES/default.po
index 6ae497612..f0545e112 100644
--- a/priv/gettext/ca/LC_MESSAGES/default.po
+++ b/priv/gettext/ca/LC_MESSAGES/default.po
@@ -406,7 +406,7 @@ msgid "View the event on: %{link}"
 msgstr "Vés a l'activitat actualitzada a %{link}"
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1205,33 +1205,79 @@ msgstr ""
 "meitat del 2020%{b_end}."
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/cs/LC_MESSAGES/default.po b/priv/gettext/cs/LC_MESSAGES/default.po
index e2da5e95e..747564b33 100644
--- a/priv/gettext/cs/LC_MESSAGES/default.po
+++ b/priv/gettext/cs/LC_MESSAGES/default.po
@@ -398,7 +398,7 @@ msgid "View the event on: %{link}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1185,33 +1185,79 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/de/LC_MESSAGES/default.po b/priv/gettext/de/LC_MESSAGES/default.po
index bba277290..2cf0416b4 100644
--- a/priv/gettext/de/LC_MESSAGES/default.po
+++ b/priv/gettext/de/LC_MESSAGES/default.po
@@ -411,7 +411,7 @@ msgid "View the event on: %{link}"
 msgstr "Zeige die aktualisierte Veranstaltung unter: %{link}"
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1213,33 +1213,79 @@ msgstr ""
 "in der ersten Hälfte von 2020 veröffentlicht wird</b>."
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot
index dff42d3b3..8550be01c 100644
--- a/priv/gettext/default.pot
+++ b/priv/gettext/default.pot
@@ -382,7 +382,7 @@ msgid "View the event on: %{link}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1164,24 +1164,24 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
@@ -1191,6 +1191,52 @@ msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:38
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po
index da9316bb9..a03c74f1b 100644
--- a/priv/gettext/en/LC_MESSAGES/default.po
+++ b/priv/gettext/en/LC_MESSAGES/default.po
@@ -405,7 +405,7 @@ msgid "View the event on: %{link}"
 msgstr "View the updated event on: %{link}"
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1187,33 +1187,79 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr "Mobilizon is under development, we will add new features to this site during regular updates, until the release of version 1 of the software in the first half of 2020."
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/es/LC_MESSAGES/default.po b/priv/gettext/es/LC_MESSAGES/default.po
index 39e9c2362..41adb1f14 100644
--- a/priv/gettext/es/LC_MESSAGES/default.po
+++ b/priv/gettext/es/LC_MESSAGES/default.po
@@ -14,293 +14,293 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
 "X-Generator: Weblate 4.1\n"
 
-#: lib/web/templates/email/password_reset.html.eex:48
 #, elixir-format
+#: lib/web/templates/email/password_reset.html.eex:48
 msgid "If you didn't request this, please ignore this email. Your password won't change until you access the link below and create a new one."
 msgstr ""
 "Si no solicitaste este correo, simplemente ignóralo. Su contraseña no "
 "cambiará al menos que use el siguiente enlace para crear una nueva."
 
-#: lib/service/export/feed.ex:170
 #, elixir-format
+#: lib/service/export/feed.ex:170
 msgid "Feed for %{email} on Mobilizon"
 msgstr "Feed para% {email} en Mobilizon"
 
-#: lib/web/templates/email/report.html.eex:52
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:52
 msgid "%{title} by %{creator}"
 msgstr "%{title} por %{creator}"
 
-#: lib/web/templates/email/registration_confirmation.html.eex:58
 #, elixir-format
+#: lib/web/templates/email/registration_confirmation.html.eex:58
 msgid "Activate my account"
 msgstr "Activar mi cuenta"
 
+#, elixir-format
 #: lib/web/templates/email/email.html.eex:121
 #: lib/web/templates/email/email.text.eex:14
-#, elixir-format
 msgid "Ask the community on Framacolibri"
 msgstr "Preguntar a la comunidad en framacolibri"
 
-#: lib/web/templates/email/report.text.eex:8
 #, elixir-format
+#: lib/web/templates/email/report.text.eex:8
 msgid "Comments"
 msgstr "Comentarios"
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:62
 #: lib/web/templates/email/report.html.eex:50 lib/web/templates/email/report.text.eex:4
-#, elixir-format
 msgid "Event"
 msgstr "Evento"
 
-#: lib/web/email/user.ex:48
 #, elixir-format
+#: lib/web/email/user.ex:48
 msgid "Instructions to reset your password on %{instance}"
 msgstr "Instrucciones para restablecer su contraseña en %{instance}"
 
-#: lib/web/templates/email/report.text.eex:14
 #, elixir-format
+#: lib/web/templates/email/report.text.eex:14
 msgid "Reason"
 msgstr "Razón"
 
-#: lib/web/templates/email/password_reset.html.eex:61
 #, elixir-format
+#: lib/web/templates/email/password_reset.html.eex:61
 msgid "Reset Password"
 msgstr "Reinicializar la contraseña"
 
-#: lib/web/templates/email/password_reset.html.eex:41
 #, elixir-format
+#: lib/web/templates/email/password_reset.html.eex:41
 msgid "Resetting your password is easy. Just press the button below and follow the instructions. We'll have you up and running in no time."
 msgstr ""
 "Restablecer tu contraseña es fácil. Simplemente presione el botón y siga las "
 "instrucciones. Te tendremos en funcionamiento en poco tiempo."
 
-#: lib/web/email/user.ex:28
 #, elixir-format
+#: lib/web/email/user.ex:28
 msgid "Instructions to confirm your Mobilizon account on %{instance}"
 msgstr "Instrucciones para confirmar su cuenta Mobilizon en %{instance}"
 
-#: lib/web/email/admin.ex:23
 #, elixir-format
+#: lib/web/email/admin.ex:23
 msgid "New report on Mobilizon instance %{instance}"
 msgstr "Nuevo informe sobre la instancia Mobilizon %{instance}"
 
+#, elixir-format
 #: lib/web/templates/email/before_event_notification.html.eex:51
 #: lib/web/templates/email/before_event_notification.text.eex:4
-#, elixir-format
 msgid "Go to event page"
 msgstr "Ir a la página del evento"
 
-#: lib/web/templates/email/report.text.eex:1
 #, elixir-format
+#: lib/web/templates/email/report.text.eex:1
 msgid "New report from %{reporter} on %{instance}"
 msgstr "Nuevo informe de %{reporter} en %{instance}"
 
-#: lib/web/templates/email/event_participation_approved.text.eex:1
 #, elixir-format
+#: lib/web/templates/email/event_participation_approved.text.eex:1
 msgid "Participation approved"
 msgstr "Participación aprobada"
 
+#, elixir-format
 #: lib/web/templates/email/password_reset.html.eex:13
 #: lib/web/templates/email/password_reset.text.eex:1
-#, elixir-format
 msgid "Password reset"
 msgstr "Restablecer contraseña"
 
-#: lib/web/templates/email/password_reset.text.eex:7
 #, elixir-format
+#: lib/web/templates/email/password_reset.text.eex:7
 msgid "Resetting your password is easy. Just click the link below and follow the instructions. We'll have you up and running in no time."
 msgstr ""
 "Restablecer tu contraseña es fácil. Simplemente haga clic en el enlace a "
 "continuación y siga las instrucciones. Estarás operacional en muy poco "
 "tiempo."
 
-#: lib/web/templates/email/registration_confirmation.text.eex:5
 #, elixir-format
+#: lib/web/templates/email/registration_confirmation.text.eex:5
 msgid "You created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email."
 msgstr ""
 "Has creado una cuenta en %{host} con esta dirección de correo electrónico. "
 "Estás a un clic de activarlo. Si no eras tú, ignora este correo electrónico."
 
-#: lib/web/email/participation.ex:92
 #, elixir-format
+#: lib/web/email/participation.ex:92
 msgid "Your participation to event %{title} has been approved"
 msgstr "Su participación en el evento %{title} ha sido aprobada"
 
-#: lib/web/email/participation.ex:71
 #, elixir-format
+#: lib/web/email/participation.ex:71
 msgid "Your participation to event %{title} has been rejected"
 msgstr "Su participación en el evento %{title} ha sido rechazada"
 
-#: lib/web/email/event.ex:35
 #, elixir-format
+#: lib/web/email/event.ex:35
 msgid "Event %{title} has been updated"
 msgstr "El evento %{title} ha sido actualizado"
 
-#: lib/web/templates/email/event_updated.text.eex:15
 #, elixir-format
+#: lib/web/templates/email/event_updated.text.eex:15
 msgid "New title: %{title}"
 msgstr "Nuevo título: %{title}"
 
-#: lib/web/templates/email/password_reset.text.eex:5
 #, elixir-format
+#: lib/web/templates/email/password_reset.text.eex:5
 msgid "You requested a new password for your account on %{instance}."
 msgstr "Solicitó una nueva contraseña para su cuenta en %{instancia}."
 
+#, elixir-format
 #: lib/web/templates/email/email.html.eex:88
 #: lib/web/templates/email/email.text.eex:6
-#, elixir-format
 msgid "This is a demonstration site to test the beta version of Mobilizon."
 msgstr ""
 "Este es un sitio de demostración para probar la versión beta de Mobilizon."
 
-#: lib/web/templates/email/email.html.eex:85
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:85
 msgid "Warning"
 msgstr "Advertencia"
 
-#: lib/web/email/participation.ex:114
 #, elixir-format
+#: lib/web/email/participation.ex:114
 msgid "Confirm your participation to event %{title}"
 msgstr "Confirme su participación en el evento %{title}"
 
-#: lib/web/templates/api/privacy.html.eex:75
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:75
 msgctxt "terms"
 msgid "An internal ID for your current selected identity"
 msgstr "Un ID interno para su identidad seleccionada actualmente"
 
-#: lib/web/templates/api/privacy.html.eex:74
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:74
 msgctxt "terms"
 msgid "An internal user ID"
 msgstr "Un ID de usuario interna"
 
-#: lib/web/templates/api/privacy.html.eex:37
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:37
 msgctxt "terms"
 msgid "Any of the information we collect from you may be used in the following ways:"
 msgstr ""
 "Cualquier información que recopilemos sobre usted puede usarse de las "
 "siguientes maneras:"
 
-#: lib/web/templates/api/privacy.html.eex:9
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:9
 msgctxt "terms"
 msgid "Basic account information"
 msgstr "Información básica de la cuenta"
 
-#: lib/web/templates/api/privacy.html.eex:25
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:25
 msgctxt "terms"
 msgid "Do not share any dangerous information over Mobilizon."
 msgstr "No comparta ninguna información peligrosa a través de Mobilizon."
 
-#: lib/web/templates/api/privacy.html.eex:90
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:90
 msgctxt "terms"
 msgid "Do we disclose any information to outside parties?"
 msgstr "¿Divulgamos alguna información a terceros?"
 
-#: lib/web/templates/api/privacy.html.eex:68
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:68
 msgctxt "terms"
 msgid "Do we use cookies?"
 msgstr "¿Usamos cookies?"
 
-#: lib/web/templates/api/privacy.html.eex:51
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:51
 msgctxt "terms"
 msgid "How do we protect your information?"
 msgstr "¿Cómo protegemos tu información?"
 
-#: lib/web/templates/api/privacy.html.eex:29
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:29
 msgctxt "terms"
 msgid "IPs and other metadata"
 msgstr "dirección IP y otros metadatos"
 
-#: lib/web/templates/api/privacy.html.eex:78
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:78
 msgctxt "terms"
 msgid "If you delete these informations, you need to login again."
 msgstr "Si eliminas esta información, deberás iniciar sesión nuevamente."
 
-#: lib/web/templates/api/privacy.html.eex:87
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:87
 msgctxt "terms"
 msgid "Note: These informations are stored in your localStorage and not your cookies."
 msgstr ""
 "Nota: Estas informaciones se almacenan en tu almacenamiento local y no en "
 "tus cookies."
 
-#: lib/web/templates/api/privacy.html.eex:17
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:17
 msgctxt "terms"
 msgid "Published events and comments"
 msgstr "Eventos publicados y comentarios"
 
-#: lib/web/templates/api/privacy.html.eex:64
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:64
 msgctxt "terms"
 msgid "Retain the IP addresses associated with registered users no more than 12 months."
 msgstr ""
 "Conserva las direcciones IP asociadas con usuarios registrados no más de 12 "
 "meses."
 
-#: lib/web/templates/api/privacy.html.eex:76
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:76
 msgctxt "terms"
 msgid "Tokens to authenticate you"
 msgstr "Fichas para \"autenticarte\""
 
-#: lib/web/templates/api/privacy.html.eex:31
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:31
 msgctxt "terms"
 msgid "We also may retain server logs which include the IP address of every request to our server."
 msgstr ""
 "También podemos conservar los registros del servidor que incluyen la "
 "dirección IP de cada solicitud a nuestro servidor."
 
-#: lib/web/templates/api/privacy.html.eex:70
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:70
 msgctxt "terms"
 msgid "We store the following information on your device when you connect:"
 msgstr ""
 "Almacenamos la siguiente información en tu dispositivo cuando te conectas:"
 
-#: lib/web/templates/api/privacy.html.eex:58
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:58
 msgctxt "terms"
 msgid "We will make a good faith effort to:"
 msgstr "Haremos un esfuerzo de buena fe para:"
 
-#: lib/web/templates/api/privacy.html.eex:35
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:35
 msgctxt "terms"
 msgid "What do we use your information for?"
 msgstr "¿Para qué utilizamos tu información?"
 
-#: lib/web/templates/api/privacy.html.eex:57
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:57
 msgctxt "terms"
 msgid "What is our data retention policy?"
 msgstr "¿Cuál es nuestra política de retención de datos?"
 
-#: lib/web/templates/api/privacy.html.eex:67
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:67
 msgctxt "terms"
 msgid "You may irreversibly delete your account at any time."
 msgstr "Puede eliminar irreversiblemente su cuenta en cualquier momento."
 
-#: lib/web/templates/api/privacy.html.eex:115
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:115
 msgctxt "terms"
 msgid "Changes to our Privacy Policy"
 msgstr "Cambios a nuestra política de privacidad"
 
-#: lib/web/templates/api/privacy.html.eex:106
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:106
 msgctxt "terms"
 msgid "If this server is in the EU or the EEA: Our site, products and services are all directed to people who are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (<a href=\"https://en.wikipedia.org/wiki/General_Data_Protection_Regulation\">General Data Protection Regulation</a>) do not use this site."
 msgstr ""
@@ -310,8 +310,8 @@ msgstr ""
 "https://en.wikipedia.org/wiki/General_Data_Protection_Regulation\"> "
 "Reglamento general de protección de datos </a>) no utilice este sitio ."
 
-#: lib/web/templates/api/privacy.html.eex:109
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:109
 msgctxt "terms"
 msgid "If this server is in the USA: Our site, products and services are all directed to people who are at least 13 years old. If you are under the age of 13, per the requirements of COPPA (<a href=\"https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act\">Children's Online Privacy Protection Act</a>) do not use this site."
 msgstr ""
@@ -322,30 +322,30 @@ msgstr ""
 "Ley de protección de la privacidad en línea para niños </a>) no utilice este "
 "sitio."
 
-#: lib/web/templates/api/privacy.html.eex:117
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:117
 msgctxt "terms"
 msgid "If we decide to change our privacy policy, we will post those changes on this page."
 msgstr ""
 "Si decidimos cambiar nuestra política de privacidad, publicaremos esos "
 "cambios en esta página."
 
-#: lib/web/templates/api/privacy.html.eex:112
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:112
 msgctxt "terms"
 msgid "Law requirements can be different if this server is in another jurisdiction."
 msgstr ""
 "Los requisitos legales pueden ser diferentes si este servidor se encuentra "
 "en otra jurisdicción."
 
-#: lib/web/templates/api/privacy.html.eex:103
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:103
 msgctxt "terms"
 msgid "Site usage by children"
 msgstr "Uso del sitio por niños"
 
-#: lib/web/templates/api/privacy.html.eex:47
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:47
 msgctxt "terms"
 msgid "The email address you provide may be used to send you information, updates and notifications about other people\n    interacting with your content or sending you messages and to respond to inquiries, and/or other requests or\n    questions."
 msgstr ""
@@ -356,8 +356,8 @@ msgstr ""
 "consultas y / u otras solicitudes o\n"
 "    preguntas."
 
-#: lib/web/templates/api/privacy.html.eex:45
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:45
 msgctxt "terms"
 msgid "To aid moderation of the community, for example comparing your IP address with other known ones to determine ban\n    evasion or other violations."
 msgstr ""
@@ -365,8 +365,8 @@ msgstr ""
 "dirección IP con otras conocidas para determinar la prohibición,\n"
 "    evasión u otras violaciones."
 
-#: lib/web/templates/api/privacy.html.eex:43
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:43
 msgctxt "terms"
 msgid "To provide the core functionality of Mobilizon. Depending on this instance's policy you may only be able to\n    interact with other people's content and post your own content if you are logged in."
 msgstr ""
@@ -375,89 +375,89 @@ msgstr ""
 "    interactuar con el contenido de otras personas y publicar tu propio "
 "contenido si ha iniciado sesión."
 
-#: lib/web/templates/api/privacy.html.eex:6
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:6
 msgctxt "terms"
 msgid "What information do we collect?"
 msgstr "¿Qué información recopilamos?"
 
-#: lib/web/email/user.ex:176
 #, elixir-format
+#: lib/web/email/user.ex:176
 msgid "Mobilizon on %{instance}: confirm your email address"
 msgstr "Mobilizon en %{instance}: confirma tu dirección de correo electrónico"
 
-#: lib/web/email/user.ex:152
 #, elixir-format
+#: lib/web/email/user.ex:152
 msgid "Mobilizon on %{instance}: email changed"
 msgstr "Mobilizon en %{instance}: correo electrónico modificado"
 
-#: lib/web/email/notification.ex:46
 #, elixir-format
+#: lib/web/email/notification.ex:46
 msgid "One event planned today"
 msgid_plural "%{nb_events} events planned today"
 msgstr[0] "Un evento programado para hoy"
 msgstr[1] "%{nb_events} eventos planeados hoy"
 
+#, elixir-format
 #: lib/web/templates/email/on_day_notification.html.eex:38
 #: lib/web/templates/email/on_day_notification.text.eex:4
-#, elixir-format
 msgid "You have one event today:"
 msgid_plural "You have %{total} events today:"
 msgstr[0] "Tienes un evento hoy:"
 msgstr[1] "Tienes %{total} eventos hoy:"
 
-#: lib/web/templates/email/group_invite.text.eex:3
 #, elixir-format
+#: lib/web/templates/email/group_invite.text.eex:3
 msgid "%{inviter} just invited you to join their group %{group}"
 msgstr "%{inviter} te acaba de invitar a unirte a su grupo %{group}"
 
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:13
 #: lib/web/templates/email/group_invite.text.eex:1
-#, elixir-format
 msgid "Come along!"
 msgstr "¡ Únete a nosotros !"
 
-#: lib/web/email/notification.ex:24
 #, elixir-format
+#: lib/web/email/notification.ex:24
 msgid "Don't forget to go to %{title}"
 msgstr "No olvides ir a %{title}"
 
+#, elixir-format
 #: lib/web/templates/email/before_event_notification.html.eex:38
 #: lib/web/templates/email/before_event_notification.text.eex:3
-#, elixir-format
 msgid "Get ready for %{title}"
 msgstr "Prepárate para %{title}"
 
-#: lib/web/templates/email/group_invite.html.eex:59
 #, elixir-format
+#: lib/web/templates/email/group_invite.html.eex:59
 msgid "See my groups"
 msgstr "Ver mis grupos"
 
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:45
 #: lib/web/templates/email/group_invite.text.eex:5
-#, elixir-format
 msgid "To accept this invitation, head over to your groups."
 msgstr "Para aceptar esta invitación, dirígete a tus grupos."
 
-#: lib/web/templates/email/before_event_notification.text.eex:5
 #, elixir-format
+#: lib/web/templates/email/before_event_notification.text.eex:5
 msgid "View the event on: %{link}"
 msgstr "Ver el evento actualizado en: %{link}"
 
-#: lib/web/email/group.ex:28
 #, elixir-format
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr "%{Inviter} te ha invitado a unirte al grupo %{group}"
 
-#: lib/web/email/notification.ex:70
 #, elixir-format
+#: lib/web/email/notification.ex:70
 msgid "One event planned this week"
 msgid_plural "%{nb_events} events planned this week"
 msgstr[0] "Un evento programado para hoy"
 msgstr[1] "%{nb_events} eventos planeados hoy"
 
-#: lib/web/email/notification.ex:92
 #, elixir-format
+#: lib/web/email/notification.ex:92
 msgid "One participation request for event %{title} to process"
 msgid_plural "%{number_participation_requests} participation requests for event %{title} to process"
 msgstr[0] "Una solicitud para participar en el evento %{title} a procesar"
@@ -465,21 +465,21 @@ msgstr[1] ""
 "%{number_participation_requests} solicitudes para participar en el evento "
 "%{title} a procesar"
 
+#, elixir-format
 #: lib/web/templates/email/notification_each_week.html.eex:38
 #: lib/web/templates/email/notification_each_week.text.eex:4
-#, elixir-format
 msgid "You have one event this week:"
 msgid_plural "You have %{total} events this week:"
 msgstr[0] "Tienes un evento hoy:"
 msgstr[1] "Tienes %{total} eventos hoy:"
 
-#: lib/service/metadata/utils.ex:27
 #, elixir-format
+#: lib/service/metadata/utils.ex:27
 msgid "The event organizer didn't add any description."
 msgstr "El organizador del evento no agregó ninguna descripción."
 
-#: lib/web/templates/api/privacy.html.eex:54
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:54
 msgctxt "terms"
 msgid "We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information. Among other things, your browser session, as well as the traffic between your applications and the API, are secured with SSL/TLS, and your password is hashed using a strong one-way algorithm."
 msgstr ""
@@ -489,8 +489,8 @@ msgstr ""
 "el tráfico entre tus aplicaciones y la API, están protegidas con SSL /TLS, y "
 "su contraseña se codifica con un fuerte algoritmo unidireccional."
 
-#: lib/web/templates/api/privacy.html.eex:94
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:94
 msgctxt "terms"
 msgid "No. We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety."
 msgstr ""
@@ -503,8 +503,8 @@ msgstr ""
 "de nuestro sitio o proteger los derechos, nuestros o de otros, propiedades o "
 "seguridad."
 
-#: lib/web/templates/api/privacy.html.eex:61
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:61
 msgctxt "terms"
 msgid "Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days."
 msgstr ""
@@ -512,8 +512,8 @@ msgstr ""
 "las solicitudes a este servidor, en la medida en que dichos registros se "
 "mantengan, no más de 90 días."
 
-#: lib/web/templates/api/privacy.html.eex:10
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:10
 msgctxt "terms"
 msgid "We collect information from you when you register on this instance and gather data when you participate in the platform by reading, writing, and interacting with content shared here. If you register on this instance, you will be asked to enter <b>an e-mail address, a password</b> (hashed) and at least <b>an username</b>. Your e-mail address will be verified by an email containing a unique link. If that link is visited, we know that you control the e-mail address. You may also enter additional profile information such as <b>a display name and biography, and upload a profile picture and header image</b>. The username, display name, biography, profile picture and header image <b>are always listed publicly</b>. <b>You may however visit this instance without registering</b>."
 msgstr ""
@@ -531,8 +531,8 @@ msgstr ""
 "imagen del encabezado <b>siempre se listan públicamente</b>. <b> Sin "
 "embargo, también puedes visitar este servidor sin registrarse</b>."
 
-#: lib/web/templates/api/privacy.html.eex:80
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:80
 msgctxt "terms"
 msgid "If you're not connected, we don't store any information on your device, unless you participate in an event anonymously. In this specific case we store the hash of an unique identifier for the event and participation status in your browser so that we may display participation status. Deleting these informations will only stop displaying participation status in your browser."
 msgstr ""
@@ -543,8 +543,8 @@ msgstr ""
 "información solo dejará de mostrar el estado de participación en tu "
 "navegador."
 
-#: lib/web/templates/api/privacy.html.eex:19
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:19
 msgctxt "terms"
 msgid "Your <b>events</b> and <b>comments</b> are delivered to other instances that follow your own, meaning they are delivered to different instances and copies are stored there. When you delete events or comments, this is likewise delivered to these other instances. All interactions related to events features - such as joining an event - or group features - such as managing resources - are federated as well. Please keep in mind that the operators of the instance and any receiving instances may view such messages and informations, and that recipients may screenshot, copy or otherwise re-share them."
 msgstr ""
@@ -556,8 +556,8 @@ msgstr ""
 "servidor y cualquier servidor receptor puede ver dichos mensajes, y los "
 "destinatarios pueden capturar, copiar o de incluso volver a compartirlos."
 
-#: lib/web/templates/api/privacy.html.eex:99
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:99
 msgctxt "terms"
 msgid "Your content may be downloaded by other instances in the network. Your public events and comments are delivered to the instances following your own instance. Content created through a group is fowarded to all the instances of all the members of the group, in so far as these members reside on a different instance than this one."
 msgstr ""
@@ -566,20 +566,20 @@ msgstr ""
 "mensajes directos se entregan a los servidores de los destinatarios, en la "
 "medida en que estos destinatarios residen en un servidor diferente a este."
 
-#: lib/web/templates/api/terms.html.eex:23
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:23
 msgctxt "terms"
 msgid "Accepting these Terms"
 msgstr "Aceptar estos Términos"
 
-#: lib/web/templates/api/terms.html.eex:27
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:27
 msgctxt "terms"
 msgid "Changes to these Terms"
 msgstr "Cambios a estos Términos de uso"
 
-#: lib/web/templates/api/terms.html.eex:30
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:30
 msgctxt "terms"
 msgid "We reserve the right to modify these Terms at any time. For instance, we may need to change these Terms if we come out with a new feature or for some other reason."
 msgstr ""
@@ -587,8 +587,8 @@ msgstr ""
 "Por ejemplo, es posible que necesitemos cambiar estos Términos si "
 "presentamos una nueva función o por alguna otra razón."
 
-#: lib/web/templates/api/terms.html.eex:85
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:85
 msgctxt "terms"
 msgid "A lot of the content on the Service is from you and others, and we don't review, verify or authenticate it, and it may include inaccuracies or false information. We make no representations, warranties, or guarantees relating to the quality, suitability, truth, accuracy or completeness of any content contained in the Service. You acknowledge sole responsibility for and assume all risk arising from your use of or reliance on any content."
 msgstr ""
@@ -600,16 +600,16 @@ msgstr ""
 "responsable y asume todos los riesgos derivados de su uso o su confianza en "
 "cualquier contenido."
 
-#: lib/web/templates/api/terms.html.eex:60
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:60
 msgctxt "terms"
 msgid "Also, you agree that you will not do any of the following in connection with the Service or other users:"
 msgstr ""
 "Además, acepta que no hará nada de lo siguiente en relación con el Servicio "
 "u otros usuarios:"
 
-#: lib/web/templates/api/terms.html.eex:65
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:65
 msgctxt "terms"
 msgid "Circumvent or attempt to circumvent any filtering, security measures, rate limits or other features designed to protect the Service, users of the Service, or third parties."
 msgstr ""
@@ -617,23 +617,23 @@ msgstr ""
 "velocidad u otras características diseñadas para proteger el Servicio, los "
 "usuarios del Servicio o terceros."
 
-#: lib/web/templates/api/terms.html.eex:64
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:64
 msgctxt "terms"
 msgid "Collect any personal information about other users, or intimidate, threaten, stalk or otherwise harass other users of the Service;"
 msgstr ""
 "Recopilar información personal sobre otros usuarios, o intimidar, amenazar, "
 "acosar o acosar a otros usuarios del Servicio;"
 
-#: lib/web/templates/api/terms.html.eex:55
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:55
 msgctxt "terms"
 msgid "Content that is illegal or unlawful, that would otherwise create liability;"
 msgstr ""
 "Contenido que es ilegal o ilegal, que de otro modo crearía responsabilidad;"
 
-#: lib/web/templates/api/terms.html.eex:56
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:56
 msgctxt "terms"
 msgid "Content that may infringe or violate any patent, trademark, trade secret, copyright, right of privacy, right of publicity or other intellectual or other right of any party;"
 msgstr ""
@@ -641,56 +641,56 @@ msgstr ""
 "secreto comercial, derecho de autor, derecho de privacidad, derecho de "
 "publicidad u otro derecho intelectual u otro derecho de cualquier parte;"
 
-#: lib/web/templates/api/terms.html.eex:42
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:42
 msgctxt "terms"
 msgid "Creating Accounts"
 msgstr "Crear cuentas"
 
-#: lib/web/templates/api/terms.html.eex:89
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:89
 msgctxt "terms"
 msgid "Entire Agreement"
 msgstr "Acuerdo completo"
 
-#: lib/web/templates/api/terms.html.eex:92
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:92
 msgctxt "terms"
 msgid "Feedback"
 msgstr "Comentarios"
 
-#: lib/web/templates/api/terms.html.eex:83
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:83
 msgctxt "terms"
 msgid "Hyperlinks and Third Party Content"
 msgstr "Hipervínculos y contenido de terceros"
 
-#: lib/web/templates/api/terms.html.eex:88
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:88
 msgctxt "terms"
 msgid "If you breach any of these Terms, we have the right to suspend or disable your access to or use of the Service."
 msgstr ""
 "Si incumple alguno de estos Términos, tenemos el derecho de suspender o "
 "deshabilitar su acceso o uso del Servicio."
 
-#: lib/web/templates/api/terms.html.eex:36
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:36
 msgctxt "terms"
 msgid "If you continue to use the Service after the revised Terms go into effect, then you have accepted the revised Terms."
 msgstr ""
 "Si continúa utilizando el Servicio después de que los Términos revisados "
 "entren en vigencia, entonces ha aceptado los Términos revisados."
 
-#: lib/web/templates/api/terms.html.eex:63
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:63
 msgctxt "terms"
 msgid "Impersonate or post on behalf of any person or entity or otherwise misrepresent your affiliation with a person or entity;"
 msgstr ""
 "Suplantar o publicar en nombre de cualquier persona o entidad o tergiversar "
 "su afiliación con una persona o entidad;"
 
-#: lib/web/templates/api/terms.html.eex:48
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:48
 msgctxt "terms"
 msgid "Our Service allows you and other users to post, link and otherwise make available content. You are responsible for the content that you make available to the Service, including its legality, reliability, and appropriateness."
 msgstr ""
@@ -698,26 +698,26 @@ msgstr ""
 "poner a disposición contenido. Usted es responsable del contenido que pone a "
 "disposición del Servicio, incluida su legalidad, confiabilidad y adecuación."
 
-#: lib/web/templates/api/terms.html.eex:39
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:39
 msgctxt "terms"
 msgid "Privacy Policy"
 msgstr "Política de privacidad"
 
-#: lib/web/templates/api/terms.html.eex:95
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:95
 msgctxt "terms"
 msgid "Questions & Contact Information"
 msgstr "Preguntas e información de contacto"
 
-#: lib/web/templates/api/terms.html.eex:87
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:87
 msgctxt "terms"
 msgid "Termination"
 msgstr "Terminación"
 
-#: lib/web/templates/api/terms.html.eex:62
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:62
 msgctxt "terms"
 msgid "Use the Service in any manner that could interfere with, disrupt, negatively affect or inhibit other users from fully enjoying the Service or that could damage, disable, overburden or impair the functioning of the Service;"
 msgstr ""
@@ -726,8 +726,8 @@ msgstr ""
 "Servicio o que pueda dañar, deshabilitar, sobrecargar o perjudicar el "
 "funcionamiento del Servicio;"
 
-#: lib/web/templates/api/terms.html.eex:49
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:49
 msgctxt "terms"
 msgid "When you post, link or otherwise make available content to the Service, you grant us the right and license to display and distribute your content on or through the Service (including via applications). We may format your content for display throughout the Service, but we will not edit or revise the substance of your content itself. The displaying and distribution of your content happens strictly only according to the visibility rules you have set for the content. We will not modify the visibility of the content you have set."
 msgstr ""
@@ -740,14 +740,14 @@ msgstr ""
 "visibilidad que ha establecido para el contenido. No modificaremos la "
 "visibilidad del contenido que ha establecido."
 
-#: lib/web/templates/api/terms.html.eex:47
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:47
 msgctxt "terms"
 msgid "Your Content & Conduct"
 msgstr "Su contenido y conducta"
 
-#: lib/web/templates/api/terms.html.eex:84
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:84
 msgctxt "terms"
 msgid "<b>%{instance_name}</b> makes no claim or representation regarding, and accepts no responsibility for third party websites accessible by hyperlink from the Service or websites linking to the Service. When you leave the Service, you should be aware that these Terms and our policies no longer govern. The inclusion of any link does not imply endorsement by <b>%{instance_name}</b> of the site. Use of any such linked website is at the user's own risk."
 msgstr ""
@@ -759,8 +759,8 @@ msgstr ""
 "no implica la aprobación por <b>% {instance_name} </b> del sitio. El uso de "
 "cualquier sitio web vinculado es bajo el propio riesgo del usuario."
 
-#: lib/web/templates/api/terms.html.eex:68
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:68
 msgctxt "terms"
 msgid "Finally, your use of the Service is also subject to acceptance of <a href=\"/rules\">the instance's own specific rules</a> regarding the code of conduct and moderation rules. Breaking those rules may also result in your account being disabled or suspended."
 msgstr ""
@@ -769,16 +769,16 @@ msgstr ""
 "código de conducta y las reglas de moderación. Romper esas reglas también "
 "puede resultar en que su cuenta sea deshabilitada o suspendida."
 
-#: lib/web/templates/api/terms.html.eex:81
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:81
 msgctxt "terms"
 msgid "For full details about the Mobilizon software <a href=\"https://joinmobilizon.org\">see here</a>."
 msgstr ""
 "Para obtener detalles completos sobre el software Mobilizon <a href=\"https"
 "://joinmobilizon.org\"> ver aquí </a>."
 
-#: lib/web/templates/api/terms.html.eex:40
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:40
 msgctxt "terms"
 msgid "For information about how we collect and use information about users of the Service, please check out our <a href=\"/privacy\">privacy policy</a>."
 msgstr ""
@@ -786,8 +786,8 @@ msgstr ""
 "sobre los usuarios del Servicio, consulte nuestra <a href=\"/privacy\"> "
 "política de privacidad </a>."
 
-#: lib/web/templates/api/terms.html.eex:18
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:18
 msgctxt "terms"
 msgid "Here are the important things you need to know about accessing and using the <b>%{instance_name}</b> (<a href=\"https://%{instance_url}\">%{instance_url}</a>) website and service (collectively, \"Service\"). These are our terms of service (\"Terms\"). Please read them carefully."
 msgstr ""
@@ -797,8 +797,8 @@ msgstr ""
 "Estos son nuestros términos de servicio (\"Términos\"). Por favor, léalos "
 "atentamente."
 
-#: lib/web/templates/api/terms.html.eex:33
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:33
 msgctxt "terms"
 msgid "If we make major changes, we will notify our users in a clear and prominent manner. Minor changes may only be highlighted in the footer of our website. It is your responsibility to check the website regularly for changes to these Terms."
 msgstr ""
@@ -807,8 +807,8 @@ msgstr ""
 "página de nuestro sitio web. Es su responsabilidad revisar el sitio web "
 "regularmente para ver los cambios a estos Términos."
 
-#: lib/web/templates/api/terms.html.eex:53
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:53
 msgctxt "terms"
 msgid "In order to make <b>%{instance_name}</b> a great place for all of us, please do not post, link and otherwise make available on or through the Service any of the following:"
 msgstr ""
@@ -816,8 +816,8 @@ msgstr ""
 "publique, enlace ni ponga a disposición en el Servicio ni a través de él "
 "ninguno de los siguientes:"
 
-#: lib/web/templates/api/terms.html.eex:57
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:57
 msgctxt "terms"
 msgid "Private information of any third party (e.g., addresses, phone numbers, email addresses, Social Security numbers and credit card numbers); and"
 msgstr ""
@@ -825,8 +825,8 @@ msgstr ""
 "de teléfono, direcciones de correo electrónico, números de Seguro Social y "
 "números de tarjetas de crédito); y"
 
-#: lib/web/templates/api/terms.html.eex:52
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:52
 msgctxt "terms"
 msgid "Since Mobilizon is a distributed network, it is possible, depending on the visibility rules set to your content, that your content has been distributed to other Mobilizon instances. When you delete your content, we will request those other instances to also delete the content. Our responsibility on the content being deleted from those other instances ends here. If for some reason, some other instance does not delete the content, we cannot be held responsible."
 msgstr ""
@@ -838,8 +838,8 @@ msgstr ""
 "instancias termina aquí. Si por alguna razón, alguna otra instancia no "
 "elimina el contenido, no podemos ser responsables."
 
-#: lib/web/templates/api/terms.html.eex:90
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:90
 msgctxt "terms"
 msgid "These Terms constitute the entire agreement between you and <b>%{instance_name}</b> regarding the use of the Service, superseding any prior agreements between you and <b>%{instance_name}</b> relating to your use of the Service."
 msgstr ""
@@ -848,8 +848,8 @@ msgstr ""
 "cualquier acuerdo previo entre usted y <b>% {instance_name} </b> relacionado "
 "con su uso de el servicio."
 
-#: lib/web/templates/api/terms.html.eex:80
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:80
 msgctxt "terms"
 msgid "This Service runs on a Mobilizon instance. This source code is licensed under an <a href=\"https://tldrlegal.com/license/gnu-affero-general-public-license-v3-(agpl-3.0)\">AGPLv3 license</a> which means you are allowed to and even encouraged to take the source code, modify it and use it."
 msgstr ""
@@ -859,16 +859,16 @@ msgstr ""
 "significa que están autorizados e incluso alentados a tomar el código "
 "fuente, modificarlo y usarlo."
 
-#: lib/web/templates/api/terms.html.eex:58
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:58
 msgctxt "terms"
 msgid "Viruses, corrupted data or other harmful, disruptive or destructive files or code."
 msgstr ""
 "Virus, datos corruptos u otros archivos o códigos dañinos, perjudiciales o "
 "destructivos."
 
-#: lib/web/templates/api/terms.html.eex:50
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:50
 msgctxt "terms"
 msgid "We cannot be held responsible should a programming or administrative error make your content visible to a larger audience than you had intended. Aside from our limited right to your content, you retain all of your rights to the content you post, link and otherwise make available on or through the Service."
 msgstr ""
@@ -878,8 +878,8 @@ msgstr ""
 "todos sus derechos sobre el contenido que publica, vincula y de lo contrario "
 "pone a disposición en oa través del Servicio."
 
-#: lib/web/templates/api/terms.html.eex:45
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:45
 msgctxt "terms"
 msgid "We will not be liable for any loss that you may incur as a result of someone else using your email or password, either with or without your knowledge."
 msgstr ""
@@ -887,8 +887,8 @@ msgstr ""
 "resultado de que otra persona use su correo electrónico o contraseña, ya sea "
 "con o sin su conocimiento."
 
-#: lib/web/templates/api/terms.html.eex:43
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:43
 msgctxt "terms"
 msgid "When you create an account you also agree to maintain the security and confidentiality of your password and accept all risks of unauthorized access to your account data and any other information you provide to <b>%{instance_name}</b>."
 msgstr ""
@@ -897,8 +897,8 @@ msgstr ""
 "autorizado a los datos de su cuenta y cualquier otra información que "
 "proporcione a <b>% {instance_name} </b>."
 
-#: lib/web/templates/api/terms.html.eex:51
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:51
 msgctxt "terms"
 msgid "You can remove the content that you posted by deleting it. Once you delete your content, it will not appear on the Service, but copies of your deleted content may remain in our system or backups for some period of time. Web server access logs might also be stored for some time in the system."
 msgstr ""
@@ -908,8 +908,8 @@ msgstr ""
 "un período de tiempo. Los registros de acceso al servidor web también pueden "
 "almacenarse durante algún tiempo en el sistema."
 
-#: lib/web/templates/api/terms.html.eex:24
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:24
 msgctxt "terms"
 msgid "If you access or use the Service, it means you agree to be bound by all of the terms below. So, before you use the Service, please read all of the terms. If you don't agree to all of the terms below, please do not use the Service. Also, if a term does not make sense to you, please let us know by contacting %{contact}."
 msgstr ""
@@ -919,22 +919,22 @@ msgstr ""
 "no utilice el Servicio. Además, si un término no tiene sentido para usted, "
 "comuníquese con% {contact}."
 
-#: lib/web/templates/api/terms.html.eex:96
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:96
 msgctxt "terms"
 msgid "Questions or comments about the Service may be directed to us at %{contact}"
 msgstr ""
 "Las preguntas o comentarios sobre el Servicio pueden dirigirse a% {contact}"
 
-#: lib/web/templates/api/terms.html.eex:79
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:79
 msgctxt "terms"
 msgid "Source code"
 msgstr "Código fuente"
 
+#, elixir-format
 #: lib/web/templates/api/privacy.html.eex:3
 #: lib/web/templates/api/terms.html.eex:15
-#, elixir-format
 msgctxt "terms"
 msgid "Some terms, technical or otherwise, used in the text below may cover concepts that are difficult to grasp. We provide <a href=\"/glossary\">a glossary</a> to help you understand them better."
 msgstr ""
@@ -943,16 +943,16 @@ msgstr ""
 "Proporcionamos <a href=\"/glossary\"> un glosario </a> para ayudarlo a "
 "comprenderlos mejor."
 
-#: lib/web/templates/api/terms.html.eex:93
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:93
 msgctxt "terms"
 msgid "We love feedback. Please let us know what you think of the Service, these Terms and, in general, <b>%{instance_name}</b>."
 msgstr ""
 "Nos encantan los comentarios. Háganos saber lo que piensa del Servicio, "
 "estos Términos y, en general, <b>% {instance_name} </b>."
 
-#: lib/web/templates/api/terms.html.eex:74
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:74
 msgctxt "terms"
 msgid "Instance administrators (and community moderators, given the relevant access) are responsible for monitoring and acting on flagged content and other user reports, and have the right and responsibility to remove or edit content that is not aligned to this Instance set of rules, or to suspend, block or ban (temporarily or permanently) any account, community, or instance for breaking these terms, or for other behaviours that they deem inappropriate, threatening, offensive, or harmful."
 msgstr ""
@@ -965,14 +965,14 @@ msgstr ""
 "incumplir estos términos o por otros comportamientos que consideren "
 "inapropiados, amenazantes, ofensivos o dañinos."
 
-#: lib/web/templates/api/terms.html.eex:71
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:71
 msgctxt "terms"
 msgid "Our responsability"
 msgstr "Nuestra responsabilidad"
 
-#: lib/web/templates/api/terms.html.eex:20
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:20
 msgctxt "terms"
 msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors, supported by <a href=\"https://framasoft.org\">Framasoft</a>, a french not-for-profit popular educational organization advocating for Free/Libre Software. Unless explicity stated, this Mobilizon instance is an independant service using Mobilizon's source code. You may find more informations about this instance on the <a href=\"/about/instance\">\"About this instance\" page</a>."
 msgstr ""
@@ -987,16 +987,16 @@ msgstr ""
 "encontrar más información sobre esta instancia en la página <a href=\"/about/"
 "instance\"> \"Acerca de esta instancia\" </a>."
 
-#: lib/web/templates/api/terms.html.eex:6
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:6
 msgctxt "terms"
 msgid "<b>%{instance_name}</b> will not use or transmit or resell your personal data"
 msgstr ""
 "<b>% {instance_name} </b> no usará ni transmitirá ni revenderá sus datos "
 "personales"
 
-#: lib/web/templates/api/terms.html.eex:44
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:44
 msgctxt "terms"
 msgid "If you discover or suspect any Service security breaches, please let us know as soon as possible. For security holes in the Mobilizon software itself, please contact <a href=\"https://framagit.org/framasoft/mobilizon/\">its contributors</a> directly."
 msgstr ""
@@ -1005,8 +1005,8 @@ msgstr ""
 "de Mobilizon, comuníquese directamente con <a href=\"https://framagit.org/"
 "framasoft/mobilizon/\"> sus colaboradores </a>."
 
-#: lib/web/templates/api/terms.html.eex:77
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:77
 msgctxt "terms"
 msgid "Instance administrators should ensure that every community hosted on the instance is properly moderated according to the defined rules."
 msgstr ""
@@ -1014,8 +1014,8 @@ msgstr ""
 "alojada en la instancia esté moderada adecuadamente de acuerdo con las "
 "reglas definidas."
 
-#: lib/web/templates/api/terms.html.eex:98
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:98
 msgctxt "terms"
 msgid "Originally adapted from the <a href=\"https://joindiaspora.com/terms\">Diaspora*</a> and <a href=\"https://github.com/appdotnet/terms-of-service\">App.net</a> privacy policies, also licensed under <a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>."
 msgstr ""
@@ -1024,8 +1024,8 @@ msgstr ""
 ">App.net</a> privacy policies, also licensed under <a href=\"https"
 "://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>."
 
-#: lib/web/templates/api/privacy.html.eex:119
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:119
 msgctxt "terms"
 msgid "Originally adapted from the <a href=\"https://mastodon.social/terms\">Mastodon</a> and <a href=\"https://github.com/discourse/discourse\">Discourse</a> privacy policies, also licensed under <a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>."
 msgstr ""
@@ -1034,22 +1034,22 @@ msgstr ""
 "</a>políticas de privacidad, también bajo licencia <a href=\"https"
 "://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>."
 
-#: lib/web/templates/api/terms.html.eex:3
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:3
 msgctxt "terms"
 msgid "Short version"
 msgstr "Version corta"
 
-#: lib/web/templates/api/terms.html.eex:9
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:9
 msgctxt "terms"
 msgid "The service is provided without warranties and these terms may change in the future"
 msgstr ""
 "El servicio se brinda sin garantías y estos términos pueden cambiar en el "
 "futuro"
 
-#: lib/web/templates/api/privacy.html.eex:118
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:118
 msgctxt "terms"
 msgid "This document is licensed under <a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>. It was last updated June 18, 2020."
 msgstr ""
@@ -1057,8 +1057,8 @@ msgstr ""
 "licenses/by-sa/4.0/\"> CC BY-SA </a>. Se actualizó por última vez el 18 de "
 "junio de 2020."
 
-#: lib/web/templates/api/terms.html.eex:97
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:97
 msgctxt "terms"
 msgid "This document is licensed under <a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>. It was last updated June 22, 2020."
 msgstr ""
@@ -1066,101 +1066,101 @@ msgstr ""
 "licenses/by-sa/4.0/\"> CC BY-SA </a>. Se actualizó por última vez el 22 de "
 "junio de 2020."
 
-#: lib/web/templates/api/terms.html.eex:8
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:8
 msgctxt "terms"
 msgid "You must respect other people and <b>%{instance_name}</b>'s rules when using the service"
 msgstr ""
 "Debe respetar las reglas de otras personas y <b>% {instance_name} </b> al "
 "usar el servicio"
 
-#: lib/web/templates/api/terms.html.eex:7
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:7
 msgctxt "terms"
 msgid "You must respect the law when using <b>%{instance_name}</b>"
 msgstr "Debe respetar la ley cuando use <b>% {instance_name} </b>"
 
-#: lib/web/templates/api/terms.html.eex:5
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:5
 msgctxt "terms"
 msgid "Your content is yours"
 msgstr "Tu contenido es tuyo"
 
-#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:58
 #, elixir-format
+#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:58
 msgid "Confirm my e-mail address"
 msgstr "Confirmar mi dirección de correo electrónico"
 
+#, elixir-format
 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:13
 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:1
-#, elixir-format
 msgid "Confirm your e-mail"
 msgstr "Confirme su email"
 
+#, elixir-format
 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:38
 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:3
-#, elixir-format
 msgid "Hi there! You just registered to join this event: « %{title} ». Please confirm the e-mail address you provided:"
 msgstr ""
 "¡Hola! Te acabas de registrar para unirte a este evento: «% {title}». "
 "Confirme la dirección de correo electrónico que proporcionó:"
 
+#, elixir-format
 #: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:12
-#, elixir-format
 msgid "Need help? Is something not working as expected?"
 msgstr "¿Necesita ayuda? ¿Algo no está funcionando correctamente?"
 
-#: lib/web/templates/email/registration_confirmation.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/registration_confirmation.html.eex:38
 msgid "You created an account on <b>%{host}</b> with this email address. You are one click away from activating it."
 msgstr ""
 "Creó una cuenta en <b>% {host} </b> con esta dirección de correo "
 "electrónico. Estás a un clic de activarlo."
 
-#: lib/web/templates/email/report.html.eex:41
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:41
 msgid "<b>%{reporter_name}</b> (%{reporter_username}) reported the following content."
 msgstr ""
 "<b>% {reporter_name} </b> (% {reporter_username}) informó el siguiente "
 "contenido."
 
-#: lib/web/templates/email/report.html.eex:13
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:13
 msgid "New report on <b>%{instance}</b>"
 msgstr "Nuevo informe sobre <b>% {instancia} </b>"
 
-#: lib/web/templates/email/email_changed_old.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/email_changed_old.html.eex:38
 msgid "The email address for your account on <b>%{host}</b> is being changed to:"
 msgstr ""
 "La dirección de correo electrónico de su cuenta en <b>% {host} </b> se "
 "cambiará a:"
 
-#: lib/web/templates/email/password_reset.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/password_reset.html.eex:38
 msgid "You requested a new password for your account on <b>%{instance}</b>."
 msgstr "Solicitó una nueva contraseña para su cuenta en <b>% {instancia} </b>."
 
-#: lib/web/templates/email/email.text.eex:9
 #, elixir-format
+#: lib/web/templates/email/email.text.eex:9
 msgid "Mobilizon is still under development, we will add new features along the updates, until the release of version 1 of the software in the fall of 2020."
 msgstr ""
 "Mobilizon está en desarrollo, agregaremos nuevas funciones a este sitio "
 "durante las actualizaciones periódicas, hasta el lanzamiento de la versión 1 "
 "del software en la primera mitad de 2020."
 
-#: lib/web/templates/email/email.text.eex:7
 #, elixir-format
+#: lib/web/templates/email/email.text.eex:7
 msgid "Please do not use it for real purposes."
 msgstr "Por favor no lo use de ninguna manera real."
 
+#, elixir-format
 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:45
 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:6 lib/web/templates/email/event_updated.html.eex:131
 #: lib/web/templates/email/event_updated.text.eex:24 lib/web/templates/email/notification_each_week.html.eex:70
 #: lib/web/templates/email/notification_each_week.text.eex:14 lib/web/templates/email/on_day_notification.html.eex:70
 #: lib/web/templates/email/on_day_notification.text.eex:14
-#, elixir-format
 msgid "Would you wish to cancel your attendance, visit the event page through the link above and click the « Attending » button."
 msgid_plural "Would you wish to cancel your attendance to one or several events, visit the event pages through the links above and click the « Attending » button."
 msgstr[0] ""
@@ -1170,9 +1170,9 @@ msgstr[1] ""
 "Si necesitas cancelar su participación, sólo accede a la página del evento "
 "mediante el enlace debajo y presiona el botón."
 
+#, elixir-format
 #: lib/web/templates/email/pending_participation_notification.html.eex:38
 #: lib/web/templates/email/pending_participation_notification.text.eex:4
-#, elixir-format
 msgid "You have one pending attendance request to process:"
 msgid_plural "You have %{number_participation_requests} attendance requests to process:"
 msgstr[0] "Tiene una solicitud de participación pendiente de procesar:"
@@ -1180,66 +1180,66 @@ msgstr[1] ""
 "Tienes %{number_participation_requests} solicitudes de participación "
 "pendientes de procesar:"
 
-#: lib/web/templates/email/email.text.eex:16
 #, elixir-format
+#: lib/web/templates/email/email.text.eex:16
 msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} es un servidor de Mobilizon."
 
-#: lib/web/templates/email/email.html.eex:146
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:146
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>% {instancia} </b> es una instancia de Mobilizon."
 
+#, elixir-format
 #: lib/web/templates/email/pending_participation_notification.html.eex:13
 #: lib/web/templates/email/pending_participation_notification.text.eex:1
-#, elixir-format
 msgid "A request is pending!"
 msgstr "¡Hay una solicitud pendiente!"
 
+#, elixir-format
 #: lib/web/templates/email/before_event_notification.html.eex:13
 #: lib/web/templates/email/before_event_notification.text.eex:1
-#, elixir-format
 msgid "An event is upcoming!"
 msgstr "¡Se acerca un evento!"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_new.html.eex:13
 #: lib/web/templates/email/email_changed_new.text.eex:1
-#, elixir-format
 msgid "Confirm new email"
 msgstr "Confirme su email"
 
-#: lib/web/templates/email/event_updated.html.eex:82
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:82
 msgid "End"
 msgstr "Final"
 
-#: lib/web/templates/email/event_updated.text.eex:21
 #, elixir-format
+#: lib/web/templates/email/event_updated.text.eex:21
 msgid "End %{ends_on}"
 msgstr "Final% {ends_on}"
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:13
 #: lib/web/templates/email/event_updated.text.eex:1
-#, elixir-format
 msgid "Event update!"
 msgstr "¡Evento actualizado!"
 
-#: lib/web/templates/email/report.html.eex:66
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:66
 msgid "Flagged comments"
 msgstr "Comentarios marcados"
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_approved.html.eex:45
 #: lib/web/templates/email/event_participation_approved.text.eex:7
-#, elixir-format
 msgid "Good news: one of the event organizers just approved your request. Update your calendar, because you're on the guest list now!"
 msgstr ""
 "Buenas noticias: uno de los organizadores del evento acaba de aprobar su "
 "solicitud. Actualice su calendario, ¡porque ya está en la lista de invitados!"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_new.html.eex:38
 #: lib/web/templates/email/email_changed_new.text.eex:3
-#, elixir-format
 msgid "Hi there! It seems like you wanted to change the email address linked to your account on <b>%{instance}</b>. If you still wish to do so, please click the button below to confirm the change. You will then be able to log in to %{instance} with this new email address."
 msgstr ""
 "¡Hola! Parece que desea cambiar la dirección de correo electrónico vinculada "
@@ -1247,16 +1247,16 @@ msgstr ""
 "botón de abajo para confirmar el cambio. Luego podrá iniciar sesión en% "
 "{instance} con esta nueva dirección de correo electrónico."
 
-#: lib/web/templates/email/email_changed_old.text.eex:3
 #, elixir-format
+#: lib/web/templates/email/email_changed_old.text.eex:3
 msgid "Hi there! Just a quick note to confirm that the email address linked to your account on %{host} has been changed from this one to:"
 msgstr ""
 "¡Hola! Solo una nota rápida para confirmar que la dirección de correo "
 "electrónico vinculada a su cuenta en% {host} se ha cambiado de esta a:"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_old.html.eex:41
 #: lib/web/templates/email/email_changed_old.text.eex:5
-#, elixir-format
 msgid "If you did not trigger this change yourself, it is likely that someone has gained access to your %{host} account. Please log in and change your password immediately. If you cannot login, contact the admin on %{host}."
 msgstr ""
 "Si no activó este cambio usted mismo, es probable que alguien haya obtenido "
@@ -1264,187 +1264,187 @@ msgstr ""
 "inmediatamente. Si no puede iniciar sesión, comuníquese con el administrador "
 "en% {host}."
 
-#: lib/web/templates/email/password_reset.text.eex:12
 #, elixir-format
+#: lib/web/templates/email/password_reset.text.eex:12
 msgid "If you didn't trigger the change yourself, please ignore this message. Your password won't be changed until you click the link above."
 msgstr ""
 "Si no activó el cambio usted mismo, ignore este mensaje. Su contraseña no se "
 "cambiará hasta que haga clic en el enlace de arriba."
 
+#, elixir-format
 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:70
 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:4 lib/web/templates/email/registration_confirmation.html.eex:45
-#, elixir-format
 msgid "If you didn't trigger this email, you may safely ignore it."
 msgstr "Si no activó esta alerta, puede ignorarla con seguridad."
 
+#, elixir-format
 #: lib/web/templates/email/before_event_notification.html.eex:63
 #: lib/web/templates/email/before_event_notification.text.eex:6
-#, elixir-format
 msgid "If you wish to cancel your attendance, visit the event page through the link above and click the « Attending » button."
 msgstr ""
 "Si necesitas cancelar su participación, sólo accede a la página del evento "
 "mediante el enlace debajo y presiona el botón."
 
-#: lib/web/templates/email/email.html.eex:92
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:92
 msgid "In the meantime, please consider this software as not (yet) fully functional. Read more %{a_start}on the Framasoft blog%{a_end}."
 msgstr ""
 "Mientras tanto, tenga en cuenta que el software no está (todavía) terminado. "
 "Más información %{a_start} en nuestro blog %{a_end}."
 
-#: lib/web/templates/email/email.text.eex:10
 #, elixir-format
+#: lib/web/templates/email/email.text.eex:10
 msgid "In the meantime, please consider this software as not (yet) fully functional. Read more on the Framasoft blog:"
 msgstr ""
 "Mientras tanto, tenga en cuenta que el software no está (todavía) terminado. "
 "Más información %{a_start} en nuestro blog %{a_end:"
 
+#, elixir-format
 #: lib/web/templates/email/email.html.eex:147
 #: lib/web/templates/email/email.text.eex:16
-#, elixir-format
 msgid "Learn more about Mobilizon here!"
 msgstr "¡Aprenda más sobre Mobilizon aquí!"
 
-#: lib/web/templates/email/event_updated.html.eex:92
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:92
 msgid "Location"
 msgstr "Ubicación"
 
-#: lib/web/templates/email/event_updated.html.eex:102
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:102
 msgid "Location address was removed"
 msgstr "Dirección física fue eliminada"
 
+#, elixir-format
 #: lib/web/templates/email/pending_participation_notification.html.eex:51
 #: lib/web/templates/email/pending_participation_notification.text.eex:6
-#, elixir-format
 msgid "Manage pending requests"
 msgstr "Gestionar solicitudes de participación pendientes"
 
+#, elixir-format
 #: lib/web/templates/email/registration_confirmation.html.eex:13
 #: lib/web/templates/email/registration_confirmation.text.eex:1
-#, elixir-format
 msgid "Nearly there!"
 msgstr "¡Ya casi estas!"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_old.html.eex:13
 #: lib/web/templates/email/email_changed_old.text.eex:1
-#, elixir-format
 msgid "New email confirmation"
 msgstr "Nueva confirmación de correo electrónico"
 
-#: lib/web/templates/email/report.html.eex:84
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:84
 msgid "Reasons for report"
 msgstr "Razones para informar"
 
-#: lib/web/templates/email/report.html.eex:39
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:39
 msgid "Someone on <b>%{instance}</b> reported the following content for you to analyze:"
 msgstr "Alguien en <b>% {instancia} </b> informó el siguiente contenido:"
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_rejected.html.eex:13
 #: lib/web/templates/email/event_participation_rejected.text.eex:1
-#, elixir-format
 msgid "Sorry! You're not going."
 msgstr "¡Lo siento! No vas."
 
-#: lib/web/templates/email/event_updated.html.eex:72
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:72
 msgid "Start"
 msgstr "Inicio"
 
-#: lib/web/templates/email/event_updated.text.eex:18
 #, elixir-format
+#: lib/web/templates/email/event_updated.text.eex:18
 msgid "Start %{begins_on}"
 msgstr "Inicio% {starts_on}"
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:38
 #: lib/web/templates/email/event_updated.text.eex:3
-#, elixir-format
 msgid "There have been changes for %{title} so we'd thought we'd let you know."
 msgstr "Ha habido cambios para% {title}, así que pensamos en avisarle."
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:54
 #: lib/web/templates/email/event_updated.text.eex:11
-#, elixir-format
 msgid "This event has been cancelled by its organizers. Sorry!"
 msgstr "Este evento ha sido cancelado por sus organizadores. ¡Lo siento!"
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:50
 #: lib/web/templates/email/event_updated.text.eex:7
-#, elixir-format
 msgid "This event has been confirmed"
 msgstr "El evento ha sido confirmado"
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:52
 #: lib/web/templates/email/event_updated.text.eex:9
-#, elixir-format
 msgid "This event has yet to be confirmed: organizers will let you know if they do confirm it."
 msgstr ""
 "Este evento aún no se ha confirmado: los organizadores te avisarán si lo "
 "confirman."
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_rejected.html.eex:45
 #: lib/web/templates/email/event_participation_rejected.text.eex:7
-#, elixir-format
 msgid "Unfortunately, the organizers rejected your request."
 msgstr ""
 "Lamentablemente, los organizadores rechazaron tu solicitud de participación."
 
-#: lib/web/templates/email/email_changed_new.html.eex:51
 #, elixir-format
+#: lib/web/templates/email/email_changed_new.html.eex:51
 msgid "Verify your email address"
 msgstr "Verifica tu dirección de correo electrónico"
 
-#: lib/web/templates/email/report.html.eex:104
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:104
 msgid "View report"
 msgstr "Ver el informe"
 
-#: lib/web/templates/email/report.text.eex:17
 #, elixir-format
+#: lib/web/templates/email/report.text.eex:17
 msgid "View report:"
 msgstr "Ver el informe:"
 
-#: lib/web/templates/email/event_participation_approved.html.eex:58
 #, elixir-format
+#: lib/web/templates/email/event_participation_approved.html.eex:58
 msgid "Visit event page"
 msgstr "Visita la página del evento"
 
-#: lib/web/templates/email/event_updated.html.eex:119
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:119
 msgid "Visit the updated event page"
 msgstr "Visita la página del evento actualizada"
 
-#: lib/web/templates/email/event_updated.text.eex:23
 #, elixir-format
+#: lib/web/templates/email/event_updated.text.eex:23
 msgid "Visit the updated event page: %{link}"
 msgstr "Ver el evento actualizado en: %{link}"
 
+#, elixir-format
 #: lib/web/templates/email/notification_each_week.html.eex:13
 #: lib/web/templates/email/notification_each_week.text.eex:1
-#, elixir-format
 msgid "What's up this week?"
 msgstr "¿Qué pasa esta semana?"
 
+#, elixir-format
 #: lib/web/templates/email/on_day_notification.html.eex:13
 #: lib/web/templates/email/on_day_notification.text.eex:1
-#, elixir-format
 msgid "What's up today?"
 msgstr "Qué pasa hoy?"
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_approved.html.eex:70
 #: lib/web/templates/email/event_participation_approved.text.eex:11
-#, elixir-format
 msgid "Would you wish to update or cancel your attendance, simply access the event page through the link above and click on the Attending button."
 msgstr ""
 "Si desea actualizar o cancelar su asistencia, simplemente acceda a la página "
 "del evento a través del enlace de arriba y haga clic en el botón Asistir."
 
+#, elixir-format
 #: lib/web/templates/email/pending_participation_notification.html.eex:64
 #: lib/web/templates/email/pending_participation_notification.text.eex:8
-#, elixir-format
 msgid "You are receiving this email because you chose to get notifications for pending attendance requests to your events. You can disable or change your notification settings in your user account settings under « Notifications »."
 msgstr ""
 "Recibió este correo electrónico porque eligió recibir notificaciones de "
@@ -1452,78 +1452,124 @@ msgstr ""
 "cambiar la configuración de notificaciones en la configuración de su cuenta "
 "de usuario en «Notificaciones»."
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_rejected.html.eex:38
 #: lib/web/templates/email/event_participation_rejected.text.eex:5
-#, elixir-format
 msgid "You issued a request to attend %{title}."
 msgstr "Envió una solicitud para asistir a %{title}."
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_approved.html.eex:38
 #: lib/web/templates/email/event_participation_approved.text.eex:5
-#, elixir-format
 msgid "You recently requested to attend %{title}."
 msgstr "Solicitaste participar en el evento %{title}."
 
-#: lib/web/templates/email/event_participation_approved.html.eex:13
 #, elixir-format
+#: lib/web/templates/email/event_participation_approved.html.eex:13
 msgid "You're going!"
 msgstr "¡Vas!"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_new.html.eex:64
 #: lib/web/templates/email/email_changed_new.text.eex:5
-#, elixir-format
 msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr "Si no activó el cambio usted mismo, ignore este mensaje."
 
-#: lib/web/templates/email/email.html.eex:89
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:89
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Por favor no lo use de ninguna manera real.</b>"
 
-#: lib/web/templates/email/email.html.eex:91
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:91
 msgid "Mobilizon is still under development, we will add new features along the updates, until the release of <b>version 1 of the software in the fall of 2020</b>."
 msgstr ""
 "Mobilizon está en desarrollo, agregaremos nuevas funciones a este sitio "
 "durante las actualizaciones periódicas, hasta el lanzamiento de la<b> "
 "versión 1 del software en la primera mitad de 2020</b>."
 
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
 #, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 "Si cree que esto es un error, puede comunicarse con los administradores del "
 "grupo para que lo puedan integrar de nuevo."
 
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
 #, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr "¡Hasta luego y gracias por el pescado!"
 
-#: lib/web/email/group.ex:58
 #, elixir-format
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr "Ha sido eliminado del grupo %{group}"
 
-#: lib/web/templates/email/group_removal.text.eex:3
 #, elixir-format
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 "Se le ha eliminado del grupo %{group}. Ya no podrá acceder al contenido "
 "privado de este grupo."
 
-#: lib/web/templates/email/group_invite.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 "<b>%{inviter} </b> le acaba de invitar a unirse a su grupo% {link_start} "
 "<b>% {group} </b>% {link_end}"
 
-#: lib/web/templates/email/group_removal.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
 "Ha sido eliminado del grupo% {link_start} <b>% {group} </b>% {link_end}. Ya "
 "no podrá acceder al contenido privado de este grupo."
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/fi/LC_MESSAGES/default.po b/priv/gettext/fi/LC_MESSAGES/default.po
index 68f8643a4..3fdc16de8 100644
--- a/priv/gettext/fi/LC_MESSAGES/default.po
+++ b/priv/gettext/fi/LC_MESSAGES/default.po
@@ -14,286 +14,286 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
 "X-Generator: Weblate 4.1\n"
 
-#: lib/web/templates/email/password_reset.html.eex:48
 #, elixir-format
+#: lib/web/templates/email/password_reset.html.eex:48
 msgid "If you didn't request this, please ignore this email. Your password won't change until you access the link below and create a new one."
 msgstr ""
 "Jos et lähettänyt pyyntöä, voit jättää tämän viestin huomiotta. Salasanasi "
 "ei vaihdu, ennen kuin käytät alla olevaa linkkiä ja luot uuden salasanan."
 
-#: lib/service/export/feed.ex:170
 #, elixir-format
+#: lib/service/export/feed.ex:170
 msgid "Feed for %{email} on Mobilizon"
 msgstr "Mobilizon-syöte osoitteeseen %{email}"
 
-#: lib/web/templates/email/report.html.eex:52
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:52
 msgid "%{title} by %{creator}"
 msgstr "%{title} luojalta %{creator}"
 
-#: lib/web/templates/email/registration_confirmation.html.eex:58
 #, elixir-format
+#: lib/web/templates/email/registration_confirmation.html.eex:58
 msgid "Activate my account"
 msgstr "Aktivoi tilini"
 
+#, elixir-format
 #: lib/web/templates/email/email.html.eex:121
 #: lib/web/templates/email/email.text.eex:14
-#, elixir-format
 msgid "Ask the community on Framacolibri"
 msgstr "Kysy yhteisöltä Framacolibrissa"
 
-#: lib/web/templates/email/report.text.eex:8
 #, elixir-format
+#: lib/web/templates/email/report.text.eex:8
 msgid "Comments"
 msgstr "Kommentit"
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:62
 #: lib/web/templates/email/report.html.eex:50 lib/web/templates/email/report.text.eex:4
-#, elixir-format
 msgid "Event"
 msgstr "Tapahtuma"
 
-#: lib/web/email/user.ex:48
 #, elixir-format
+#: lib/web/email/user.ex:48
 msgid "Instructions to reset your password on %{instance}"
 msgstr "Ohjeet salasanan palauttamiseen palvelimella %{instance}"
 
-#: lib/web/templates/email/report.text.eex:14
 #, elixir-format
+#: lib/web/templates/email/report.text.eex:14
 msgid "Reason"
 msgstr "Syy"
 
-#: lib/web/templates/email/password_reset.html.eex:61
 #, elixir-format
+#: lib/web/templates/email/password_reset.html.eex:61
 msgid "Reset Password"
 msgstr "Palauta salasana"
 
-#: lib/web/templates/email/password_reset.html.eex:41
 #, elixir-format
+#: lib/web/templates/email/password_reset.html.eex:41
 msgid "Resetting your password is easy. Just press the button below and follow the instructions. We'll have you up and running in no time."
 msgstr ""
 "Salasana on helppo palauttaa. Paina alla olevaa painiketta ja noudata "
 "ohjeita. Pääset tuota pikaa jatkamaan käyttöä."
 
-#: lib/web/email/user.ex:28
 #, elixir-format
+#: lib/web/email/user.ex:28
 msgid "Instructions to confirm your Mobilizon account on %{instance}"
 msgstr "Ohjeet Mobilizon-tilin vahvistamiseen palvelimella %{instance}"
 
-#: lib/web/email/admin.ex:23
 #, elixir-format
+#: lib/web/email/admin.ex:23
 msgid "New report on Mobilizon instance %{instance}"
 msgstr "Uusi raportti Mobilizon-palvelimella %{instance}"
 
+#, elixir-format
 #: lib/web/templates/email/before_event_notification.html.eex:51
 #: lib/web/templates/email/before_event_notification.text.eex:4
-#, elixir-format
 msgid "Go to event page"
 msgstr "Siirry tapahtuman sivulle"
 
-#: lib/web/templates/email/report.text.eex:1
 #, elixir-format
+#: lib/web/templates/email/report.text.eex:1
 msgid "New report from %{reporter} on %{instance}"
 msgstr "Uusi raportti käyttäjältä %{reporter} palvelimella %{instance}"
 
-#: lib/web/templates/email/event_participation_approved.text.eex:1
 #, elixir-format
+#: lib/web/templates/email/event_participation_approved.text.eex:1
 msgid "Participation approved"
 msgstr "Osallistuminen hyväksytty"
 
+#, elixir-format
 #: lib/web/templates/email/password_reset.html.eex:13
 #: lib/web/templates/email/password_reset.text.eex:1
-#, elixir-format
 msgid "Password reset"
 msgstr "Salasanan palautus"
 
-#: lib/web/templates/email/password_reset.text.eex:7
 #, elixir-format
+#: lib/web/templates/email/password_reset.text.eex:7
 msgid "Resetting your password is easy. Just click the link below and follow the instructions. We'll have you up and running in no time."
 msgstr ""
 "Salasana on helppo palauttaa. Paina alla olevaa linkkiä ja noudata ohjeita. "
 "Pääset tuota pikaa jatkamaan käyttöä."
 
-#: lib/web/templates/email/registration_confirmation.text.eex:5
 #, elixir-format
+#: lib/web/templates/email/registration_confirmation.text.eex:5
 msgid "You created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email."
 msgstr ""
 "Loit palvelimelle %{host} tilin tällä sähköpostiosoitteella. Aktivoi se "
 "yhdellä napsautuksella. Jos et luonut tiliä itse, voit jättää tämän viestin "
 "huomiotta."
 
-#: lib/web/email/participation.ex:92
 #, elixir-format
+#: lib/web/email/participation.ex:92
 msgid "Your participation to event %{title} has been approved"
 msgstr "Osallistumisesi tapahtumaan %{title} on hyväksytty"
 
-#: lib/web/email/participation.ex:71
 #, elixir-format
+#: lib/web/email/participation.ex:71
 msgid "Your participation to event %{title} has been rejected"
 msgstr "Osallistumisesi tapahtumaan %{title) on hylätty"
 
-#: lib/web/email/event.ex:35
 #, elixir-format
+#: lib/web/email/event.ex:35
 msgid "Event %{title} has been updated"
 msgstr "Tapahtumaa %{title} on päivitetty"
 
-#: lib/web/templates/email/event_updated.text.eex:15
 #, elixir-format
+#: lib/web/templates/email/event_updated.text.eex:15
 msgid "New title: %{title}"
 msgstr "Uusi otsikko: %{title}"
 
-#: lib/web/templates/email/password_reset.text.eex:5
 #, elixir-format
+#: lib/web/templates/email/password_reset.text.eex:5
 msgid "You requested a new password for your account on %{instance}."
 msgstr "Pyysit uutta salasanaa tilillesi palvelimella %{instance}."
 
+#, elixir-format
 #: lib/web/templates/email/email.html.eex:88
 #: lib/web/templates/email/email.text.eex:6
-#, elixir-format
 msgid "This is a demonstration site to test the beta version of Mobilizon."
 msgstr "Tällä esittelysivulla voit koekäyttää Mobilizonin beetaversiota."
 
-#: lib/web/templates/email/email.html.eex:85
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:85
 msgid "Warning"
 msgstr "Varoitus"
 
-#: lib/web/email/participation.ex:114
 #, elixir-format
+#: lib/web/email/participation.ex:114
 msgid "Confirm your participation to event %{title}"
 msgstr "Vahvista osallistumisesi tapahtumaan %{title}"
 
-#: lib/web/templates/api/privacy.html.eex:75
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:75
 msgctxt "terms"
 msgid "An internal ID for your current selected identity"
 msgstr "Valittuna olevan identiteettisi sisäinen tunniste"
 
-#: lib/web/templates/api/privacy.html.eex:74
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:74
 msgctxt "terms"
 msgid "An internal user ID"
 msgstr "Sisäinen käyttäjätunniste"
 
-#: lib/web/templates/api/privacy.html.eex:37
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:37
 msgctxt "terms"
 msgid "Any of the information we collect from you may be used in the following ways:"
 msgstr "Kaikkia sinulta kerättäviä tietoja voidaan käyttää seuraavin tavoin:"
 
-#: lib/web/templates/api/privacy.html.eex:9
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:9
 msgctxt "terms"
 msgid "Basic account information"
 msgstr "Tilin perustiedot"
 
-#: lib/web/templates/api/privacy.html.eex:25
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:25
 msgctxt "terms"
 msgid "Do not share any dangerous information over Mobilizon."
 msgstr "Älä jaa vaarallisia tietoja Mobilizonin kautta."
 
-#: lib/web/templates/api/privacy.html.eex:90
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:90
 msgctxt "terms"
 msgid "Do we disclose any information to outside parties?"
 msgstr "Luovutetaanko tietoja ulkopuolisille?"
 
-#: lib/web/templates/api/privacy.html.eex:68
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:68
 msgctxt "terms"
 msgid "Do we use cookies?"
 msgstr "Käytetäänkö evästeitä?"
 
-#: lib/web/templates/api/privacy.html.eex:51
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:51
 msgctxt "terms"
 msgid "How do we protect your information?"
 msgstr "Kuinka tietojasi suojataan?"
 
-#: lib/web/templates/api/privacy.html.eex:29
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:29
 msgctxt "terms"
 msgid "IPs and other metadata"
 msgstr "IP-osoitteet ja muu metadata"
 
-#: lib/web/templates/api/privacy.html.eex:78
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:78
 msgctxt "terms"
 msgid "If you delete these informations, you need to login again."
 msgstr "Jos poistat nämä tiedot, joudut kirjautumaan uudelleen."
 
-#: lib/web/templates/api/privacy.html.eex:87
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:87
 msgctxt "terms"
 msgid "Note: These informations are stored in your localStorage and not your cookies."
 msgstr "Huomaa: Nämä tiedot tallennetaan localStorage-tietoina eikä evästeinä."
 
-#: lib/web/templates/api/privacy.html.eex:17
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:17
 msgctxt "terms"
 msgid "Published events and comments"
 msgstr "Julkaistut tapahtumat ja kommentit"
 
-#: lib/web/templates/api/privacy.html.eex:64
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:64
 msgctxt "terms"
 msgid "Retain the IP addresses associated with registered users no more than 12 months."
 msgstr ""
 "Säilyttämään rekisteröityjen käyttäjien IP-osoitteita enintään 12 kuukautta."
 
-#: lib/web/templates/api/privacy.html.eex:76
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:76
 msgctxt "terms"
 msgid "Tokens to authenticate you"
 msgstr "Tunnistautumismerkkisi"
 
-#: lib/web/templates/api/privacy.html.eex:31
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:31
 msgctxt "terms"
 msgid "We also may retain server logs which include the IP address of every request to our server."
 msgstr ""
 "Myös palvelinlokeja, jotka sisältävät jokaisen palvelimelle tehdyn pyynnön "
 "IP-osoitteen, saatetaan säilyttää."
 
-#: lib/web/templates/api/privacy.html.eex:70
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:70
 msgctxt "terms"
 msgid "We store the following information on your device when you connect:"
 msgstr "Kun muodostat yhteyden, laitteellesi tallennetaan seuraavat tiedot:"
 
-#: lib/web/templates/api/privacy.html.eex:58
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:58
 msgctxt "terms"
 msgid "We will make a good faith effort to:"
 msgstr "Pyrimme parhaamme mukaan seuraavaan:"
 
-#: lib/web/templates/api/privacy.html.eex:35
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:35
 msgctxt "terms"
 msgid "What do we use your information for?"
 msgstr "Mihin käytämme tietojasi?"
 
-#: lib/web/templates/api/privacy.html.eex:57
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:57
 msgctxt "terms"
 msgid "What is our data retention policy?"
 msgstr "Millainen tietojensäilytyskäytäntö meillä on?"
 
-#: lib/web/templates/api/privacy.html.eex:67
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:67
 msgctxt "terms"
 msgid "You may irreversibly delete your account at any time."
 msgstr "Voit milloin tahansa poistaa tilisi pysyvästi."
 
-#: lib/web/templates/api/privacy.html.eex:115
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:115
 msgctxt "terms"
 msgid "Changes to our Privacy Policy"
 msgstr "Muutokset tietosuojakäytäntöön"
 
-#: lib/web/templates/api/privacy.html.eex:106
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:106
 msgctxt "terms"
 msgid "If this server is in the EU or the EEA: Our site, products and services are all directed to people who are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (<a href=\"https://en.wikipedia.org/wiki/General_Data_Protection_Regulation\">General Data Protection Regulation</a>) do not use this site."
 msgstr ""
@@ -303,8 +303,8 @@ msgstr ""
 "wiki/Yleinen_tietosuoja-asetus\">yleinen tietosuoja-asetus</a>) mukaisesti "
 "et voi käyttää tätä sivustoa."
 
-#: lib/web/templates/api/privacy.html.eex:109
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:109
 msgctxt "terms"
 msgid "If this server is in the USA: Our site, products and services are all directed to people who are at least 13 years old. If you are under the age of 13, per the requirements of COPPA (<a href=\"https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act\">Children's Online Privacy Protection Act</a>) do not use this site."
 msgstr ""
@@ -314,30 +314,30 @@ msgstr ""
 "27s_Online_Privacy_Protection_Act\">Children's Online Privacy Protection "
 "Act</a>) mukaisesti et voi käyttää tätä sivustoa."
 
-#: lib/web/templates/api/privacy.html.eex:117
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:117
 msgctxt "terms"
 msgid "If we decide to change our privacy policy, we will post those changes on this page."
 msgstr ""
 "Jos päätämme muuttaa tietosuojakäytäntöämme, muutoksesta kerrotaan tällä "
 "sivulla."
 
-#: lib/web/templates/api/privacy.html.eex:112
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:112
 msgctxt "terms"
 msgid "Law requirements can be different if this server is in another jurisdiction."
 msgstr ""
 "Lakisääteiset vaatimukset saattavat poiketa tästä, jos palvelin sijaitsee "
 "muulla lainkäyttöalueella."
 
-#: lib/web/templates/api/privacy.html.eex:103
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:103
 msgctxt "terms"
 msgid "Site usage by children"
 msgstr "Lapset sivuston käyttäjinä"
 
-#: lib/web/templates/api/privacy.html.eex:47
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:47
 msgctxt "terms"
 msgid "The email address you provide may be used to send you information, updates and notifications about other people\n    interacting with your content or sending you messages and to respond to inquiries, and/or other requests or\n    questions."
 msgstr ""
@@ -347,8 +347,8 @@ msgstr ""
 "kyselyihisi, tai muihin pyyntöihin tai kysymyksiin\n"
 "    liittyen."
 
-#: lib/web/templates/api/privacy.html.eex:45
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:45
 msgctxt "terms"
 msgid "To aid moderation of the community, for example comparing your IP address with other known ones to determine ban\n    evasion or other violations."
 msgstr ""
@@ -356,8 +356,8 @@ msgstr ""
 "muihin tiedossa oleviin osoitteisiin\n"
 "    porttikieltojen kiertämisen tai muiden rikkomusten havaitsemiseksi."
 
-#: lib/web/templates/api/privacy.html.eex:43
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:43
 msgctxt "terms"
 msgid "To provide the core functionality of Mobilizon. Depending on this instance's policy you may only be able to\n    interact with other people's content and post your own content if you are logged in."
 msgstr ""
@@ -366,89 +366,89 @@ msgstr ""
 "    vaikuttaminen ja oman sisällön julkaiseminen saattaa olla mahdollista "
 "vain sisäänkirjautuneena."
 
-#: lib/web/templates/api/privacy.html.eex:6
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:6
 msgctxt "terms"
 msgid "What information do we collect?"
 msgstr "Mitä tietoja kerätään?"
 
-#: lib/web/email/user.ex:176
 #, elixir-format
+#: lib/web/email/user.ex:176
 msgid "Mobilizon on %{instance}: confirm your email address"
 msgstr "Mobilizon palvelimella %{instance}: vahvista sähköpostiosoitteesi"
 
-#: lib/web/email/user.ex:152
 #, elixir-format
+#: lib/web/email/user.ex:152
 msgid "Mobilizon on %{instance}: email changed"
 msgstr "Mobilizon palvelimella %{instance}: sähköpostiosoite vaihdettu"
 
-#: lib/web/email/notification.ex:46
 #, elixir-format
+#: lib/web/email/notification.ex:46
 msgid "One event planned today"
 msgid_plural "%{nb_events} events planned today"
 msgstr[0] "Yksi suunniteltu tapahtuma tänään"
 msgstr[1] "%{nb_events} suunniteltua tapahtumaa tänään"
 
+#, elixir-format
 #: lib/web/templates/email/on_day_notification.html.eex:38
 #: lib/web/templates/email/on_day_notification.text.eex:4
-#, elixir-format
 msgid "You have one event today:"
 msgid_plural "You have %{total} events today:"
 msgstr[0] "Sinulla on tänään yksi tapahtuma:"
 msgstr[1] "Sinulla on tänään %{total} tapahtumaa:"
 
-#: lib/web/templates/email/group_invite.text.eex:3
 #, elixir-format
+#: lib/web/templates/email/group_invite.text.eex:3
 msgid "%{inviter} just invited you to join their group %{group}"
 msgstr "%{inviter} kutsui sinut ryhmään %{group}"
 
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:13
 #: lib/web/templates/email/group_invite.text.eex:1
-#, elixir-format
 msgid "Come along!"
 msgstr "Tule mukaan!"
 
-#: lib/web/email/notification.ex:24
 #, elixir-format
+#: lib/web/email/notification.ex:24
 msgid "Don't forget to go to %{title}"
 msgstr "Muista %{title}"
 
+#, elixir-format
 #: lib/web/templates/email/before_event_notification.html.eex:38
 #: lib/web/templates/email/before_event_notification.text.eex:3
-#, elixir-format
 msgid "Get ready for %{title}"
 msgstr "%{title} tulee, oletko valmis?"
 
-#: lib/web/templates/email/group_invite.html.eex:59
 #, elixir-format
+#: lib/web/templates/email/group_invite.html.eex:59
 msgid "See my groups"
 msgstr "Näytä omat ryhmät"
 
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:45
 #: lib/web/templates/email/group_invite.text.eex:5
-#, elixir-format
 msgid "To accept this invitation, head over to your groups."
 msgstr "Hyväksy kutsu siirtymällä omiin ryhmiisi."
 
-#: lib/web/templates/email/before_event_notification.text.eex:5
 #, elixir-format
+#: lib/web/templates/email/before_event_notification.text.eex:5
 msgid "View the event on: %{link}"
 msgstr "Katso päivitetty tapahtuma: %{linkki}"
 
-#: lib/web/email/group.ex:28
 #, elixir-format
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr "%{inviter} kutsui sinut ryhmään %{group}"
 
-#: lib/web/email/notification.ex:70
 #, elixir-format
+#: lib/web/email/notification.ex:70
 msgid "One event planned this week"
 msgid_plural "%{nb_events} events planned this week"
 msgstr[0] "Yksi suunniteltu tapahtuma tällä viikolla"
 msgstr[1] "%{nb_events} suunniteltua tapahtumaa tällä viikolla"
 
-#: lib/web/email/notification.ex:92
 #, elixir-format
+#: lib/web/email/notification.ex:92
 msgid "One participation request for event %{title} to process"
 msgid_plural "%{number_participation_requests} participation requests for event %{title} to process"
 msgstr[0] "Yksi osallistujapyyntö tapahtumaan %{title} odottaa käsittelyä"
@@ -456,21 +456,21 @@ msgstr[1] ""
 "%{number_participation_requests} osallistujapyyntöä tapahtumaan %{title} "
 "odottaa käsittelyä"
 
+#, elixir-format
 #: lib/web/templates/email/notification_each_week.html.eex:38
 #: lib/web/templates/email/notification_each_week.text.eex:4
-#, elixir-format
 msgid "You have one event this week:"
 msgid_plural "You have %{total} events this week:"
 msgstr[0] "Sinulla on tällä viikolla yksi tapahtuma:"
 msgstr[1] "Sinulla on tällä viikolla %{total} tapahtumaa:"
 
-#: lib/service/metadata/utils.ex:27
 #, elixir-format
+#: lib/service/metadata/utils.ex:27
 msgid "The event organizer didn't add any description."
 msgstr "Tapahtuman järjestäjä ei ole lisännyt kuvausta."
 
-#: lib/web/templates/api/privacy.html.eex:54
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:54
 msgctxt "terms"
 msgid "We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information. Among other things, your browser session, as well as the traffic between your applications and the API, are secured with SSL/TLS, and your password is hashed using a strong one-way algorithm."
 msgstr ""
@@ -479,8 +479,8 @@ msgstr ""
 "sovellusten ja sovellusrajapinnan välinen tietoliikenne ovat SSL/TLS-"
 "suojattuja, ja salasanasi salataan vahvalla yksisuuntaisella algoritmilla."
 
-#: lib/web/templates/api/privacy.html.eex:94
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:94
 msgctxt "terms"
 msgid "No. We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety."
 msgstr ""
@@ -492,8 +492,8 @@ msgstr ""
 "välttämätöntä lain tai sivustomme noudattamisen tahi meidän tai muiden "
 "oikeuksien, omaisuuden tai turvallisuuden suojelemisen kannalta."
 
-#: lib/web/templates/api/privacy.html.eex:61
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:61
 msgctxt "terms"
 msgid "Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days."
 msgstr ""
@@ -501,8 +501,8 @@ msgstr ""
 "sisältäviä palvelinlokeja, mikäli sellaisia pidetään, enintään 90 päivän "
 "ajan."
 
-#: lib/web/templates/api/privacy.html.eex:10
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:10
 msgctxt "terms"
 msgid "We collect information from you when you register on this instance and gather data when you participate in the platform by reading, writing, and interacting with content shared here. If you register on this instance, you will be asked to enter <b>an e-mail address, a password</b> (hashed) and at least <b>an username</b>. Your e-mail address will be verified by an email containing a unique link. If that link is visited, we know that you control the e-mail address. You may also enter additional profile information such as <b>a display name and biography, and upload a profile picture and header image</b>. The username, display name, biography, profile picture and header image <b>are always listed publicly</b>. <b>You may however visit this instance without registering</b>."
 msgstr ""
@@ -518,8 +518,8 @@ msgstr ""
 "otsikkokuva <b>ovat aina julkista tietoa</b>. <b>Voit myös käyttää "
 "palvelinta rekisteröitymättä</b>."
 
-#: lib/web/templates/api/privacy.html.eex:80
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:80
 msgctxt "terms"
 msgid "If you're not connected, we don't store any information on your device, unless you participate in an event anonymously. In this specific case we store the hash of an unique identifier for the event and participation status in your browser so that we may display participation status. Deleting these informations will only stop displaying participation status in your browser."
 msgstr ""
@@ -529,8 +529,8 @@ msgstr ""
 "voidaan näyttää. Näiden tietojen poisto vaikuttaa vain siten, että "
 "osallistumisen tilaa ei enää näytetä selaimessa."
 
-#: lib/web/templates/api/privacy.html.eex:19
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:19
 msgctxt "terms"
 msgid "Your <b>events</b> and <b>comments</b> are delivered to other instances that follow your own, meaning they are delivered to different instances and copies are stored there. When you delete events or comments, this is likewise delivered to these other instances. All interactions related to events features - such as joining an event - or group features - such as managing resources - are federated as well. Please keep in mind that the operators of the instance and any receiving instances may view such messages and informations, and that recipients may screenshot, copy or otherwise re-share them."
 msgstr ""
@@ -543,8 +543,8 @@ msgstr ""
 "voivat kopioida viestin tekstinä tai kuvankaappauksena tai muulla tavoin "
 "levittää niitä edelleen."
 
-#: lib/web/templates/api/privacy.html.eex:99
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:99
 msgctxt "terms"
 msgid "Your content may be downloaded by other instances in the network. Your public events and comments are delivered to the instances following your own instance. Content created through a group is fowarded to all the instances of all the members of the group, in so far as these members reside on a different instance than this one."
 msgstr ""
@@ -554,20 +554,20 @@ msgstr ""
 "jäsenten kaikille palvelimille, mikäli ryhmässä on muita kuin tätä "
 "palvelinta käyttäviä jäseniä."
 
-#: lib/web/templates/api/terms.html.eex:23
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:23
 msgctxt "terms"
 msgid "Accepting these Terms"
 msgstr "Ehtojen hyväksyminen"
 
-#: lib/web/templates/api/terms.html.eex:27
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:27
 msgctxt "terms"
 msgid "Changes to these Terms"
 msgstr "Ehtojen muutokset"
 
-#: lib/web/templates/api/terms.html.eex:30
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:30
 msgctxt "terms"
 msgid "We reserve the right to modify these Terms at any time. For instance, we may need to change these Terms if we come out with a new feature or for some other reason."
 msgstr ""
@@ -575,8 +575,8 @@ msgstr ""
 "esimerkiksi olla tarpeen muuttaa, jos käyttöön otetaan uusia ominaisuuksia, "
 "tai muusta syystä."
 
-#: lib/web/templates/api/terms.html.eex:85
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:85
 msgctxt "terms"
 msgid "A lot of the content on the Service is from you and others, and we don't review, verify or authenticate it, and it may include inaccuracies or false information. We make no representations, warranties, or guarantees relating to the quality, suitability, truth, accuracy or completeness of any content contained in the Service. You acknowledge sole responsibility for and assume all risk arising from your use of or reliance on any content."
 msgstr ""
@@ -587,16 +587,16 @@ msgstr ""
 "Olet yksin vastuussa sisällön käyttämisestä, siihen luottamisesta ja siihen "
 "liittyvistä riskeistä."
 
-#: lib/web/templates/api/terms.html.eex:60
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:60
 msgctxt "terms"
 msgid "Also, you agree that you will not do any of the following in connection with the Service or other users:"
 msgstr ""
 "Lisäksi sitoudut olemaan tekemättä palvelun tai muiden käyttäjien osalta "
 "mitään seuraavista:"
 
-#: lib/web/templates/api/terms.html.eex:65
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:65
 msgctxt "terms"
 msgid "Circumvent or attempt to circumvent any filtering, security measures, rate limits or other features designed to protect the Service, users of the Service, or third parties."
 msgstr ""
@@ -604,22 +604,22 @@ msgstr ""
 "suodatus- ja turvallisuuskeinojen, käyttömäärärajoitusten tai muiden "
 "vastaavien ominaisuuksien kiertäminen tai kiertämisen yritys"
 
-#: lib/web/templates/api/terms.html.eex:64
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:64
 msgctxt "terms"
 msgid "Collect any personal information about other users, or intimidate, threaten, stalk or otherwise harass other users of the Service;"
 msgstr ""
 "palvelun muiden käyttäjien henkilötietojen kerääminen tai heidän "
 "ahdisteleminen, uhkaaminen, seuraaminen tai häiritseminen muilla tavoin"
 
-#: lib/web/templates/api/terms.html.eex:55
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:55
 msgctxt "terms"
 msgid "Content that is illegal or unlawful, that would otherwise create liability;"
 msgstr "laittoman sisällön oikeudellisiin seuraamuksiin johtava lähettäminen"
 
-#: lib/web/templates/api/terms.html.eex:56
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:56
 msgctxt "terms"
 msgid "Content that may infringe or violate any patent, trademark, trade secret, copyright, right of privacy, right of publicity or other intellectual or other right of any party;"
 msgstr ""
@@ -627,56 +627,56 @@ msgstr ""
 "yksityisyydensuojaa, julkisuusoikeutta tai muuta immateriaali- tai muuta "
 "oikeutta loukkaavan sisällön lähettäminen"
 
-#: lib/web/templates/api/terms.html.eex:42
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:42
 msgctxt "terms"
 msgid "Creating Accounts"
 msgstr "Tilien luominen"
 
-#: lib/web/templates/api/terms.html.eex:89
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:89
 msgctxt "terms"
 msgid "Entire Agreement"
 msgstr "Koko sopimusteksti"
 
-#: lib/web/templates/api/terms.html.eex:92
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:92
 msgctxt "terms"
 msgid "Feedback"
 msgstr "Palaute"
 
-#: lib/web/templates/api/terms.html.eex:83
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:83
 msgctxt "terms"
 msgid "Hyperlinks and Third Party Content"
 msgstr "Linkit ja kolmansien osapuolten sisältö"
 
-#: lib/web/templates/api/terms.html.eex:88
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:88
 msgctxt "terms"
 msgid "If you breach any of these Terms, we have the right to suspend or disable your access to or use of the Service."
 msgstr ""
 "Jos toimit näiden ehtojen vastaisesti, voimme poistaa tai keskeyttää "
 "käyttöoikeutesi palveluun."
 
-#: lib/web/templates/api/terms.html.eex:36
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:36
 msgctxt "terms"
 msgid "If you continue to use the Service after the revised Terms go into effect, then you have accepted the revised Terms."
 msgstr ""
 "Jos jatkat palvelun käyttöä muutettujen ehtojen astuttua voimaan, osoitat "
 "hyväksyneesi muutetut ehdot."
 
-#: lib/web/templates/api/terms.html.eex:63
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:63
 msgctxt "terms"
 msgid "Impersonate or post on behalf of any person or entity or otherwise misrepresent your affiliation with a person or entity;"
 msgstr ""
 "luvaton toisen henkilön tai tahon nimissä esiintyminen tai julkaiseminen tai "
 "muunlainen valheellisen yhteyden ilmaiseminen"
 
-#: lib/web/templates/api/terms.html.eex:48
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:48
 msgctxt "terms"
 msgid "Our Service allows you and other users to post, link and otherwise make available content. You are responsible for the content that you make available to the Service, including its legality, reliability, and appropriateness."
 msgstr ""
@@ -685,26 +685,26 @@ msgstr ""
 "saataville saattamastasi sisällöstä sekä sen laillisuudesta, "
 "luotettavuudesta ja sopivaisuudesta."
 
-#: lib/web/templates/api/terms.html.eex:39
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:39
 msgctxt "terms"
 msgid "Privacy Policy"
 msgstr "Tietosuojakäytäntö"
 
-#: lib/web/templates/api/terms.html.eex:95
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:95
 msgctxt "terms"
 msgid "Questions & Contact Information"
 msgstr "Kysymykset ja yhteystiedot"
 
-#: lib/web/templates/api/terms.html.eex:87
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:87
 msgctxt "terms"
 msgid "Termination"
 msgstr "Lopettaminen"
 
-#: lib/web/templates/api/terms.html.eex:62
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:62
 msgctxt "terms"
 msgid "Use the Service in any manner that could interfere with, disrupt, negatively affect or inhibit other users from fully enjoying the Service or that could damage, disable, overburden or impair the functioning of the Service;"
 msgstr ""
@@ -712,8 +712,8 @@ msgstr ""
 "käyttäjiä heidän käyttäessään palvelua, tai joka voi vahingoittaa, estää, "
 "ylikuormittaa tai rajoittaa palvelun toimivuutta"
 
-#: lib/web/templates/api/terms.html.eex:49
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:49
 msgctxt "terms"
 msgid "When you post, link or otherwise make available content to the Service, you grant us the right and license to display and distribute your content on or through the Service (including via applications). We may format your content for display throughout the Service, but we will not edit or revise the substance of your content itself. The displaying and distribution of your content happens strictly only according to the visibility rules you have set for the content. We will not modify the visibility of the content you have set."
 msgstr ""
@@ -725,14 +725,14 @@ msgstr ""
 "sisällölle asettamiesi näkyvyysehtojen mukaisesti. Emme muuta sisällölle "
 "asettamiasi näkyvyysehtoja."
 
-#: lib/web/templates/api/terms.html.eex:47
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:47
 msgctxt "terms"
 msgid "Your Content & Conduct"
 msgstr "Oma sisältö ja käytös"
 
-#: lib/web/templates/api/terms.html.eex:84
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:84
 msgctxt "terms"
 msgid "<b>%{instance_name}</b> makes no claim or representation regarding, and accepts no responsibility for third party websites accessible by hyperlink from the Service or websites linking to the Service. When you leave the Service, you should be aware that these Terms and our policies no longer govern. The inclusion of any link does not imply endorsement by <b>%{instance_name}</b> of the site. Use of any such linked website is at the user's own risk."
 msgstr ""
@@ -744,8 +744,8 @@ msgstr ""
 "sivuston. Linkitettyjen verkkosivujen käyttö tapahtuu käyttäjän omalla "
 "vastuulla."
 
-#: lib/web/templates/api/terms.html.eex:68
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:68
 msgctxt "terms"
 msgid "Finally, your use of the Service is also subject to acceptance of <a href=\"/rules\">the instance's own specific rules</a> regarding the code of conduct and moderation rules. Breaking those rules may also result in your account being disabled or suspended."
 msgstr ""
@@ -754,24 +754,24 @@ msgstr ""
 "hyväksymistä. Sääntöjen rikkomisesta voi seurata tilisi tilapäinen tai "
 "pysyvä käytöstäpoisto."
 
-#: lib/web/templates/api/terms.html.eex:81
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:81
 msgctxt "terms"
 msgid "For full details about the Mobilizon software <a href=\"https://joinmobilizon.org\">see here</a>."
 msgstr ""
 "Katso <a href=\"https://joinmobilizon.org\">täältä</a> tarkempia Mobilizon-"
 "ohjelmaa koskevia tietoja."
 
-#: lib/web/templates/api/terms.html.eex:40
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:40
 msgctxt "terms"
 msgid "For information about how we collect and use information about users of the Service, please check out our <a href=\"/privacy\">privacy policy</a>."
 msgstr ""
 "<a href=\"/privacy\">Tietosuojakäytännössämme</a> kerrotaan, kuinka keräämme "
 "ja käytämme palvelun käyttäjien tietoja."
 
-#: lib/web/templates/api/terms.html.eex:18
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:18
 msgctxt "terms"
 msgid "Here are the important things you need to know about accessing and using the <b>%{instance_name}</b> (<a href=\"https://%{instance_url}\">%{instance_url}</a>) website and service (collectively, \"Service\"). These are our terms of service (\"Terms\"). Please read them carefully."
 msgstr ""
@@ -780,8 +780,8 @@ msgstr ""
 "palvelua (yhteisesti ”palvelu”). Ne ovat käyttöehtomme (”ehdot”). Lue ne "
 "huolellisesti."
 
-#: lib/web/templates/api/terms.html.eex:33
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:33
 msgctxt "terms"
 msgid "If we make major changes, we will notify our users in a clear and prominent manner. Minor changes may only be highlighted in the footer of our website. It is your responsibility to check the website regularly for changes to these Terms."
 msgstr ""
@@ -790,8 +790,8 @@ msgstr ""
 "huomautuksella verkkosivun alaosassa. Verkkosivun ehdoissa tapahtuvien "
 "muutosten säännöllinen tarkistaminen on omalla vastuullasi."
 
-#: lib/web/templates/api/terms.html.eex:53
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:53
 msgctxt "terms"
 msgid "In order to make <b>%{instance_name}</b> a great place for all of us, please do not post, link and otherwise make available on or through the Service any of the following:"
 msgstr ""
@@ -799,16 +799,16 @@ msgstr ""
 "julkaise, linkitä tai muulla tavoin saata palvelussa tai sen välityksellä "
 "saataville mitään seuraavista:"
 
-#: lib/web/templates/api/terms.html.eex:57
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:57
 msgctxt "terms"
 msgid "Private information of any third party (e.g., addresses, phone numbers, email addresses, Social Security numbers and credit card numbers); and"
 msgstr ""
 "kolmannen osapuolen yksityisiä tietoja (esim. osoitteita, puhelinnumeroita, "
 "sähköpostiosoitteita, henkilötunnuksia ja maksukorttien numeroita)"
 
-#: lib/web/templates/api/terms.html.eex:52
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:52
 msgctxt "terms"
 msgid "Since Mobilizon is a distributed network, it is possible, depending on the visibility rules set to your content, that your content has been distributed to other Mobilizon instances. When you delete your content, we will request those other instances to also delete the content. Our responsibility on the content being deleted from those other instances ends here. If for some reason, some other instance does not delete the content, we cannot be held responsible."
 msgstr ""
@@ -819,8 +819,8 @@ msgstr ""
 "sisällön poistamisesta päättyy siihen. Jos jokin toinen palvelin ei syystä "
 "tai toisesta poista sisältöä, emme ole siitä vastuussa."
 
-#: lib/web/templates/api/terms.html.eex:90
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:90
 msgctxt "terms"
 msgid "These Terms constitute the entire agreement between you and <b>%{instance_name}</b> regarding the use of the Service, superseding any prior agreements between you and <b>%{instance_name}</b> relating to your use of the Service."
 msgstr ""
@@ -829,8 +829,8 @@ msgstr ""
 "aiemmat sinun ja palvelimen <b>%{instance_name}</b> väliset palvelun käyttöä "
 "koskevat sopimukset."
 
-#: lib/web/templates/api/terms.html.eex:80
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:80
 msgctxt "terms"
 msgid "This Service runs on a Mobilizon instance. This source code is licensed under an <a href=\"https://tldrlegal.com/license/gnu-affero-general-public-license-v3-(agpl-3.0)\">AGPLv3 license</a> which means you are allowed to and even encouraged to take the source code, modify it and use it."
 msgstr ""
@@ -840,16 +840,16 @@ msgstr ""
 "tarkoittaa, että lähdekoodin lataaminen, muokkaaminen ja käyttö on paitsi "
 "sallittua myös kannustettavaa."
 
-#: lib/web/templates/api/terms.html.eex:58
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:58
 msgctxt "terms"
 msgid "Viruses, corrupted data or other harmful, disruptive or destructive files or code."
 msgstr ""
 "Virukset, vioittuneet tiedot tai muut haitalliset, häiritsevät tai tuhoa "
 "aiheuttavat tiedostot tai koodikatkelmat."
 
-#: lib/web/templates/api/terms.html.eex:50
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:50
 msgctxt "terms"
 msgid "We cannot be held responsible should a programming or administrative error make your content visible to a larger audience than you had intended. Aside from our limited right to your content, you retain all of your rights to the content you post, link and otherwise make available on or through the Service."
 msgstr ""
@@ -859,16 +859,16 @@ msgstr ""
 "julkaisemaasi, linkittämääsi tai muulla tavoin palvelussa tai sen kautta "
 "saataville saattamaasi sisältöä koskevat oikeudet säilyvät sinulla."
 
-#: lib/web/templates/api/terms.html.eex:45
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:45
 msgctxt "terms"
 msgid "We will not be liable for any loss that you may incur as a result of someone else using your email or password, either with or without your knowledge."
 msgstr ""
 "Emme ole vastuussa seurauksista, jos joku muu käyttää sähköpostiosoitettasi "
 "ja salasanaasi joko sinun tietäen tai tietämättäsi."
 
-#: lib/web/templates/api/terms.html.eex:43
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:43
 msgctxt "terms"
 msgid "When you create an account you also agree to maintain the security and confidentiality of your password and accept all risks of unauthorized access to your account data and any other information you provide to <b>%{instance_name}</b>."
 msgstr ""
@@ -877,8 +877,8 @@ msgstr ""
 "luovuttamiesi tilitietojen ja muiden tietojen luvattomaan käyttöön liittyvät "
 "riskit."
 
-#: lib/web/templates/api/terms.html.eex:51
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:51
 msgctxt "terms"
 msgid "You can remove the content that you posted by deleting it. Once you delete your content, it will not appear on the Service, but copies of your deleted content may remain in our system or backups for some period of time. Web server access logs might also be stored for some time in the system."
 msgstr ""
@@ -887,8 +887,8 @@ msgstr ""
 "järjestelmässämme tai varmuuskopioissamme. Niin ikään www-palvelimen "
 "käyttölokeja säilytetään järjestelmässä jonkin aikaa."
 
-#: lib/web/templates/api/terms.html.eex:24
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:24
 msgctxt "terms"
 msgid "If you access or use the Service, it means you agree to be bound by all of the terms below. So, before you use the Service, please read all of the terms. If you don't agree to all of the terms below, please do not use the Service. Also, if a term does not make sense to you, please let us know by contacting %{contact}."
 msgstr ""
@@ -897,23 +897,23 @@ msgstr ""
 "esitettyjä ehtoja, älä käytä palvelua. Jos et ymmärrä jotakin ehtoa, voit "
 "ottaa meihin yhteyttä osoitteeseen %{contact}."
 
-#: lib/web/templates/api/terms.html.eex:96
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:96
 msgctxt "terms"
 msgid "Questions or comments about the Service may be directed to us at %{contact}"
 msgstr ""
 "Meille voi lähettää palvelua koskevia kysymyksiä ja kommentteja osoitteeseen "
 "%{contact}"
 
-#: lib/web/templates/api/terms.html.eex:79
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:79
 msgctxt "terms"
 msgid "Source code"
 msgstr "Lähdekoodi"
 
+#, elixir-format
 #: lib/web/templates/api/privacy.html.eex:3
 #: lib/web/templates/api/terms.html.eex:15
-#, elixir-format
 msgctxt "terms"
 msgid "Some terms, technical or otherwise, used in the text below may cover concepts that are difficult to grasp. We provide <a href=\"/glossary\">a glossary</a> to help you understand them better."
 msgstr ""
@@ -921,16 +921,16 @@ msgstr ""
 "ymmärtää. Laatimamme <a href=\"/glossary\">sanasto</a> voi auttaa niiden "
 "ymmärtämisessä."
 
-#: lib/web/templates/api/terms.html.eex:93
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:93
 msgctxt "terms"
 msgid "We love feedback. Please let us know what you think of the Service, these Terms and, in general, <b>%{instance_name}</b>."
 msgstr ""
 "Pidämme palautteesta. Kerro meille, mitä mieltä olet palvelusta, näistä "
 "ehdoista ja yleisesti palvelimesta <b>%{instance_name}</b>."
 
-#: lib/web/templates/api/terms.html.eex:74
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:74
 msgctxt "terms"
 msgid "Instance administrators (and community moderators, given the relevant access) are responsible for monitoring and acting on flagged content and other user reports, and have the right and responsibility to remove or edit content that is not aligned to this Instance set of rules, or to suspend, block or ban (temporarily or permanently) any account, community, or instance for breaking these terms, or for other behaviours that they deem inappropriate, threatening, offensive, or harmful."
 msgstr ""
@@ -943,14 +943,14 @@ msgstr ""
 "toimivat muulla tavoin asiattomasti, uhkaavasti, hyökkäävästi tai "
 "vahingollisesti."
 
-#: lib/web/templates/api/terms.html.eex:71
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:71
 msgctxt "terms"
 msgid "Our responsability"
 msgstr "Meidän vastuumme"
 
-#: lib/web/templates/api/terms.html.eex:20
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:20
 msgctxt "terms"
 msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors, supported by <a href=\"https://framasoft.org\">Framasoft</a>, a french not-for-profit popular educational organization advocating for Free/Libre Software. Unless explicity stated, this Mobilizon instance is an independant service using Mobilizon's source code. You may find more informations about this instance on the <a href=\"/about/instance\">\"About this instance\" page</a>."
 msgstr ""
@@ -963,15 +963,15 @@ msgstr ""
 "itsenäinen palvelu. Voit lukea lisää tästä palvelimesta <a href=\"/about/"
 "instance\">”Tietoja tästä palvelimesta” -sivulta</a>."
 
-#: lib/web/templates/api/terms.html.eex:6
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:6
 msgctxt "terms"
 msgid "<b>%{instance_name}</b> will not use or transmit or resell your personal data"
 msgstr ""
 "<b>%{instance_name}</b> ei käytä, lähetä edelleen tai myy henkilötietojasi"
 
-#: lib/web/templates/api/terms.html.eex:44
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:44
 msgctxt "terms"
 msgid "If you discover or suspect any Service security breaches, please let us know as soon as possible. For security holes in the Mobilizon software itself, please contact <a href=\"https://framagit.org/framasoft/mobilizon/\">its contributors</a> directly."
 msgstr ""
@@ -980,16 +980,16 @@ msgstr ""
 "aukkojen osalta ota yhteyttä suoraan <a href=\"https://framagit.org/"
 "framasoft/mobilizon/\">ohjelman tekijöihin</a>."
 
-#: lib/web/templates/api/terms.html.eex:77
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:77
 msgctxt "terms"
 msgid "Instance administrators should ensure that every community hosted on the instance is properly moderated according to the defined rules."
 msgstr ""
 "Palvelimen ylläpitäjien tulee varmistaa, että kaikkia palvelimella toimivia "
 "yhteisöjä moderoidaan sääntöjen mukaisesti."
 
-#: lib/web/templates/api/terms.html.eex:98
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:98
 msgctxt "terms"
 msgid "Originally adapted from the <a href=\"https://joindiaspora.com/terms\">Diaspora*</a> and <a href=\"https://github.com/appdotnet/terms-of-service\">App.net</a> privacy policies, also licensed under <a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>."
 msgstr ""
@@ -998,8 +998,8 @@ msgstr ""
 "a> tietosuojakäytännöistä, lisäksi lisensoitu <a href=\"https"
 "://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA -lisenssillä</a>."
 
-#: lib/web/templates/api/privacy.html.eex:119
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:119
 msgctxt "terms"
 msgid "Originally adapted from the <a href=\"https://mastodon.social/terms\">Mastodon</a> and <a href=\"https://github.com/discourse/discourse\">Discourse</a> privacy policies, also licensed under <a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>."
 msgstr ""
@@ -1008,129 +1008,129 @@ msgstr ""
 "tietosuojakäytännöistä, lisäksi lisensoitu <a href=\"https://creativecommons."
 "org/licenses/by-sa/4.0/\">CC BY-SA -lisenssillä</a>."
 
-#: lib/web/templates/api/terms.html.eex:3
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:3
 msgctxt "terms"
 msgid "Short version"
 msgstr "Lyhyt versio"
 
-#: lib/web/templates/api/terms.html.eex:9
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:9
 msgctxt "terms"
 msgid "The service is provided without warranties and these terms may change in the future"
 msgstr ""
 "Palvelu tarjotaan ilman minkäänlaista takuuta, ja nämä ehdot voivat "
 "myöhemmin muuttua"
 
-#: lib/web/templates/api/privacy.html.eex:118
 #, elixir-format
+#: lib/web/templates/api/privacy.html.eex:118
 msgctxt "terms"
 msgid "This document is licensed under <a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>. It was last updated June 18, 2020."
 msgstr ""
 "Tämän asiakirjan lisenssinä on <a href=\"https://creativecommons.org/"
 "licenses/by-sa/4.0/\">CC BY-SA</a>. Se päivitettiin viimeksi 18.6.2020."
 
-#: lib/web/templates/api/terms.html.eex:97
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:97
 msgctxt "terms"
 msgid "This document is licensed under <a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">CC BY-SA</a>. It was last updated June 22, 2020."
 msgstr ""
 "Tämän asiakirjan lisenssinä on <a href=\"https://creativecommons.org/"
 "licenses/by-sa/4.0/\">CC BY-SA</a>. Se päivitettiin viimeksi 22.6.2020."
 
-#: lib/web/templates/api/terms.html.eex:8
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:8
 msgctxt "terms"
 msgid "You must respect other people and <b>%{instance_name}</b>'s rules when using the service"
 msgstr ""
 "Kun käytät palvelua, kunnioita muita ihmisiä ja palvelimen "
 "<b>%{instance_name}</b> sääntöjä"
 
-#: lib/web/templates/api/terms.html.eex:7
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:7
 msgctxt "terms"
 msgid "You must respect the law when using <b>%{instance_name}</b>"
 msgstr "Noudata lakia käyttäessäsi palvelinta <b>%{instance_name}</b>"
 
-#: lib/web/templates/api/terms.html.eex:5
 #, elixir-format
+#: lib/web/templates/api/terms.html.eex:5
 msgctxt "terms"
 msgid "Your content is yours"
 msgstr "Sisältösi kuuluu sinulle"
 
-#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:58
 #, elixir-format
+#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:58
 msgid "Confirm my e-mail address"
 msgstr "Vahvista sähköpostiosoite"
 
+#, elixir-format
 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:13
 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:1
-#, elixir-format
 msgid "Confirm your e-mail"
 msgstr "Vahvista sähköpostiosoite"
 
+#, elixir-format
 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:38
 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:3
-#, elixir-format
 msgid "Hi there! You just registered to join this event: « %{title} ». Please confirm the e-mail address you provided:"
 msgstr ""
 "Hei! Rekisteröidyit juuri tapahtumaan ”%{title}”. Vahvista ilmoittamasi "
 "sähköpostiosoite:"
 
+#, elixir-format
 #: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:12
-#, elixir-format
 msgid "Need help? Is something not working as expected?"
 msgstr "Tarvitsetko apua? Eikö kaikki toimi niin kuin pitäisi?"
 
-#: lib/web/templates/email/registration_confirmation.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/registration_confirmation.html.eex:38
 msgid "You created an account on <b>%{host}</b> with this email address. You are one click away from activating it."
 msgstr ""
 "Loit palvelimelle <b>%{host}</b> tilin tällä sähköpostiosoitteella. Aktivoi "
 "se yhdellä napsautuksella."
 
-#: lib/web/templates/email/report.html.eex:41
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:41
 msgid "<b>%{reporter_name}</b> (%{reporter_username}) reported the following content."
 msgstr ""
 "<b>%{reporter_name}</b> (%{reporter_username}) raportoi seuraavan sisällön."
 
-#: lib/web/templates/email/report.html.eex:13
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:13
 msgid "New report on <b>%{instance}</b>"
 msgstr "Uusi raportti palvelimella <b>%{instance}</b>"
 
-#: lib/web/templates/email/email_changed_old.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/email_changed_old.html.eex:38
 msgid "The email address for your account on <b>%{host}</b> is being changed to:"
 msgstr ""
 "Palvelimella <b>%{host}</b> olevan tilisi sähköpostiosoitteeksi vaihdetaan:"
 
-#: lib/web/templates/email/password_reset.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/password_reset.html.eex:38
 msgid "You requested a new password for your account on <b>%{instance}</b>."
 msgstr "Pyysit uutta salasanaa tilillesi palvelimella <b>%{instance}</b>."
 
-#: lib/web/templates/email/email.text.eex:9
 #, elixir-format
+#: lib/web/templates/email/email.text.eex:9
 msgid "Mobilizon is still under development, we will add new features along the updates, until the release of version 1 of the software in the fall of 2020."
 msgstr ""
 "Mobilizonin kehitystyö on vielä käynnissä, ja tälle sivulle lisätään "
 "säännöllisesti uusia ominaisuuksia, kunnes ohjelman versio 1 julkaistaan "
 "vuoden 2020 alkupuoliskolla."
 
-#: lib/web/templates/email/email.text.eex:7
 #, elixir-format
+#: lib/web/templates/email/email.text.eex:7
 msgid "Please do not use it for real purposes."
 msgstr "Älä käytä todellisiin tarkoituksiin."
 
+#, elixir-format
 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:45
 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:6 lib/web/templates/email/event_updated.html.eex:131
 #: lib/web/templates/email/event_updated.text.eex:24 lib/web/templates/email/notification_each_week.html.eex:70
 #: lib/web/templates/email/notification_each_week.text.eex:14 lib/web/templates/email/on_day_notification.html.eex:70
 #: lib/web/templates/email/on_day_notification.text.eex:14
-#, elixir-format
 msgid "Would you wish to cancel your attendance, visit the event page through the link above and click the « Attending » button."
 msgid_plural "Would you wish to cancel your attendance to one or several events, visit the event pages through the links above and click the « Attending » button."
 msgstr[0] ""
@@ -1140,75 +1140,75 @@ msgstr[1] ""
 "Jos haluat perua osallistumisesi, siirry tapahtumien sivuille yllä olevista "
 "linkeistä ja napsauta niissä osallistumispainiketta."
 
+#, elixir-format
 #: lib/web/templates/email/pending_participation_notification.html.eex:38
 #: lib/web/templates/email/pending_participation_notification.text.eex:4
-#, elixir-format
 msgid "You have one pending attendance request to process:"
 msgid_plural "You have %{number_participation_requests} attendance requests to process:"
 msgstr[0] "Yksi osallistujapyyntö odottaa käsittelyäsi:"
 msgstr[1] ""
 "%{number_participation_requests} osallistujapyyntöä odottaa käsittelyäsi:"
 
-#: lib/web/templates/email/email.text.eex:16
 #, elixir-format
+#: lib/web/templates/email/email.text.eex:16
 msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} on Mobilizon-palvelin."
 
-#: lib/web/templates/email/email.html.eex:146
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:146
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> on Mobilizon-palvelin."
 
+#, elixir-format
 #: lib/web/templates/email/pending_participation_notification.html.eex:13
 #: lib/web/templates/email/pending_participation_notification.text.eex:1
-#, elixir-format
 msgid "A request is pending!"
 msgstr "Pyyntö odottaa!"
 
+#, elixir-format
 #: lib/web/templates/email/before_event_notification.html.eex:13
 #: lib/web/templates/email/before_event_notification.text.eex:1
-#, elixir-format
 msgid "An event is upcoming!"
 msgstr "Tapahtuma lähestyy!"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_new.html.eex:13
 #: lib/web/templates/email/email_changed_new.text.eex:1
-#, elixir-format
 msgid "Confirm new email"
 msgstr "Vahvista sähköpostiosoite"
 
-#: lib/web/templates/email/event_updated.html.eex:82
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:82
 msgid "End"
 msgstr "Päättyy"
 
-#: lib/web/templates/email/event_updated.text.eex:21
 #, elixir-format
+#: lib/web/templates/email/event_updated.text.eex:21
 msgid "End %{ends_on}"
 msgstr "Päättyy %{ends_on}"
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:13
 #: lib/web/templates/email/event_updated.text.eex:1
-#, elixir-format
 msgid "Event update!"
 msgstr "Tapahtuma päivitetty!"
 
-#: lib/web/templates/email/report.html.eex:66
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:66
 msgid "Flagged comments"
 msgstr "Merkityt kommentit"
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_approved.html.eex:45
 #: lib/web/templates/email/event_participation_approved.text.eex:7
-#, elixir-format
 msgid "Good news: one of the event organizers just approved your request. Update your calendar, because you're on the guest list now!"
 msgstr ""
 "Hyviä uutisia: joku tapahtuman järjestäjistä hyväksyi juuri pyyntösi. Olet "
 "kutsuttujen joukossa, joten merkitse tapahtuma kalenteriisi!"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_new.html.eex:38
 #: lib/web/templates/email/email_changed_new.text.eex:3
-#, elixir-format
 msgid "Hi there! It seems like you wanted to change the email address linked to your account on <b>%{instance}</b>. If you still wish to do so, please click the button below to confirm the change. You will then be able to log in to %{instance} with this new email address."
 msgstr ""
 "Hei! Haluat ilmeisesti vaihtaa palvelimella <b>%{instance}</b> olevaan "
@@ -1216,16 +1216,16 @@ msgstr ""
 "vaihto napsauttamalla alla olevaa painiketta. Sen jälkeen voit kirjautua "
 "palvelimelle %{instance} uudella sähköpostiosoitteella."
 
-#: lib/web/templates/email/email_changed_old.text.eex:3
 #, elixir-format
+#: lib/web/templates/email/email_changed_old.text.eex:3
 msgid "Hi there! Just a quick note to confirm that the email address linked to your account on %{host} has been changed from this one to:"
 msgstr ""
 "Hei! Vahvistamme vain, että palvelimella %{host} olevaan tiliisi yhdistetty "
 "sähköpostiosoite on vaihdettu seuraavaan osoitteeseen:"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_old.html.eex:41
 #: lib/web/templates/email/email_changed_old.text.eex:5
-#, elixir-format
 msgid "If you did not trigger this change yourself, it is likely that someone has gained access to your %{host} account. Please log in and change your password immediately. If you cannot login, contact the admin on %{host}."
 msgstr ""
 "Jos et tehnyt vaihtoa itse, todennäköisesti joku muu on päässyt käyttämään "
@@ -1233,186 +1233,186 @@ msgstr ""
 "viipymättä. Jos et pääse kirjautumaan sisään, ota yhteyttä palvelimen %{host}"
 " ylläpitäjään."
 
-#: lib/web/templates/email/password_reset.text.eex:12
 #, elixir-format
+#: lib/web/templates/email/password_reset.text.eex:12
 msgid "If you didn't trigger the change yourself, please ignore this message. Your password won't be changed until you click the link above."
 msgstr ""
 "Jos et tehnyt vaihtoa itse, voit jättää tämän viestin huomiotta. Salasana ei "
 "vaihdu, ellet avaa yllä olevaa linkkiä."
 
+#, elixir-format
 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:70
 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:4 lib/web/templates/email/registration_confirmation.html.eex:45
-#, elixir-format
 msgid "If you didn't trigger this email, you may safely ignore it."
 msgstr "Jos et lähettänyt pyyntöä, voit jättää tämän viestin huomiotta."
 
+#, elixir-format
 #: lib/web/templates/email/before_event_notification.html.eex:63
 #: lib/web/templates/email/before_event_notification.text.eex:6
-#, elixir-format
 msgid "If you wish to cancel your attendance, visit the event page through the link above and click the « Attending » button."
 msgstr ""
 "Jos haluat perua osallistumisesi, siirry tapahtuman sivulle yllä olevasta "
 "linkistä ja napsauta siellä osallistumispainiketta."
 
-#: lib/web/templates/email/email.html.eex:92
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:92
 msgid "In the meantime, please consider this software as not (yet) fully functional. Read more %{a_start}on the Framasoft blog%{a_end}."
 msgstr ""
 "Huomaathan, että ohjelma ei ole (vielä) täysin valmis. Lisätietoja "
 "%{a_start}blogissamme%{a_end}."
 
-#: lib/web/templates/email/email.text.eex:10
 #, elixir-format
+#: lib/web/templates/email/email.text.eex:10
 msgid "In the meantime, please consider this software as not (yet) fully functional. Read more on the Framasoft blog:"
 msgstr ""
 "Huomaathan, että ohjelma ei ole (vielä) täysin valmis. Lisätietoja "
 "%{a_start}blogissamme%{a_end}:"
 
+#, elixir-format
 #: lib/web/templates/email/email.html.eex:147
 #: lib/web/templates/email/email.text.eex:16
-#, elixir-format
 msgid "Learn more about Mobilizon here!"
 msgstr "Lue lisää Mobilizonista."
 
-#: lib/web/templates/email/event_updated.html.eex:92
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:92
 msgid "Location"
 msgstr "Sijainti"
 
-#: lib/web/templates/email/event_updated.html.eex:102
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:102
 msgid "Location address was removed"
 msgstr "Käyntiosoite poistettiin"
 
+#, elixir-format
 #: lib/web/templates/email/pending_participation_notification.html.eex:51
 #: lib/web/templates/email/pending_participation_notification.text.eex:6
-#, elixir-format
 msgid "Manage pending requests"
 msgstr "Hallinnoi odottavia osallistujapyyntöjä"
 
+#, elixir-format
 #: lib/web/templates/email/registration_confirmation.html.eex:13
 #: lib/web/templates/email/registration_confirmation.text.eex:1
-#, elixir-format
 msgid "Nearly there!"
 msgstr "Melkein valmista!"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_old.html.eex:13
 #: lib/web/templates/email/email_changed_old.text.eex:1
-#, elixir-format
 msgid "New email confirmation"
 msgstr "Uuden sähköpostiosoitteen vahvistaminen"
 
-#: lib/web/templates/email/report.html.eex:84
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:84
 msgid "Reasons for report"
 msgstr "Raportin syy"
 
-#: lib/web/templates/email/report.html.eex:39
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:39
 msgid "Someone on <b>%{instance}</b> reported the following content for you to analyze:"
 msgstr "Seuraava sisältö raportoitiin palvelimelta <b>%{instance}</b>:"
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_rejected.html.eex:13
 #: lib/web/templates/email/event_participation_rejected.text.eex:1
-#, elixir-format
 msgid "Sorry! You're not going."
 msgstr "Valitettavasti et pääse mukaan."
 
-#: lib/web/templates/email/event_updated.html.eex:72
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:72
 msgid "Start"
 msgstr "Alkaa"
 
-#: lib/web/templates/email/event_updated.text.eex:18
 #, elixir-format
+#: lib/web/templates/email/event_updated.text.eex:18
 msgid "Start %{begins_on}"
 msgstr "Alkaa %{begins_on}"
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:38
 #: lib/web/templates/email/event_updated.text.eex:3
-#, elixir-format
 msgid "There have been changes for %{title} so we'd thought we'd let you know."
 msgstr "%{title} on joiltain osin muuttunut, ja ajattelimme ilmoittaa asiasta."
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:54
 #: lib/web/templates/email/event_updated.text.eex:11
-#, elixir-format
 msgid "This event has been cancelled by its organizers. Sorry!"
 msgstr "Valitettavasti tapahtuman järjestäjät peruivat tapahtuman."
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:50
 #: lib/web/templates/email/event_updated.text.eex:7
-#, elixir-format
 msgid "This event has been confirmed"
 msgstr "Tapahtuma on vahvistettu"
 
+#, elixir-format
 #: lib/web/templates/email/event_updated.html.eex:52
 #: lib/web/templates/email/event_updated.text.eex:9
-#, elixir-format
 msgid "This event has yet to be confirmed: organizers will let you know if they do confirm it."
 msgstr ""
 "Tapahtumaa ei ole vielä vahvistettu. Järjestäjät ilmoittavat vahvistamisesta "
 "myöhemmin."
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_rejected.html.eex:45
 #: lib/web/templates/email/event_participation_rejected.text.eex:7
-#, elixir-format
 msgid "Unfortunately, the organizers rejected your request."
 msgstr "Ikävä kyllä järjestäjät hylkäsivät osallistumisesi."
 
-#: lib/web/templates/email/email_changed_new.html.eex:51
 #, elixir-format
+#: lib/web/templates/email/email_changed_new.html.eex:51
 msgid "Verify your email address"
 msgstr "Vahvista sähköpostiosoite"
 
-#: lib/web/templates/email/report.html.eex:104
 #, elixir-format
+#: lib/web/templates/email/report.html.eex:104
 msgid "View report"
 msgstr "Näytä raportti"
 
-#: lib/web/templates/email/report.text.eex:17
 #, elixir-format
+#: lib/web/templates/email/report.text.eex:17
 msgid "View report:"
 msgstr "Näytä raportti:"
 
-#: lib/web/templates/email/event_participation_approved.html.eex:58
 #, elixir-format
+#: lib/web/templates/email/event_participation_approved.html.eex:58
 msgid "Visit event page"
 msgstr "Käy tapahtumasivulla"
 
-#: lib/web/templates/email/event_updated.html.eex:119
 #, elixir-format
+#: lib/web/templates/email/event_updated.html.eex:119
 msgid "Visit the updated event page"
 msgstr "Käy päivitetyllä tapahtumasivulla"
 
-#: lib/web/templates/email/event_updated.text.eex:23
 #, elixir-format
+#: lib/web/templates/email/event_updated.text.eex:23
 msgid "Visit the updated event page: %{link}"
 msgstr "Katso päivitetty tapahtuma: %{linkki}"
 
+#, elixir-format
 #: lib/web/templates/email/notification_each_week.html.eex:13
 #: lib/web/templates/email/notification_each_week.text.eex:1
-#, elixir-format
 msgid "What's up this week?"
 msgstr "Mitä tällä viikolla tapahtuu?"
 
+#, elixir-format
 #: lib/web/templates/email/on_day_notification.html.eex:13
 #: lib/web/templates/email/on_day_notification.text.eex:1
-#, elixir-format
 msgid "What's up today?"
 msgstr "Mitä tänään tapahtuu?"
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_approved.html.eex:70
 #: lib/web/templates/email/event_participation_approved.text.eex:11
-#, elixir-format
 msgid "Would you wish to update or cancel your attendance, simply access the event page through the link above and click on the Attending button."
 msgstr ""
 "Jos haluat päivittää tai perua osallistumisesi, siirry yllä olevasta "
 "linkistä tapahtumasivulle ja napsauta osallistumispainiketta."
 
+#, elixir-format
 #: lib/web/templates/email/pending_participation_notification.html.eex:64
 #: lib/web/templates/email/pending_participation_notification.text.eex:8
-#, elixir-format
 msgid "You are receiving this email because you chose to get notifications for pending attendance requests to your events. You can disable or change your notification settings in your user account settings under « Notifications »."
 msgstr ""
 "Saat tämän sähköpostin, koska olet tilannut ilmoitukset tapahtumiesi "
@@ -1420,78 +1420,124 @@ msgstr ""
 "poistaa ilmoitukset käytöstä käyttäjätilisi asetuksista kohdasta "
 "”Ilmoitukset”."
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_rejected.html.eex:38
 #: lib/web/templates/email/event_participation_rejected.text.eex:5
-#, elixir-format
 msgid "You issued a request to attend %{title}."
 msgstr "Lähetit pyynnön osallistua tapahtumaan %{title}."
 
+#, elixir-format
 #: lib/web/templates/email/event_participation_approved.html.eex:38
 #: lib/web/templates/email/event_participation_approved.text.eex:5
-#, elixir-format
 msgid "You recently requested to attend %{title}."
 msgstr "Lähetit pyynnön osallistua tapahtumaan %{title}."
 
-#: lib/web/templates/email/event_participation_approved.html.eex:13
 #, elixir-format
+#: lib/web/templates/email/event_participation_approved.html.eex:13
 msgid "You're going!"
 msgstr "Olet mukana!"
 
+#, elixir-format
 #: lib/web/templates/email/email_changed_new.html.eex:64
 #: lib/web/templates/email/email_changed_new.text.eex:5
-#, elixir-format
 msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr "Jos et tehnyt vaihtoa itse, voit jättää tämän viestin huomiotta."
 
-#: lib/web/templates/email/email.html.eex:89
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:89
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Älä käytä todellisiin tarkoituksiin.</b>"
 
-#: lib/web/templates/email/email.html.eex:91
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:91
 msgid "Mobilizon is still under development, we will add new features along the updates, until the release of <b>version 1 of the software in the fall of 2020</b>."
 msgstr ""
 "Mobilizonin kehitystyö on vielä käynnissä, ja tälle sivulle lisätään "
 "säännöllisesti uusia ominaisuuksia, kunnes <b>ohjelman versio 1 julkaistaan "
 "syksyllä 2020</b>."
 
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
 #, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 "Jos tämä on virhe, ota yhteyttä ryhmän ylläpitäjiin ja pyydä lisäämään sinut "
 "takaisin."
 
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
 #, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr "Näkemiin ja kiitos kaloista!"
 
-#: lib/web/email/group.ex:58
 #, elixir-format
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr "Sinut on poistettu ryhmästä %{group}"
 
-#: lib/web/templates/email/group_removal.text.eex:3
 #, elixir-format
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 "Sinut on poistettu ryhmästä %{group}. Et voi enää käyttää ryhmän yksityistä "
 "sisältöä."
 
-#: lib/web/templates/email/group_invite.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 "<b>%{inviter}</b> kutsui sinut ryhmään "
 "%{link_start}<b>%{group}</b>%{link_end}"
 
-#: lib/web/templates/email/group_removal.html.eex:38
 #, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
 "Sinut on poistettu ryhmästä %{link_start}<b>%{group}</b>%{link_end}. Et voi "
 "enää käyttää ryhmän yksityistä sisältöä."
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/fr/LC_MESSAGES/default.po b/priv/gettext/fr/LC_MESSAGES/default.po
index f4760072d..a2a194bc7 100644
--- a/priv/gettext/fr/LC_MESSAGES/default.po
+++ b/priv/gettext/fr/LC_MESSAGES/default.po
@@ -10,16 +10,15 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-18 12:37+0000\n"
+"PO-Revision-Date: 2020-08-27 12:12+0200\n"
 "Last-Translator: Thomas Citharel <thomas.citharel@framasoft.org>\n"
-"Language-Team: French <https://weblate.framasoft.org/projects/mobilizon/"
-"backend/fr/>\n"
+"Language-Team: French <https://weblate.framasoft.org/projects/mobilizon/backend/fr/>\n"
 "Language: fr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.1\n"
+"X-Generator: Poedit 2.3\n"
 
 #: lib/web/templates/email/password_reset.html.eex:48
 msgid "If you didn't request this, please ignore this email. Your password won't change until you access the link below and create a new one."
@@ -334,7 +333,7 @@ msgstr "Pour accepter cette invitation, rendez-vous dans vos groupes."
 msgid "View the event on: %{link}"
 msgstr "Voir l'événement mis à jour sur : %{link}"
 
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr "Vous avez été invité par %{inviter} à rejoindre le groupe %{group}"
 
@@ -817,12 +816,8 @@ msgid "In the meantime, please consider this software as not (yet) fully functio
 msgstr "D'ici là, veuillez considérer que le logiciel n'est pas (encore) fini. Retrouvez plus d'informations %{a_start}sur le blog de Framasoft%{a_end}."
 
 #: lib/web/templates/email/email.text.eex:10
-msgid ""
-"In the meantime, please consider this software as not (yet) fully "
-"functional. Read more on the Framasoft blog:"
-msgstr ""
-"D'ici là, veuillez considérer que le logiciel n'est pas (encore) fini. "
-"Retrouvez plus d'informations sur le blog de Framasoft :"
+msgid "In the meantime, please consider this software as not (yet) fully functional. Read more on the Framasoft blog:"
+msgstr "D'ici là, veuillez considérer que le logiciel n'est pas (encore) fini. Retrouvez plus d'informations sur le blog de Framasoft :"
 
 #: lib/web/templates/email/email.html.eex:147 lib/web/templates/email/email.text.eex:16
 msgid "Learn more about Mobilizon here!"
@@ -952,19 +947,19 @@ msgstr "<b>Veuillez ne pas l'utiliser pour un cas réel.</b>"
 msgid "Mobilizon is still under development, we will add new features along the updates, until the release of <b>version 1 of the software in the fall of 2020</b>."
 msgstr "Mobilizon est en cours de développement, nous y ajouterons de nouvelles fonctionnalités lors de mises à jour régulières, jusqu'à la publication de <b>la version 1 du logiciel à l'automne 2020</b>."
 
-#: lib/web/templates/email/group_removal.html.eex:45 lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45 lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr "Si vous pensez qu'il s'agit d'une erreur, vous pouvez contacter les administrateurs du groupe afin qu'ils vous réintègrent."
 
-#: lib/web/templates/email/group_removal.html.eex:13 lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13 lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr "Salut, et encore merci pour le poisson !"
 
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr "Vous avez été enlevé du groupe %{group}"
 
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr "Vous avez été enlevé du groupe %{group}. Vous ne serez plus en mesure d'accéder au contenu privé du groupe."
 
@@ -972,6 +967,38 @@ msgstr "Vous avez été enlevé du groupe %{group}. Vous ne serez plus en mesure
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr "<b>%{inviter}</b> vient de vous inviter à rejoindre son groupe %{link_start}<b>%{group}</b>%{link_end}"
 
-#: lib/web/templates/email/group_removal.html.eex:38
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr "Vous avez été enlevé du groupe %{link_start}<b>%{group}</b>%{link_end}. Vous ne serez plus en mesure d'accéder au contenu privé du groupe."
+
+#: lib/web/templates/email/group_suspension.html.eex:54 lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr "Comme ce groupe était originaire d'une autre instance, il continuera à fonctionner pour d'autres instances que celle-ci."
+
+#: lib/web/templates/email/group_suspension.html.eex:46 lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr "Comme ce groupe était originaire de cette instance, toutes ses données ont été irrémédiablement détruites."
+
+#: lib/web/templates/email/group_deletion.html.eex:38 lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr "L'administrateur·ice %{author} a supprimé le groupe %{group}. Tous les événements, discussions, billets et todos du groupe ont été supprimés."
+
+#: lib/web/templates/email/group_suspension.html.eex:13 lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr "Le groupe %{group} a été suspendu sur %{instance} !"
+
+#: lib/web/templates/email/group_deletion.html.eex:13 lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr "Le groupe %{group} a été supprimé sur %{instance} !"
+
+#: lib/web/templates/email/group_suspension.html.eex:38 lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr "L'équipe de modération de votre instance a décidé de suspendre %{group_name} (%{group_address}). Vous n'êtes désormais plus membre de ce groupe."
+
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr "Le groupe %{group} a été supprimé sur %{instance}"
+
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr "Le groupe %{group} a été suspendu sur %{instance}"
diff --git a/priv/gettext/it/LC_MESSAGES/default.po b/priv/gettext/it/LC_MESSAGES/default.po
index a59395c2b..63cfb3f8e 100644
--- a/priv/gettext/it/LC_MESSAGES/default.po
+++ b/priv/gettext/it/LC_MESSAGES/default.po
@@ -398,7 +398,7 @@ msgid "View the event on: %{link}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1181,33 +1181,79 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/ja/LC_MESSAGES/default.po b/priv/gettext/ja/LC_MESSAGES/default.po
index 56785108e..06285d4a4 100644
--- a/priv/gettext/ja/LC_MESSAGES/default.po
+++ b/priv/gettext/ja/LC_MESSAGES/default.po
@@ -394,7 +394,7 @@ msgid "View the event on: %{link}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1171,33 +1171,79 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/nl/LC_MESSAGES/default.po b/priv/gettext/nl/LC_MESSAGES/default.po
index f4b4261b0..e7769577a 100644
--- a/priv/gettext/nl/LC_MESSAGES/default.po
+++ b/priv/gettext/nl/LC_MESSAGES/default.po
@@ -407,7 +407,7 @@ msgid "View the event on: %{link}"
 msgstr "Bekijk het bijgewerkte evenement op: %{link}"
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1208,33 +1208,79 @@ msgstr ""
 "beschikbaar is in de eerste helft van 2020</b>."
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/oc/LC_MESSAGES/default.po b/priv/gettext/oc/LC_MESSAGES/default.po
index b65bfaebe..7f26ccf87 100644
--- a/priv/gettext/oc/LC_MESSAGES/default.po
+++ b/priv/gettext/oc/LC_MESSAGES/default.po
@@ -405,7 +405,7 @@ msgid "View the event on: %{link}"
 msgstr "Veire l’eveniment actualizat sus : %{link}"
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr "%{inviter} vos a convidat a rejónher lo grop %{group}"
 
@@ -1210,33 +1210,79 @@ msgstr ""
 "la version 1 del logicial al primièr semèstre 2020</b>."
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/pl/LC_MESSAGES/default.po b/priv/gettext/pl/LC_MESSAGES/default.po
index 679d3be4e..163bc611a 100644
--- a/priv/gettext/pl/LC_MESSAGES/default.po
+++ b/priv/gettext/pl/LC_MESSAGES/default.po
@@ -413,7 +413,7 @@ msgid "View the event on: %{link}"
 msgstr "Zobacz zaktualizowane wydarzenie na %{link}"
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1221,33 +1221,79 @@ msgstr ""
 "roku</b>."
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/pt/LC_MESSAGES/default.po b/priv/gettext/pt/LC_MESSAGES/default.po
index 4247e1102..677d31772 100644
--- a/priv/gettext/pt/LC_MESSAGES/default.po
+++ b/priv/gettext/pt/LC_MESSAGES/default.po
@@ -396,7 +396,7 @@ msgid "View the event on: %{link}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1178,33 +1178,79 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/pt_BR/LC_MESSAGES/default.po b/priv/gettext/pt_BR/LC_MESSAGES/default.po
index d5fff8d28..ae5fe9747 100644
--- a/priv/gettext/pt_BR/LC_MESSAGES/default.po
+++ b/priv/gettext/pt_BR/LC_MESSAGES/default.po
@@ -444,7 +444,7 @@ msgid "View the event on: %{link}"
 msgstr "Veja o evento atualizado em: %{link}"
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1300,33 +1300,79 @@ msgstr ""
 "1 do aplicativo no primeiro semestre de 2020</b>."
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/ru/LC_MESSAGES/default.po b/priv/gettext/ru/LC_MESSAGES/default.po
index a232b23b9..990fb63fc 100644
--- a/priv/gettext/ru/LC_MESSAGES/default.po
+++ b/priv/gettext/ru/LC_MESSAGES/default.po
@@ -405,7 +405,7 @@ msgid "View the event on: %{link}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1196,33 +1196,79 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/priv/gettext/sv/LC_MESSAGES/default.po b/priv/gettext/sv/LC_MESSAGES/default.po
index eb1184a27..37a684ea6 100644
--- a/priv/gettext/sv/LC_MESSAGES/default.po
+++ b/priv/gettext/sv/LC_MESSAGES/default.po
@@ -408,7 +408,7 @@ msgid "View the event on: %{link}"
 msgstr "Visa det uppdaterade evenemanget på %{link}"
 
 #, elixir-format
-#: lib/web/email/group.ex:28
+#: lib/web/email/group.ex:32
 msgid "You have been invited by %{inviter} to join group %{group}"
 msgstr ""
 
@@ -1199,33 +1199,79 @@ msgid "Mobilizon is still under development, we will add new features along the
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:45
-#: lib/web/templates/email/group_removal.text.eex:5
+#: lib/web/templates/email/group_member_removal.html.eex:45
+#: lib/web/templates/email/group_member_removal.text.eex:5
 msgid "If you feel this is an error, you may contact the group's administrators so that they can add you back."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.html.eex:13
-#: lib/web/templates/email/group_removal.text.eex:1
+#: lib/web/templates/email/group_member_removal.html.eex:13
+#: lib/web/templates/email/group_member_removal.text.eex:1
 msgid "So long, and thanks for the fish!"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/group.ex:58
+#: lib/web/email/group.ex:62
 msgid "You have been removed from group %{group}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/group_removal.text.eex:3
+#: lib/web/templates/email/group_member_removal.text.eex:3
 msgid "You have been removed from group %{group}. You will not be able to access this group's private content anymore."
 msgstr ""
 
-#, elixir-format, fuzzy
+#, elixir-format
 #: lib/web/templates/email/group_invite.html.eex:38
 msgid "<b>%{inviter}</b> just invited you to join their group %{link_start}<b>%{group}</b>%{link_end}"
 msgstr ""
 
-#, elixir-format, fuzzy
-#: lib/web/templates/email/group_removal.html.eex:38
+#, elixir-format
+#: lib/web/templates/email/group_member_removal.html.eex:38
 msgid "You have been removed from group %{link_start}<b>%{group}</b>%{link_end}. You will not be able to access this group's private content anymore."
 msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:54
+#: lib/web/templates/email/group_suspension.text.eex:7
+msgid "As this group was located on another instance, it will continue to work for other instances than this one."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:46
+#: lib/web/templates/email/group_suspension.text.eex:5
+msgid "As this group was located on this instance, all of it's data has been irretrievably deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:38
+#: lib/web/templates/email/group_deletion.text.eex:3
+msgid "The administrator %{author} deleted group %{group}. All of the group's events, discussions, posts and todos have been deleted."
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:13
+#: lib/web/templates/email/group_suspension.text.eex:1
+msgid "The group %{group} has been suspended on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_deletion.html.eex:13
+#: lib/web/templates/email/group_deletion.text.eex:1
+msgid "The group %{group} was deleted on %{instance}!"
+msgstr ""
+
+#, elixir-format
+#: lib/web/templates/email/group_suspension.html.eex:38
+#: lib/web/templates/email/group_suspension.text.eex:3
+msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:135
+msgid "The group %{group} has been deleted on %{instance}"
+msgstr ""
+
+#, elixir-format, fuzzy
+#: lib/web/email/group.ex:96
+msgid "The group %{group} has been suspended on %{instance}"
+msgstr ""
diff --git a/test/federation/activity_pub/transmogrifier_test.exs b/test/federation/activity_pub/transmogrifier_test.exs
index 3a0ce1328..4d3e7d995 100644
--- a/test/federation/activity_pub/transmogrifier_test.exs
+++ b/test/federation/activity_pub/transmogrifier_test.exs
@@ -789,8 +789,22 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do
 
   describe "handle incoming delete activities" do
     test "it works for incoming deletes" do
-      %Actor{url: actor_url} = actor = insert(:actor)
-      %Comment{url: comment_url} = insert(:comment, actor: nil, actor_id: actor.id)
+      %Actor{url: actor_url} =
+        actor = insert(:actor, url: "http://mobilizon.tld/@remote", domain: "mobilizon.tld")
+
+      %Comment{url: comment_url} =
+        insert(:comment,
+          actor: nil,
+          actor_id: actor.id,
+          url: "http://mobilizon.tld/comments/9f3794b8-11a0-4a98-8cb7-475ab332c701"
+        )
+
+      Mock
+      |> expect(:call, fn
+        %{method: :get, url: "http://mobilizon.tld/comments/9f3794b8-11a0-4a98-8cb7-475ab332c701"},
+        _opts ->
+          {:ok, %Tesla.Env{status: 410, body: "Gone"}}
+      end)
 
       data =
         File.read!("test/fixtures/mastodon-delete.json")
@@ -843,7 +857,9 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do
     setup :set_mox_from_context
 
     test "it works for incoming actor deletes" do
-      %Actor{url: url} = actor = insert(:actor, url: "https://framapiaf.org/users/admin")
+      %Actor{url: url} =
+        actor = insert(:actor, url: "https://framapiaf.org/users/admin", domain: "framapiaf.org")
+
       %Event{url: event1_url} = event1 = insert(:event, organizer_actor: actor)
       insert(:event, organizer_actor: actor)
 
diff --git a/test/graphql/resolvers/group_test.exs b/test/graphql/resolvers/group_test.exs
index 97b663f68..73d325c4f 100644
--- a/test/graphql/resolvers/group_test.exs
+++ b/test/graphql/resolvers/group_test.exs
@@ -1,5 +1,6 @@
 defmodule Mobilizon.Web.Resolvers.GroupTest do
   use Mobilizon.Web.ConnCase
+  use Oban.Testing, repo: Mobilizon.Storage.Repo
 
   import Mobilizon.Factory
 
@@ -87,13 +88,8 @@ defmodule Mobilizon.Web.Resolvers.GroupTest do
   end
 
   describe "list groups" do
-    test "list_groups/3 returns all public groups", %{conn: conn} do
-      group = insert(:group, visibility: :public)
-      insert(:group, visibility: :unlisted)
-      insert(:group, visibility: :private)
-
-      query = """
-      {
+    @list_groups_query """
+    {
         groups {
             elements {
               preferredUsername,
@@ -101,14 +97,49 @@ defmodule Mobilizon.Web.Resolvers.GroupTest do
             total
         }
       }
-      """
+    """
 
-      res = AbsintheHelpers.graphql_query(conn, query: query)
+    test "list_groups/3 doesn't returns all groups if not authenticated", %{conn: conn} do
+      insert(:group, visibility: :public)
+      insert(:group, visibility: :unlisted)
+      insert(:group, visibility: :private)
 
-      assert res["data"]["groups"]["total"] == 1
+      res = AbsintheHelpers.graphql_query(conn, query: @list_groups_query)
 
-      assert hd(res["data"]["groups"]["elements"])["preferredUsername"] ==
-               group.preferred_username
+      assert hd(res["errors"])["message"] == "You may not list groups unless moderator."
+    end
+
+    test "list_groups/3 doesn't return all groups if not a moderator", %{conn: conn} do
+      insert(:group, visibility: :public)
+      insert(:group, visibility: :unlisted)
+      insert(:group, visibility: :private)
+      user = insert(:user)
+
+      res =
+        conn
+        |> auth_conn(user)
+        |> AbsintheHelpers.graphql_query(query: @list_groups_query)
+
+      assert hd(res["errors"])["message"] == "You may not list groups unless moderator."
+    end
+
+    test "list_groups/3 returns all groups if a moderator", %{conn: conn} do
+      group_1 = insert(:group, visibility: :public)
+      group_2 = insert(:group, visibility: :unlisted)
+      group_3 = insert(:group, visibility: :private)
+      user = insert(:user, role: :moderator)
+
+      res =
+        conn
+        |> auth_conn(user)
+        |> AbsintheHelpers.graphql_query(query: @list_groups_query)
+
+      assert res["data"]["groups"]["total"] == 3
+
+      assert res["data"]["groups"]["elements"]
+             |> Enum.map(& &1["preferredUsername"])
+             |> MapSet.new() ==
+               [group_1, group_2, group_3] |> Enum.map(& &1.preferred_username) |> MapSet.new()
     end
   end
 
@@ -209,57 +240,70 @@ defmodule Mobilizon.Web.Resolvers.GroupTest do
   end
 
   describe "delete a group" do
+    @delete_group_mutation """
+    mutation DeleteGroup($groupId: ID!) {
+      deleteGroup(
+        groupId: $groupId
+      ) {
+          id
+        }
+      }
+    """
+
     test "delete_group/3 deletes a group", %{conn: conn, user: user, actor: actor} do
       group = insert(:group)
       insert(:member, parent: group, actor: actor, role: :administrator)
 
-      mutation = """
-          mutation {
-            deleteGroup(
-              actor_id: #{actor.id},
-              group_id: #{group.id}
-            ) {
-                id
-              }
-            }
-      """
-
       res =
         conn
         |> auth_conn(user)
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+        |> AbsintheHelpers.graphql_query(
+          query: @delete_group_mutation,
+          variables: %{groupId: group.id}
+        )
 
-      assert json_response(res, 200)["errors"] == nil
-      assert json_response(res, 200)["data"]["deleteGroup"]["id"] == to_string(group.id)
+      assert res["errors"] == nil
+      assert res["data"]["deleteGroup"]["id"] == to_string(group.id)
 
-      res =
-        conn
-        |> auth_conn(user)
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+      assert_enqueued(
+        worker: Mobilizon.Service.Workers.Background,
+        args: %{
+          "actor_id" => group.id,
+          "author_id" => actor.id,
+          "op" => "delete_actor",
+          "reserve_username" => true,
+          "suspension" => false
+        }
+      )
 
-      assert hd(json_response(res, 200)["errors"])["message"] =~ "not found"
+      # Can't be used right now, probably because we try to run a transaction in a Oban Job while using Ecto Sandbox
+
+      # assert %{success: 1, failure: 0} == Oban.drain_queue(queue: :background)
+
+      # res =
+      #   conn
+      #   |> auth_conn(user)
+      #   |> AbsintheHelpers.graphql_query(
+      #     query: @delete_group_mutation,
+      #     variables: %{groupId: group.id}
+      #   )
+
+      # assert res["data"] == "tt"
+      # assert hd(json_response(res, 200)["errors"])["message"] =~ "not found"
     end
 
     test "delete_group/3 should check user authentication", %{conn: conn, actor: actor} do
       group = insert(:group)
       insert(:member, parent: group, actor: actor, role: :member)
 
-      mutation = """
-          mutation {
-            deleteGroup(
-              actor_id: #{actor.id},
-              group_id: #{group.id}
-            ) {
-                id
-              }
-            }
-      """
-
       res =
         conn
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+        |> AbsintheHelpers.graphql_query(
+          query: @delete_group_mutation,
+          variables: %{groupId: group.id}
+        )
 
-      assert hd(json_response(res, 200)["errors"])["message"] =~ "logged-in"
+      assert hd(res["errors"])["message"] =~ "logged-in"
     end
 
     test "delete_group/3 should check the actor is owned by the user", %{
@@ -270,49 +314,33 @@ defmodule Mobilizon.Web.Resolvers.GroupTest do
       group = insert(:group)
       insert(:member, parent: group, actor: actor, role: :member)
 
-      mutation = """
-          mutation {
-            deleteGroup(
-              actor_id: 159,
-              group_id: #{group.id}
-            ) {
-                id
-              }
-            }
-      """
-
       res =
         conn
         |> auth_conn(user)
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+        |> AbsintheHelpers.graphql_query(
+          query: @delete_group_mutation,
+          variables: %{groupId: group.id}
+        )
 
-      assert hd(json_response(res, 200)["errors"])["message"] =~ "not owned"
+      assert hd(res["errors"])["message"] ==
+               "Actor id is not an administrator of the selected group"
     end
 
     test "delete_group/3 should check the actor is a member of this group", %{
       conn: conn,
-      user: user,
-      actor: actor
+      user: user
     } do
       group = insert(:group)
 
-      mutation = """
-          mutation {
-            deleteGroup(
-              actor_id: #{actor.id},
-              group_id: #{group.id}
-            ) {
-                id
-              }
-            }
-      """
-
       res =
         conn
         |> auth_conn(user)
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+        |> AbsintheHelpers.graphql_query(
+          query: @delete_group_mutation,
+          variables: %{groupId: group.id}
+        )
 
-      assert hd(json_response(res, 200)["errors"])["message"] =~ "not a member"
+      assert hd(res["errors"])["message"] =~ "not a member"
     end
 
     test "delete_group/3 should check the actor is an administrator of this group", %{
@@ -323,23 +351,15 @@ defmodule Mobilizon.Web.Resolvers.GroupTest do
       group = insert(:group)
       insert(:member, parent: group, actor: actor, role: :member)
 
-      mutation = """
-          mutation {
-            deleteGroup(
-              actor_id: #{actor.id},
-              group_id: #{group.id}
-            ) {
-                id
-              }
-            }
-      """
-
       res =
         conn
         |> auth_conn(user)
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+        |> AbsintheHelpers.graphql_query(
+          query: @delete_group_mutation,
+          variables: %{groupId: group.id}
+        )
 
-      assert hd(json_response(res, 200)["errors"])["message"] =~ "not an administrator"
+      assert hd(res["errors"])["message"] =~ "not an administrator"
     end
   end
 end
diff --git a/test/graphql/resolvers/member_test.exs b/test/graphql/resolvers/member_test.exs
index 9e1fce195..276fa982b 100644
--- a/test/graphql/resolvers/member_test.exs
+++ b/test/graphql/resolvers/member_test.exs
@@ -140,6 +140,14 @@ defmodule Mobilizon.GraphQL.Resolvers.MemberTest do
   end
 
   describe "Member Resolver to leave from a group" do
+    @leave_group_mutation """
+    mutation LeaveGroup($groupId: ID!) {
+      leaveGroup(groupId: $groupId) {
+        id
+      }
+    }
+    """
+
     test "leave_group/3 should delete a member from a group", %{
       conn: conn,
       user: user,
@@ -149,23 +157,16 @@ defmodule Mobilizon.GraphQL.Resolvers.MemberTest do
       insert(:member, role: :administrator, parent: group)
       %Member{id: member_id} = insert(:member, %{actor: actor, parent: group})
 
-      mutation = """
-          mutation {
-            leaveGroup(
-              group_id: #{group.id}
-            ) {
-              id
-            }
-          }
-      """
-
       res =
         conn
         |> auth_conn(user)
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+        |> AbsintheHelpers.graphql_query(
+          query: @leave_group_mutation,
+          variables: %{groupId: group.id}
+        )
 
-      assert json_response(res, 200)["errors"] == nil
-      assert json_response(res, 200)["data"]["leaveGroup"]["id"] == to_string(member_id)
+      assert res["errors"] == nil
+      assert res["data"]["leaveGroup"]["id"] == to_string(member_id)
     end
 
     test "leave_group/3 should check if the member is the only administrator", %{
@@ -177,43 +178,29 @@ defmodule Mobilizon.GraphQL.Resolvers.MemberTest do
       insert(:member, %{actor: actor, role: :creator, parent: group})
       insert(:member, %{parent: group})
 
-      mutation = """
-          mutation {
-            leaveGroup(
-              group_id: #{group.id}
-            ) {
-                id
-              }
-            }
-      """
-
       res =
         conn
         |> auth_conn(user)
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+        |> AbsintheHelpers.graphql_query(
+          query: @leave_group_mutation,
+          variables: %{groupId: group.id}
+        )
 
-      assert hd(json_response(res, 200)["errors"])["message"] =~ "only administrator"
+      assert hd(res["errors"])["message"] =~ "only administrator"
     end
 
     test "leave_group/3 should check the user is logged in", %{conn: conn, actor: actor} do
       group = insert(:group)
       insert(:member, %{actor: actor, parent: group})
 
-      mutation = """
-          mutation {
-            leaveGroup(
-              group_id: #{group.id}
-            ) {
-                id
-              }
-            }
-      """
-
       res =
         conn
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+        |> AbsintheHelpers.graphql_query(
+          query: @leave_group_mutation,
+          variables: %{groupId: group.id}
+        )
 
-      assert hd(json_response(res, 200)["errors"])["message"] =~ "logged-in"
+      assert hd(res["errors"])["message"] =~ "logged-in"
     end
 
     test "leave_group/3 should check the group exists", %{
@@ -224,22 +211,15 @@ defmodule Mobilizon.GraphQL.Resolvers.MemberTest do
       group = insert(:group)
       insert(:member, %{actor: actor, parent: group})
 
-      mutation = """
-          mutation {
-            leaveGroup(
-              group_id: 1042
-            ) {
-                id
-              }
-            }
-      """
-
       res =
         conn
         |> auth_conn(user)
-        |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
+        |> AbsintheHelpers.graphql_query(
+          query: @leave_group_mutation,
+          variables: %{groupId: 1042}
+        )
 
-      assert hd(json_response(res, 200)["errors"])["message"] =~ "Group not found"
+      assert hd(res["errors"])["message"] =~ "Group not found"
     end
   end
 
diff --git a/test/graphql/resolvers/person_test.exs b/test/graphql/resolvers/person_test.exs
index 7b6471f27..c67234a50 100644
--- a/test/graphql/resolvers/person_test.exs
+++ b/test/graphql/resolvers/person_test.exs
@@ -508,7 +508,13 @@ defmodule Mobilizon.GraphQL.Resolvers.PersonTest do
 
       assert_enqueued(
         worker: Workers.Background,
-        args: %{"actor_id" => person_id, "op" => "delete_actor", "reserve_username" => true}
+        args: %{
+          "actor_id" => person_id,
+          "op" => "delete_actor",
+          "author_id" => nil,
+          "suspension" => false,
+          "reserve_username" => true
+        }
       )
 
       assert %{success: 1, failure: 0} == Oban.drain_queue(queue: :background)
diff --git a/test/mobilizon/actors/actors_test.exs b/test/mobilizon/actors/actors_test.exs
index 77fb60381..a925de2f0 100644
--- a/test/mobilizon/actors/actors_test.exs
+++ b/test/mobilizon/actors/actors_test.exs
@@ -367,7 +367,13 @@ defmodule Mobilizon.ActorsTest do
 
       assert_enqueued(
         worker: Workers.Background,
-        args: %{"actor_id" => actor.id, "op" => "delete_actor", "reserve_username" => true}
+        args: %{
+          "actor_id" => actor.id,
+          "op" => "delete_actor",
+          "author_id" => nil,
+          "suspension" => false,
+          "reserve_username" => true
+        }
       )
 
       assert %{success: 1, failure: 0} == Oban.drain_queue(queue: :background)