diff --git a/js/src/App.vue b/js/src/App.vue
index ac3070a21..79b809b51 100644
--- a/js/src/App.vue
+++ b/js/src/App.vue
@@ -49,12 +49,6 @@ export default class App extends Vue {
       route: "GroupList",
       role: null
     },
-    {
-      icon: "content_copy",
-      text: "Categories",
-      route: "CategoryList",
-      role: "ROLE_ADMIN"
-    },
     { icon: "settings", text: "Settings", role: "ROLE_USER" },
     { icon: "chat_bubble", text: "Send feedback", role: "ROLE_USER" },
     { icon: "help", text: "Help", role: null },
diff --git a/js/src/graphql/category.ts b/js/src/graphql/category.ts
deleted file mode 100644
index 3966ff137..000000000
--- a/js/src/graphql/category.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import gql from 'graphql-tag';
-
-export const FETCH_CATEGORIES = gql`
-query {
-    categories {
-        id,
-        title,
-        description,
-        picture {
-            url,
-        },
-   }
-}
-`;
-
-export const CREATE_CATEGORY = gql`
-    mutation createCategory($title: String!, $description: String!, $picture: Upload!) {
-        createCategory(title: $title, description: $description, picture: $picture) {
-            id,
-            title,
-            description,
-            picture {
-                url,
-                url_thumbnail
-            },
-        },
-    },
-
-`;
diff --git a/js/src/graphql/event.ts b/js/src/graphql/event.ts
index b5989eeb0..75f908934 100644
--- a/js/src/graphql/event.ts
+++ b/js/src/graphql/event.ts
@@ -25,6 +25,7 @@ export const FETCH_EVENT = gql`
       thumbnail,
       large_image,
       publish_at,
+      category,
       # online_address,
       # phone_address,
       organizerActor {
@@ -39,10 +40,7 @@ export const FETCH_EVENT = gql`
       # },
       participants {
         ${participantQuery}
-      },
-      category {
-        title,
-      },
+      }
     }
   }
 `;
@@ -75,9 +73,7 @@ export const FETCH_EVENTS = gql`
         preferredUsername,
         name,
       },
-      category {
-        title,
-      },
+      category,
       participants {
         ${participantQuery}
       }
@@ -112,9 +108,9 @@ export const EDIT_EVENT = gql`
   $title: String!,
   $description: String!,
   $organizerActorId: Int!,
-  $categoryId: Int!
+  $category: String!
   ) {
-    EditEvent(title: $title, description: $description, organizerActorId: $organizerActorId, categoryId: $categoryId) {
+    EditEvent(title: $title, description: $description, organizerActorId: $organizerActorId, category: $category) {
       uuid
     }
   }
diff --git a/js/src/router/category.ts b/js/src/router/category.ts
deleted file mode 100644
index 1dee45401..000000000
--- a/js/src/router/category.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import CategoryList from '@/views/Category/List.vue';
-import CreateCategory from '@/views/Category/Create.vue';
-
-export enum CategoryRouteName {
-  CATEGORY_LIST = 'CategoryList',
-  CREATE_CATEGORY = 'CreateCategory',
-}
-
-export const categoryRoutes = [
-  {
-    path: '/category',
-    name: CategoryRouteName.CATEGORY_LIST,
-    component: CategoryList,
-    meta: { requiredAuth: false },
-  },
-  {
-    path: '/category/create',
-    name: CategoryRouteName.CREATE_CATEGORY,
-    component: CreateCategory,
-    meta: { requiredAuth: true },
-  },
-];
diff --git a/js/src/router/index.ts b/js/src/router/index.ts
index aa259fcd4..0663b53d4 100644
--- a/js/src/router/index.ts
+++ b/js/src/router/index.ts
@@ -5,7 +5,6 @@ import Home from '@/views/Home.vue';
 import { UserRouteName, userRoutes } from './user';
 import { EventRouteName, eventRoutes } from '@/router/event';
 import { ActorRouteName, actorRoutes } from '@/router/actor';
-import { CategoryRouteName, categoryRoutes } from '@/router/category';
 
 Vue.use(Router);
 
@@ -20,7 +19,6 @@ export const RouteName = {
   ...GlobalRouteName,
   ...UserRouteName,
   ...EventRouteName,
-  ...CategoryRouteName,
   ...ActorRouteName,
 };
 
@@ -30,7 +28,6 @@ const router = new Router({
   routes: [
     ...userRoutes,
     ...eventRoutes,
-    ...categoryRoutes,
     ...actorRoutes,
 
     {
diff --git a/js/src/types/event.model.ts b/js/src/types/event.model.ts
index 48c713d13..42893dec8 100644
--- a/js/src/types/event.model.ts
+++ b/js/src/types/event.model.ts
@@ -27,10 +27,12 @@ export enum ParticipantRole {
   CREATOR = 'creator',
 }
 
-export interface ICategory {
-  title: string;
-  description: string;
-  picture: string;
+export enum Category {
+  BUSINESS = 'business',
+  CONFERENCE = 'conference',
+  BIRTHDAY = 'birthday',
+  DEMONSTRATION = 'demonstration',
+  MEETING = 'meeting',
 }
 
 export interface IParticipant {
@@ -47,7 +49,7 @@ export interface IEvent {
 
   title: string;
   description: string;
-  category: ICategory;
+  category: Category;
 
   begins_on: Date;
   ends_on: Date;
diff --git a/js/src/views/Category/Create.vue b/js/src/views/Category/Create.vue
deleted file mode 100644
index 6617bb72d..000000000
--- a/js/src/views/Category/Create.vue
+++ /dev/null
@@ -1,75 +0,0 @@
-<template>
-  <section>
-    <h1 class="title">
-      <translate>Create a new category</translate>
-    </h1>
-    <div class="columns">
-      <form class="column" @submit="submit">
-        <b-field :label="$gettext('Name of the category')">
-          <b-input aria-required="true" required v-model="category.title"/>
-        </b-field>
-
-        <b-field :label="$gettext('Description')">
-          <b-input type="textarea" v-model="category.description"/>
-        </b-field>
-
-        <b-field class="file">
-          <b-upload v-model="file" @input="onFilePicked">
-            <a class="button is-primary">
-              <b-icon icon="upload"></b-icon>
-              <span>
-                <translate>Click to upload</translate>
-              </span>
-            </a>
-          </b-upload>
-          <span class="file-name" v-if="file">{{ this.image.name }}</span>
-        </b-field>
-
-        <button class="button is-primary">
-          <translate>Create the category</translate>
-        </button>
-      </form>
-    </div>
-  </section>
-</template>
-
-<script lang="ts">
-import { CREATE_CATEGORY } from "@/graphql/category";
-import { Component, Vue } from "vue-property-decorator";
-import { ICategory } from "@/types/event.model";
-
-/**
- * TODO : No picture is uploaded ATM
- */
-
-@Component
-export default class CreateCategory extends Vue {
-  category!: ICategory;
-  image = {
-    name: ""
-  } as { name: string };
-  file: any = null;
-
-  create() {
-    this.$apollo
-      .mutate({
-        mutation: CREATE_CATEGORY,
-        variables: this.category
-      })
-      .then(data => {
-        console.log(data);
-      })
-      .catch(error => {
-        console.error(error);
-      });
-  }
-
-  // TODO : Check if we can upload as soon as file is picked and purge files not validated
-  onFilePicked(e) {
-    if (e === undefined || e.name.lastIndexOf(".") <= 0) {
-      console.error("File is incorrect");
-    }
-    this.image.name = e.name;
-  }
-}
-</script>
diff --git a/js/src/views/Category/List.vue b/js/src/views/Category/List.vue
deleted file mode 100644
index 0fb1a6e70..000000000
--- a/js/src/views/Category/List.vue
+++ /dev/null
@@ -1,55 +0,0 @@
-<template>
-  <section>
-    <h1 class="title">
-      <translate>Category List</translate>
-    </h1>
-    <b-loading :active.sync="$apollo.loading"></b-loading>
-    <div class="columns">
-      <div class="column card" v-for="category in categories" :key="category.id">
-        <div class="card-image">
-          <figure class="image is-4by3">
-            <img v-if="category.picture.url" :src="HTTP_ENDPOINT + category.picture.url">
-          </figure>
-        </div>
-        <div class="card-content">
-          <h2 class="title is-4">{{ category.title }}</h2>
-          <p>{{ category.description }}</p>
-        </div>
-      </div>
-    </div>
-  </section>
-</template>
-
-<script lang="ts">
-import { FETCH_CATEGORIES } from "@/graphql/category";
-import { Component, Vue } from "vue-property-decorator";
-
-// TODO : remove this hardcode
-
-@Component({
-  apollo: {
-    categories: {
-      query: FETCH_CATEGORIES
-    }
-  }
-})
-export default class List extends Vue {
-  categories = [];
-  loading = true;
-  HTTP_ENDPOINT = "http://localhost:4000";
-
-  deleteCategory(categoryId) {
-    const router = this.$router;
-    // FIXME: remove eventFetch
-    // eventFetch(`/categories/${categoryId}`, this.$store, { method: 'DELETE' })
-    //   .then(() => {
-    //     this.categories = this.categories.filter(category => category.id !== categoryId);
-    //     router.push('/category');
-    //   });
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-</style>
diff --git a/js/src/views/Event/Create.vue b/js/src/views/Event/Create.vue
index b674f9f66..60e8e55b0 100644
--- a/js/src/views/Event/Create.vue
+++ b/js/src/views/Event/Create.vue
@@ -1,3 +1,4 @@
+import {Category} from "../../types/event.model";
 import {EventJoinOptions} from "../../types/event.model";
 <template>
   <section>
@@ -18,8 +19,8 @@ import {EventJoinOptions} from "../../types/event.model";
             <option
               v-for="category in categories"
               :value="category"
-              :key="category.title"
-            >{{ category.title }}</option>
+              :key="category"
+            >{{ $gettext(category) }}</option>
           </b-select>
         </b-field>
 
@@ -32,30 +33,24 @@ import {EventJoinOptions} from "../../types/event.model";
 </template>
 
 <script lang="ts">
-  // import Location from '@/components/Location';
-  import VueMarkdown from "vue-markdown";
-  import {CREATE_EVENT, EDIT_EVENT} from "@/graphql/event";
-  import {FETCH_CATEGORIES} from "@/graphql/category";
-  import {Component, Prop, Vue} from "vue-property-decorator";
-  import {EventJoinOptions, EventStatus, EventVisibility, ICategory, IEvent} from "@/types/event.model";
-  import {LOGGED_PERSON} from "@/graphql/actor";
-  import {IPerson} from "@/types/actor.model";
+    // import Location from '@/components/Location';
+    import VueMarkdown from "vue-markdown";
+    import {CREATE_EVENT, EDIT_EVENT} from "@/graphql/event";
+    import {Component, Prop, Vue} from "vue-property-decorator";
+    import {Category, EventJoinOptions, EventStatus, EventVisibility, IEvent} from "@/types/event.model";
+    import {LOGGED_PERSON} from "@/graphql/actor";
+    import {IPerson} from "@/types/actor.model";
 
-  @Component({
+    @Component({
   components: {
     VueMarkdown
-  },
-  apollo: {
-    categories: {
-      query: FETCH_CATEGORIES
-    }
   }
 })
 export default class CreateEvent extends Vue {
   @Prop({ required: false, type: String }) uuid!: string;
 
   loggedPerson!: IPerson;
-  categories: ICategory[] = [];
+  categories: string[] = Object.keys(Category);
   event!: IEvent; // FIXME: correctly type an event
 
   // created() {
@@ -77,7 +72,7 @@ export default class CreateEvent extends Vue {
       description: "",
       begins_on: new Date(),
       ends_on: new Date(),
-      category: this.categories[0],
+      category: Category.MEETING,
       participants: [],
       uuid: "",
       url: "",
@@ -102,7 +97,7 @@ export default class CreateEvent extends Vue {
             title: this.event.title,
             description: this.event.description,
             beginsOn: this.event.begins_on,
-            category: this.event.category.title,
+            category: this.event.category,
             organizerActorId: this.event.organizerActor.id
           }
         })
diff --git a/js/src/views/Event/Event.vue b/js/src/views/Event/Event.vue
index bc946442d..9510dcf48 100644
--- a/js/src/views/Event/Event.vue
+++ b/js/src/views/Event/Event.vue
@@ -10,7 +10,7 @@
         </div>
         <div class="card-content">
           <span>{{ event.begins_on | formatDay }}</span>
-          <span class="tag is-primary">{{ event.category.title }}</span>
+          <span class="tag is-primary">{{ event.category }}</span>
           <h1 class="title">{{ event.title }}</h1>
           <router-link
             :to="{name: 'Profile', params: { name: event.organizerActor.preferredUsername } }"
diff --git a/lib/mobilizon/events/category.ex b/lib/mobilizon/events/category.ex
deleted file mode 100644
index a9afeea2f..000000000
--- a/lib/mobilizon/events/category.ex
+++ /dev/null
@@ -1,26 +0,0 @@
-defmodule Mobilizon.Events.Category do
-  @moduledoc """
-  Represents a category for events
-  """
-  use Ecto.Schema
-  import Ecto.Changeset
-  alias Mobilizon.Events.Category
-  use Arc.Ecto.Schema
-
-  schema "categories" do
-    field(:description, :string)
-    field(:picture, MobilizonWeb.Uploaders.Category.Type)
-    field(:title, :string, null: false)
-
-    timestamps()
-  end
-
-  @doc false
-  def changeset(%Category{} = category, attrs) do
-    category
-    |> cast(attrs, [:title, :description])
-    |> cast_attachments(attrs, [:picture])
-    |> validate_required([:title])
-    |> unique_constraint(:title)
-  end
-end
diff --git a/lib/mobilizon/events/event.ex b/lib/mobilizon/events/event.ex
index 98a82876f..05fbfe3a8 100644
--- a/lib/mobilizon/events/event.ex
+++ b/lib/mobilizon/events/event.ex
@@ -19,13 +19,21 @@ defenum(Mobilizon.Events.EventStatusEnum, :event_status_type, [
   :cancelled
 ])
 
+defenum(Mobilizon.Event.EventCategoryEnum, :event_category_type, [
+  :business,
+  :conference,
+  :birthday,
+  :demonstration,
+  :meeting
+])
+
 defmodule Mobilizon.Events.Event do
   @moduledoc """
   Represents an event
   """
   use Ecto.Schema
   import Ecto.Changeset
-  alias Mobilizon.Events.{Event, Participant, Tag, Category, Session, Track}
+  alias Mobilizon.Events.{Event, Participant, Tag, Session, Track}
   alias Mobilizon.Actors.Actor
   alias Mobilizon.Addresses.Address
 
@@ -45,10 +53,10 @@ defmodule Mobilizon.Events.Event do
     field(:uuid, Ecto.UUID, default: Ecto.UUID.generate())
     field(:online_address, :string)
     field(:phone_address, :string)
+    field(:category, :string)
     belongs_to(:organizer_actor, Actor, foreign_key: :organizer_actor_id)
     belongs_to(:attributed_to, Actor, foreign_key: :attributed_to_id)
     many_to_many(:tags, Tag, join_through: "events_tags")
-    belongs_to(:category, Category)
     many_to_many(:participants, Actor, join_through: Participant)
     has_many(:tracks, Track)
     has_many(:sessions, Session)
@@ -67,7 +75,7 @@ defmodule Mobilizon.Events.Event do
       :begins_on,
       :ends_on,
       :organizer_actor_id,
-      :category_id,
+      :category,
       :status,
       :visibility,
       :thumbnail,
@@ -83,7 +91,7 @@ defmodule Mobilizon.Events.Event do
       :title,
       :begins_on,
       :organizer_actor_id,
-      :category_id,
+      :category,
       :url,
       :uuid
     ])
diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex
index 6fc784991..6bf3ea1ec 100644
--- a/lib/mobilizon/events/events.ex
+++ b/lib/mobilizon/events/events.ex
@@ -27,7 +27,6 @@ defmodule Mobilizon.Events do
         order_by: [desc: :id],
         preload: [
           :organizer_actor,
-          :category,
           :sessions,
           :tracks,
           :tags,
@@ -145,7 +144,6 @@ defmodule Mobilizon.Events do
       where: e.uuid == ^uuid and e.visibility in [^:public, ^:unlisted],
       preload: [
         :organizer_actor,
-        :category,
         :sessions,
         :tracks,
         :tags,
@@ -164,7 +162,6 @@ defmodule Mobilizon.Events do
 
     Repo.preload(event, [
       :organizer_actor,
-      :category,
       :sessions,
       :tracks,
       :tags,
@@ -182,7 +179,6 @@ defmodule Mobilizon.Events do
              where: e.url == ^url and e.visibility in [^:public, ^:unlisted],
              preload: [
                :organizer_actor,
-               :category,
                :sessions,
                :tracks,
                :tags,
@@ -205,7 +201,6 @@ defmodule Mobilizon.Events do
         where: e.url == ^url and e.visibility in [^:public, ^:unlisted],
         preload: [
           :organizer_actor,
-          :category,
           :sessions,
           :tracks,
           :tags,
@@ -350,110 +345,6 @@ defmodule Mobilizon.Events do
     Event.changeset(event, %{})
   end
 
-  alias Mobilizon.Events.Category
-
-  @doc """
-  Returns the list of categories.
-
-  ## Examples
-
-      iex> list_categories()
-      [%Category{}, ...]
-
-  """
-  def list_categories(page \\ nil, limit \\ nil) do
-    Repo.all(
-      Category
-      |> paginate(page, limit)
-    )
-  end
-
-  @doc """
-  Gets a single category.
-
-  Raises `Ecto.NoResultsError` if the Category does not exist.
-
-  ## Examples
-
-      iex> get_category!(123)
-      %Category{}
-
-      iex> get_category!(456)
-      ** (Ecto.NoResultsError)
-
-  """
-  def get_category!(id), do: Repo.get!(Category, id)
-
-  @spec get_category_by_title(String.t()) :: Category.t() | nil
-  def get_category_by_title(title) when is_binary(title) do
-    Repo.get_by(Category, title: title)
-  end
-
-  @doc """
-  Creates a category.
-
-  ## Examples
-
-      iex> create_category(%{field: value})
-      {:ok, %Category{}}
-
-      iex> create_category(%{field: bad_value})
-      {:error, %Ecto.Changeset{}}
-
-  """
-  def create_category(attrs \\ %{}) do
-    %Category{}
-    |> Category.changeset(attrs)
-    |> Repo.insert()
-  end
-
-  @doc """
-  Updates a category.
-
-  ## Examples
-
-      iex> update_category(category, %{field: new_value})
-      {:ok, %Category{}}
-
-      iex> update_category(category, %{field: bad_value})
-      {:error, %Ecto.Changeset{}}
-
-  """
-  def update_category(%Category{} = category, attrs) do
-    category
-    |> Category.changeset(attrs)
-    |> Repo.update()
-  end
-
-  @doc """
-  Deletes a Category.
-
-  ## Examples
-
-      iex> delete_category(category)
-      {:ok, %Category{}}
-
-      iex> delete_category(category)
-      {:error, %Ecto.Changeset{}}
-
-  """
-  def delete_category(%Category{} = category) do
-    Repo.delete(category)
-  end
-
-  @doc """
-  Returns an `%Ecto.Changeset{}` for tracking category changes.
-
-  ## Examples
-
-      iex> change_category(category)
-      %Ecto.Changeset{source: %Category{}}
-
-  """
-  def change_category(%Category{} = category) do
-    Category.changeset(category, %{})
-  end
-
   alias Mobilizon.Events.Tag
 
   @doc """
diff --git a/lib/mobilizon_web/resolvers/category.ex b/lib/mobilizon_web/resolvers/category.ex
deleted file mode 100644
index d7d8997e8..000000000
--- a/lib/mobilizon_web/resolvers/category.ex
+++ /dev/null
@@ -1,48 +0,0 @@
-defmodule MobilizonWeb.Resolvers.Category do
-  @moduledoc """
-  Handles the category-related GraphQL calls
-  """
-  require Logger
-  alias Mobilizon.Actors.User
-
-  ###
-  # TODO : Refactor this into MobilizonWeb.API.Categories when a standard AS category is defined
-  ###
-  def list_categories(_parent, %{page: page, limit: limit}, _resolution) do
-    categories =
-      Mobilizon.Events.list_categories(page, limit)
-      |> Enum.map(fn category ->
-        urls = MobilizonWeb.Uploaders.Category.urls({category.picture, category})
-        Map.put(category, :picture, %{url: urls.original, url_thumbnail: urls.thumb})
-      end)
-
-    {:ok, categories}
-  end
-
-  def create_category(_parent, %{title: title, picture: picture, description: description}, %{
-        context: %{current_user: %User{} = _user}
-      }) do
-    with {:ok, category} <-
-           Mobilizon.Events.create_category(%{
-             title: title,
-             description: description,
-             picture: picture
-           }),
-         urls <- MobilizonWeb.Uploaders.Category.urls({category.picture, category}) do
-      Logger.info("Created category " <> title)
-      {:ok, Map.put(category, :picture, %{url: urls.original, url_thumbnail: urls.thumb})}
-    else
-      {:error, %Ecto.Changeset{errors: errors} = _changeset} ->
-        # This is pretty ridiculous for changeset to error
-        errors =
-          Enum.into(errors, %{})
-          |> Enum.map(fn {key, {value, _}} -> Atom.to_string(key) <> ": " <> value end)
-
-        {:error, errors}
-    end
-  end
-
-  def create_category(_parent, _args, %{}) do
-    {:error, "You are not allowed to create a category if not connected"}
-  end
-end
diff --git a/lib/mobilizon_web/schema.ex b/lib/mobilizon_web/schema.ex
index b3d741eb7..7d6ff35ae 100644
--- a/lib/mobilizon_web/schema.ex
+++ b/lib/mobilizon_web/schema.ex
@@ -130,7 +130,6 @@ defmodule MobilizonWeb.Schema do
     import_fields(:group_queries)
     import_fields(:event_queries)
     import_fields(:participant_queries)
-    import_fields(:category_queries)
     import_fields(:tag_queries)
   end
 
@@ -142,7 +141,6 @@ defmodule MobilizonWeb.Schema do
     import_fields(:person_mutations)
     import_fields(:group_mutations)
     import_fields(:event_mutations)
-    import_fields(:category_mutations)
     import_fields(:comment_mutations)
     import_fields(:participant_mutations)
 
diff --git a/lib/mobilizon_web/schema/event.ex b/lib/mobilizon_web/schema/event.ex
index 1214bf3a0..5747aeb50 100644
--- a/lib/mobilizon_web/schema/event.ex
+++ b/lib/mobilizon_web/schema/event.ex
@@ -7,7 +7,6 @@ defmodule MobilizonWeb.Schema.EventType do
   import Absinthe.Resolution.Helpers, only: [dataloader: 1]
   import_types(MobilizonWeb.Schema.AddressType)
   import_types(MobilizonWeb.Schema.Events.ParticipantType)
-  import_types(MobilizonWeb.Schema.Events.CategoryType)
   import_types(MobilizonWeb.Schema.TagType)
   alias MobilizonWeb.Resolvers
 
@@ -44,7 +43,7 @@ defmodule MobilizonWeb.Schema.EventType do
       description: "The event's tags"
     )
 
-    field(:category, :category, description: "The event's category")
+    field(:category, :string, description: "The event's category")
 
     field(:participants, list_of(:participant),
       resolve: &MobilizonWeb.Resolvers.Event.list_participants_for_event/3,
diff --git a/lib/mobilizon_web/schema/events/category.ex b/lib/mobilizon_web/schema/events/category.ex
deleted file mode 100644
index 521000ac7..000000000
--- a/lib/mobilizon_web/schema/events/category.ex
+++ /dev/null
@@ -1,34 +0,0 @@
-defmodule MobilizonWeb.Schema.Events.CategoryType do
-  @moduledoc """
-  Schema representation for Category
-  """
-  use Absinthe.Schema.Notation
-  alias MobilizonWeb.Resolvers
-
-  @desc "A category"
-  object :category do
-    field(:id, :id, description: "The category's ID")
-    field(:description, :string, description: "The category's description")
-    field(:picture, :picture, description: "The category's picture")
-    field(:title, :string, description: "The category's title")
-  end
-
-  object :category_queries do
-    @desc "Get the list of categories"
-    field :categories, non_null(list_of(:category)) do
-      arg(:page, :integer, default_value: 1)
-      arg(:limit, :integer, default_value: 10)
-      resolve(&Resolvers.Category.list_categories/3)
-    end
-  end
-
-  object :category_mutations do
-    @desc "Create a category with a title, description and picture"
-    field :create_category, type: :category do
-      arg(:title, non_null(:string))
-      arg(:description, non_null(:string))
-      arg(:picture, non_null(:upload))
-      resolve(&Resolvers.Category.create_category/3)
-    end
-  end
-end
diff --git a/lib/mobilizon_web/uploaders/category.ex b/lib/mobilizon_web/uploaders/event.ex
similarity index 91%
rename from lib/mobilizon_web/uploaders/category.ex
rename to lib/mobilizon_web/uploaders/event.ex
index 247085f45..9f888e4a4 100644
--- a/lib/mobilizon_web/uploaders/category.ex
+++ b/lib/mobilizon_web/uploaders/event.ex
@@ -30,10 +30,9 @@ defmodule MobilizonWeb.Uploaders.Category do
     "#{title}_#{version}"
   end
 
-  # TODO : When we're sure creating a category is secured and made possible only for admins, use category name
   # Override the storage directory:
   def storage_dir(_, _) do
-    "uploads/categories/"
+    "uploads/event/"
   end
 
   # Provide a default URL if there hasn't been a file uploaded
diff --git a/lib/mobilizon_web/views/activity_pub/object_view.ex b/lib/mobilizon_web/views/activity_pub/object_view.ex
index d7b67055c..e8dcfa12a 100644
--- a/lib/mobilizon_web/views/activity_pub/object_view.ex
+++ b/lib/mobilizon_web/views/activity_pub/object_view.ex
@@ -1,6 +1,5 @@
 defmodule MobilizonWeb.ActivityPub.ObjectView do
   use MobilizonWeb, :view
-  alias MobilizonWeb.ActivityPub.ObjectView
   alias Mobilizon.Service.ActivityPub.Utils
 
   def render("event.json", %{event: event}) do
@@ -9,7 +8,7 @@ defmodule MobilizonWeb.ActivityPub.ObjectView do
       "actor" => event["actor"],
       "id" => event["id"],
       "name" => event["title"],
-      "category" => render_one(event["category"], ObjectView, "category.json", as: :category),
+      "category" => event["category"],
       "content" => event["summary"],
       "mediaType" => "text/html"
       # "published" => Timex.format!(event.inserted_at, "{ISO:Extended}"),
@@ -35,15 +34,4 @@ defmodule MobilizonWeb.ActivityPub.ObjectView do
 
     Map.merge(comment, Utils.make_json_ld_header())
   end
-
-  def render("category.json", %{category: category}) when not is_nil(category) do
-    %{
-      "identifier" => category.id,
-      "name" => category.title
-    }
-  end
-
-  def render("category.json", %{category: _category}) do
-    nil
-  end
 end
diff --git a/lib/service/activity_pub/activity_pub.ex b/lib/service/activity_pub/activity_pub.ex
index 01f7c1d65..193806762 100644
--- a/lib/service/activity_pub/activity_pub.ex
+++ b/lib/service/activity_pub/activity_pub.ex
@@ -11,7 +11,7 @@ defmodule Mobilizon.Service.ActivityPub do
   """
 
   alias Mobilizon.Events
-  alias Mobilizon.Events.{Event, Category, Comment}
+  alias Mobilizon.Events.{Event, Comment}
   alias Mobilizon.Service.ActivityPub.Transmogrifier
   alias Mobilizon.Service.WebFinger
   alias Mobilizon.Activity
@@ -565,23 +565,8 @@ defmodule Mobilizon.Service.ActivityPub do
     # TODO : Use MobilizonWeb.API instead
     # TODO : refactor me and move me somewhere else!
     # TODO : also, there should be a form of cache that allows this to be more efficient
-    category =
-      if is_nil(ical_event.categories) do
-        nil
-      else
-        ical_category = ical_event.categories |> hd() |> String.downcase()
 
-        case ical_category |> Events.get_category_by_title() do
-          nil ->
-            case Events.create_category(%{"title" => ical_category}) do
-              {:ok, %Category{} = category} -> category
-              _ -> nil
-            end
-
-          category ->
-            category
-        end
-      end
+    # ical_event.categories should be tags
 
     {:ok, event} =
       Events.create_event(%{
@@ -591,8 +576,7 @@ defmodule Mobilizon.Service.ActivityPub do
         updated_at: ical_event.stamp,
         description: ical_event.description |> sanitize_ical_event_strings,
         title: ical_event.summary |> sanitize_ical_event_strings,
-        organizer_actor: actor,
-        category: category
+        organizer_actor: actor
       })
 
     event_to_activity(event, false)
diff --git a/lib/service/activity_pub/utils.ex b/lib/service/activity_pub/utils.ex
index 637b1c132..d00a49a93 100644
--- a/lib/service/activity_pub/utils.ex
+++ b/lib/service/activity_pub/utils.ex
@@ -117,7 +117,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
       "description" => object["content"],
       "organizer_actor_id" => actor_id,
       "begins_on" => object["begins_on"],
-      "category_id" => Events.get_category_by_title(object["category"]).id,
+      "category" => object["category"],
       "url" => object["id"],
       "uuid" => object["uuid"]
     }
diff --git a/mix.lock b/mix.lock
index 8e9a80ecb..c065b8b12 100644
--- a/mix.lock
+++ b/mix.lock
@@ -71,7 +71,7 @@
   "phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
   "phoenix_html": {:hex, :phoenix_html, "2.13.1", "fa8f034b5328e2dfa0e4131b5569379003f34bc1fafdaa84985b0b9d2f12e68b", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
   "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.0", "3bb31a9fbd40ffe8652e60c8660dffd72dd231efcdf49b744fb75b9ef7db5dd2", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"},
-  "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.1", "6668d787e602981f24f17a5fbb69cc98f8ab085114ebfac6cc36e10a90c8e93c", [:mix], [], "hexpm"},
+  "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm"},
   "plug": {:hex, :plug, "1.7.2", "d7b7db7fbd755e8283b6c0a50be71ec0a3d67d9213d74422d9372effc8e87fd1", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}], "hexpm"},
   "plug_cowboy": {:hex, :plug_cowboy, "2.0.1", "d798f8ee5acc86b7d42dbe4450b8b0dadf665ce588236eb0a751a132417a980e", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
   "plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"},
diff --git a/priv/repo/migrations/20190222151449_drop_categories.exs b/priv/repo/migrations/20190222151449_drop_categories.exs
new file mode 100644
index 000000000..3211a4702
--- /dev/null
+++ b/priv/repo/migrations/20190222151449_drop_categories.exs
@@ -0,0 +1,35 @@
+defmodule Mobilizon.Repo.Migrations.DropCategories do
+  use Ecto.Migration
+
+  def up do
+    # The category field is a string for the time being
+    # while we determine the definitive minimal list of
+    # categories in https://framagit.org/framasoft/mobilizon/issues/30
+    # afterwards it will be a PostgreSQL enum and we'll
+    # just add new elements without being able to delete
+    # the previous ones
+    alter table(:events) do
+      add(:category, :string)
+      remove(:category_id)
+    end
+
+    drop(table(:categories))
+  end
+
+  def down do
+    create table(:categories) do
+      add(:title, :string)
+      add(:description, :string)
+      add(:picture, :string)
+
+      timestamps()
+    end
+
+    create(unique_index(:categories, [:title]))
+
+    alter table(:events) do
+      remove(:category)
+      add(:category_id, references(:categories, on_delete: :nothing))
+    end
+  end
+end
diff --git a/test/mobilizon/events/events_test.exs b/test/mobilizon/events/events_test.exs
index ddf92e29d..b07283994 100644
--- a/test/mobilizon/events/events_test.exs
+++ b/test/mobilizon/events/events_test.exs
@@ -11,7 +11,8 @@ defmodule Mobilizon.EventsTest do
     ends_on: "2010-04-17 14:00:00Z",
     title: "some title",
     url: "some url",
-    uuid: "b5126423-f1af-43e4-a923-002a03003ba4"
+    uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
+    category: "meeting"
   }
 
   describe "events" do
@@ -79,14 +80,12 @@ defmodule Mobilizon.EventsTest do
 
     test "create_event/1 with valid data creates a event" do
       actor = insert(:actor)
-      category = insert(:category)
       address = insert(:address)
 
       valid_attrs =
         @event_valid_attrs
         |> Map.put(:organizer_actor, actor)
         |> Map.put(:organizer_actor_id, actor.id)
-        |> Map.put(:category_id, category.id)
         |> Map.put(:address_id, address.id)
 
       with {:ok, %Event{} = event} <- Events.create_event(valid_attrs) do
@@ -175,77 +174,6 @@ defmodule Mobilizon.EventsTest do
     end
   end
 
-  describe "categories" do
-    alias Mobilizon.Events.Category
-
-    setup do
-      category = insert(:category)
-      {:ok, category: category}
-    end
-
-    @valid_attrs %{
-      description: "some description",
-      picture: %Plug.Upload{
-        path: "test/fixtures/category_picture.png",
-        filename: "category_picture.png"
-      },
-      title: "some title"
-    }
-    @update_attrs %{
-      description: "some updated description",
-      picture: %Plug.Upload{
-        path: "test/fixtures/category_picture_updated.png",
-        filename: "category_picture_updated.png"
-      },
-      title: "some updated title"
-    }
-    @invalid_attrs %{description: nil, picture: nil, title: nil}
-
-    test "list_categories/0 returns all categories", %{category: category} do
-      assert [category.id] == Events.list_categories() |> Enum.map(& &1.id)
-    end
-
-    test "get_category!/1 returns the category with given id", %{category: category} do
-      assert Events.get_category!(category.id).id == category.id
-    end
-
-    test "get_category_by_title/1 return the category with given title", %{category: category} do
-      assert Events.get_category_by_title(category.title).id == category.id
-    end
-
-    test "create_category/1 with valid data creates a category" do
-      assert {:ok, %Category{} = category} = Events.create_category(@valid_attrs)
-      assert category.description == "some description"
-      assert category.picture.file_name == @valid_attrs.picture.filename
-      assert category.title == "some title"
-    end
-
-    test "create_category/1 with invalid data returns error changeset" do
-      assert {:error, %Ecto.Changeset{}} = Events.create_category(@invalid_attrs)
-    end
-
-    test "update_category/2 with valid data updates the category", %{category: category} do
-      assert {:ok, %Category{} = category} = Events.update_category(category, @update_attrs)
-      assert category.description == "some updated description"
-      assert category.picture.file_name == @update_attrs.picture.filename
-      assert category.title == "some updated title"
-    end
-
-    test "update_category/2 with invalid data returns error changeset", %{category: category} do
-      assert {:error, %Ecto.Changeset{}} = Events.update_category(category, @invalid_attrs)
-      assert category.description == Events.get_category!(category.id).description
-    end
-
-    test "delete_category/1 deletes the category", %{category: category} do
-      assert {:ok, %Category{}} = Events.delete_category(category)
-      assert_raise Ecto.NoResultsError, fn -> Events.get_category!(category.id) end
-    end
-
-    test "change_category/1 returns a category changeset", %{category: category} do
-      assert %Ecto.Changeset{} = Events.change_category(category)
-    end
-  end
-
   describe "tags" do
     alias Mobilizon.Events.Tag
 
diff --git a/test/mobilizon_web/resolvers/category_resolver_test.exs b/test/mobilizon_web/resolvers/category_resolver_test.exs
deleted file mode 100644
index bfc82b7a7..000000000
--- a/test/mobilizon_web/resolvers/category_resolver_test.exs
+++ /dev/null
@@ -1,77 +0,0 @@
-defmodule MobilizonWeb.Resolvers.CategoryResolverTest do
-  use MobilizonWeb.ConnCase
-  alias MobilizonWeb.AbsintheHelpers
-  import Mobilizon.Factory
-
-  setup %{conn: conn} do
-    user = insert(:user)
-    actor = insert(:actor, user: user)
-
-    {:ok, conn: conn, actor: actor, user: user}
-  end
-
-  describe "Category Resolver" do
-    test "list_categories/3 returns the list of categories", context do
-      insert(:category)
-      insert(:category)
-
-      query = """
-      {
-          categories {
-              id,
-              title,
-              description,
-              picture {
-                  url,
-              },
-          }
-      }
-      """
-
-      res =
-        context.conn
-        |> get("/api", AbsintheHelpers.query_skeleton(query, "categories"))
-
-      assert json_response(res, 200)["data"]["categories"] |> length == 2
-    end
-
-    # We can't test an upload…yet?
-    # test "create_category/3 creates a category", %{conn: conn, actor: actor, user: user} do
-    #   mutation = """
-    #       mutation {
-    #         createCategory(title: "my category", description: "my desc") {
-    #             id,
-    #             title,
-    #             description,
-    #         },
-    #       }
-    #   """
-
-    #   res =
-    #     conn
-    #     |> auth_conn(user)
-    #     |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
-
-    #   assert json_response(res, 200)["data"]["createCategory"]["title"] == "my category"
-    # end
-
-    # test "create_category/3 doesn't create a category if the user isn't logged in", %{conn: conn, actor: actor} do
-    #   mutation = """
-    #       mutation {
-    #         createCategory(title: "my category", description: "my desc") {
-    #             id,
-    #             title,
-    #             description,
-    #         },
-    #       }
-    #   """
-
-    #   res =
-    #     conn
-    #     |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
-
-    #     assert hd(json_response(res, 200)["errors"])["message"] ==
-    #     "You are not allowed to create a category if not connected"
-    # end
-  end
-end
diff --git a/test/mobilizon_web/resolvers/event_resolver_test.exs b/test/mobilizon_web/resolvers/event_resolver_test.exs
index 8759086d0..636386364 100644
--- a/test/mobilizon_web/resolvers/event_resolver_test.exs
+++ b/test/mobilizon_web/resolvers/event_resolver_test.exs
@@ -9,7 +9,8 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
     title: "some title",
     begins_on: DateTime.utc_now() |> DateTime.truncate(:second),
     uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
-    url: "some url"
+    url: "some url",
+    category: "meeting"
   }
 
   setup %{conn: conn} do
@@ -21,12 +22,9 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
 
   describe "Event Resolver" do
     test "find_event/3 returns an event", context do
-      category = insert(:category)
-
       event =
         @event
         |> Map.put(:organizer_actor_id, context.actor.id)
-        |> Map.put(:category_id, category.id)
 
       {:ok, event} = Events.create_event(event)
 
@@ -61,8 +59,6 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
     end
 
     test "create_event/3 creates an event", %{conn: conn, actor: actor, user: user} do
-      category = insert(:category)
-
       mutation = """
           mutation {
               createEvent(
@@ -72,7 +68,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
         DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
       }",
                   organizer_actor_id: "#{actor.id}",
-                  category: "#{category.title}"
+                  category: "birthday"
               ) {
                 title,
                 uuid
diff --git a/test/mobilizon_web/resolvers/participant_resolver_test.exs b/test/mobilizon_web/resolvers/participant_resolver_test.exs
index 070d6c0c1..bf526c8c2 100644
--- a/test/mobilizon_web/resolvers/participant_resolver_test.exs
+++ b/test/mobilizon_web/resolvers/participant_resolver_test.exs
@@ -9,7 +9,8 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
     title: "some title",
     begins_on: DateTime.utc_now() |> DateTime.truncate(:second),
     uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
-    url: "some url"
+    url: "some url",
+    category: "meeting"
   }
 
   setup %{conn: conn} do
@@ -313,13 +314,9 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
     end
 
     test "list_participants_for_event/3 returns participants for an event", context do
-      # Plain event
-      category = insert(:category)
-
       event =
         @event
         |> Map.put(:organizer_actor_id, context.actor.id)
-        |> Map.put(:category_id, category.id)
 
       {:ok, event} = Events.create_event(event)
 
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 33075e4d0..13281407e 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -53,13 +53,6 @@ defmodule Mobilizon.Factory do
     }
   end
 
-  def category_factory do
-    %Mobilizon.Events.Category{
-      title: sequence("MyCategory"),
-      description: "My category desc"
-    }
-  end
-
   def tag_factory do
     %Mobilizon.Events.Tag{
       title: "MyTag",
@@ -112,7 +105,7 @@ defmodule Mobilizon.Factory do
       begins_on: start,
       ends_on: Timex.shift(start, hours: 2),
       organizer_actor: actor,
-      category: build(:category),
+      category: sequence("something"),
       physical_address: build(:address),
       visibility: :public,
       url: "#{actor.url}/#{uuid}",