diff --git a/crawler.py b/crawler.py
index 1c45f67ba3e24916e8747ff396fc5d12d2ea0b00..417e139004cda71ed053290767f2c40d79d2c364 100644
--- a/crawler.py
+++ b/crawler.py
@@ -1,7 +1,7 @@
 import re
 from collections import namedtuple
 from datetime import date, datetime, timedelta
-from typing import Dict, Set
+from typing import Dict, List, Set
 
 import requests
 from bs4 import BeautifulSoup
@@ -16,7 +16,9 @@ cached_update_times: Dict[Location, datetime] = dict()
 cached_responses: Dict[Location, LocationDays] = dict()
 
 
-def get_location_days(location: Location) -> LocationDays:
+def get_location_days(
+    location: Location, menu_item_indicators: List[MenuItemIndicator]
+) -> LocationDays:
     global cached_responses
     global cached_update_times
 
@@ -58,21 +60,17 @@ def get_location_days(location: Location) -> LocationDays:
                 elif child.name == "a":
                     if not child.select_one("img"):
                         continue
-                    href = child["href"]
-                    if "Vegano" in href:
-                        item_indicators.add(MenuItemIndicator.VEGAN)
-                    elif "Gluten" in href:
-                        item_indicators.add(MenuItemIndicator.GLUTEN)
-                    elif "Leite" in href:
-                        item_indicators.add(MenuItemIndicator.LACTOSE)
-                    elif "animal" in href:
-                        item_indicators.add(MenuItemIndicator.ANIMAL)
-                    elif "Ovo" in href:
-                        item_indicators.add(MenuItemIndicator.EGG)
-                    elif "Mel" in href:
-                        item_indicators.add(MenuItemIndicator.HONEY)
-                    elif "Alergenicos" in href:
-                        item_indicators.add(MenuItemIndicator.ALERGIC)
+                    href = child["href"].lower()
+                    indicator = next(
+                        (
+                            indicator
+                            for indicator in menu_item_indicators
+                            if indicator.find_text in href
+                        ),
+                        None,
+                    )
+                    if indicator is not None:
+                        item_indicators.add(indicator)
                 elif child.text.strip() != "":
                     item_name = child.text.strip()
             if item_name is not None:
diff --git a/database.py b/database.py
index d1080c237a9329ba18612affe9d42e45bfa21ed6..16078b4ba941eacaa3954e62d42230cf1da90b7c 100644
--- a/database.py
+++ b/database.py
@@ -9,8 +9,12 @@ try:
 except ImportError:
     from backports.zoneinfo import ZoneInfo  # type: ignore
 
-from model import Location, Meal, Schedule, WeekDay
-from seed import get_seed_locations, get_seed_meals
+from model import Location, Meal, MenuItemIndicator, Schedule, WeekDay
+from seed import (
+    get_seed_locations,
+    get_seed_meals,
+    get_seed_menu_item_indicators,
+)
 
 CURITIBA_TZ = ZoneInfo("America/Sao_Paulo")
 
@@ -31,13 +35,13 @@ with connection:
     connection.execute(
         dedent(
             """\
-    CREATE TABLE IF NOT EXISTS location (
-            name TEXT NOT NULL PRIMARY KEY,
-            command TEXT NOT NULL,
-            ordering INT NOT NULL,
-            url TEXT NOT NULL
+        CREATE TABLE IF NOT EXISTS location (
+                name TEXT NOT NULL PRIMARY KEY,
+                command TEXT NOT NULL,
+                ordering INT NOT NULL,
+                url TEXT NOT NULL
         )
-    """
+            """
         )
     )
     connection.execute(
@@ -54,7 +58,7 @@ with connection:
             end_time TEXT NOT NULL,
             PRIMARY KEY (location_name, name, week_day)
         )
-    """
+            """
         )
     )
     connection.execute(
@@ -72,7 +76,33 @@ with connection:
                 REFERENCES meal(location_name, name, week_day)
                 DEFERRABLE INITIALLY DEFERRED
         )
-    """
+            """
+        )
+    )
+    connection.execute(
+        dedent(
+            """
+        CREATE TABLE IF NOT EXISTS menu_item_indicator (
+            emoji TEXT NOT NULL PRIMARY KEY,
+            description TEXT NOT NULL,
+            find_text TEXT NOT NULL,
+            ordering INT NOT NULL
+        )
+            """
+        )
+    )
+    connection.execute(
+        dedent(
+            """
+        CREATE TABLE IF NOT EXISTS menu_item_indicator_preferences (
+            menu_item_indicator_emoji TEXT NOT NULL
+                REFERENCES menu_item_indicator(emoji)
+                DEFERRABLE INITIALLY DEFERRED,
+            user_id INT NOT NULL,
+            show BOOLEAN TEXT NOT NULL,
+            PRIMARY KEY (menu_item_indicator_emoji, user_id)
+        )
+            """
         )
     )
     cur = connection.cursor()
@@ -83,9 +113,9 @@ with connection:
         cur.execute(
             dedent(
                 """\
-            INSERT INTO location (name, command, ordering, url)
-            VALUES (?, ?, ?, ?)
-        """
+                INSERT INTO location (name, command, ordering, url)
+                VALUES (?, ?, ?, ?)
+                """
             ),
             location,
         )
@@ -103,6 +133,20 @@ with connection:
             ),
             meal,
         )
+    cur.execute("DELETE FROM menu_item_indicator")
+    seed_menu_item_indicators = get_seed_menu_item_indicators()
+    for menu_item_indicator in seed_menu_item_indicators:
+        cur.execute(
+            dedent(
+                """\
+            INSERT INTO menu_item_indicator
+            (emoji, description, find_text, ordering)
+            VALUES
+            (?, ?, ?, ?)
+        """
+            ),
+            menu_item_indicator,
+        )
     cur.execute("COMMIT")
 
 
@@ -336,7 +380,7 @@ def get_meals():
     return get_meals_query(
         dedent(
             """\
-        ORDER BY location.name, meal.ordering, meal.week_day
+        ORDER BY location.ordering, meal.ordering, meal.week_day
     """
         )
     )
@@ -352,3 +396,97 @@ def get_meals_by_location_name(location_name):
         ),
         (location_name,),
     )
+
+
+def get_menu_item_indicators():
+    cur = connection.execute(
+        dedent(
+            """\
+        SELECT
+            menu_item_indicator.emoji,
+            menu_item_indicator.description,
+            menu_item_indicator.find_text,
+            menu_item_indicator.ordering
+        FROM menu_item_indicator
+        ORDER BY menu_item_indicator.ordering
+    """
+        ),
+    )
+    rows = cur.fetchall()
+    return [
+        MenuItemIndicator(
+            emoji=emoji,
+            description=description,
+            find_text=find_text,
+            ordering=ordering,
+        )
+        for (
+            emoji,
+            description,
+            find_text,
+            ordering,
+        ) in rows
+    ]
+
+
+def get_shown_menu_item_indicators_for_user(user_id):
+    cur = connection.execute(
+        dedent(
+            """\
+        SELECT
+            menu_item_indicator.emoji,
+            menu_item_indicator.description,
+            menu_item_indicator.find_text,
+            menu_item_indicator.ordering
+        FROM menu_item_indicator
+        LEFT JOIN menu_item_indicator_preferences
+        ON menu_item_indicator_preferences.menu_item_indicator_emoji
+            = menu_item_indicator.emoji
+            AND menu_item_indicator_preferences.user_id = ?
+        WHERE (menu_item_indicator_preferences.show IS NULL
+            OR menu_item_indicator_preferences.show = 1)
+        ORDER BY menu_item_indicator.ordering
+    """
+        ),
+        (user_id,),
+    )
+    rows = cur.fetchall()
+    return [
+        MenuItemIndicator(
+            emoji=emoji,
+            description=description,
+            find_text=find_text,
+            ordering=ordering,
+        )
+        for (
+            emoji,
+            description,
+            find_text,
+            ordering,
+        ) in rows
+    ]
+
+
+def delete_menu_item_indicator_preference(emoji, user_id):
+    connection.execute(
+        dedent(
+            """\
+        DELETE FROM menu_item_indicator_preferences
+        WHERE menu_item_indicator_emoji = ? AND user_id = ?
+            """
+        ),
+        (emoji, user_id),
+    )
+
+
+def insert_menu_item_indicator_preference(emoji, user_id, show):
+    connection.execute(
+        dedent(
+            """\
+        INSERT INTO menu_item_indicator_preferences
+        (menu_item_indicator_emoji, user_id, show)
+        VALUES (?, ?, ?)
+            """
+        ),
+        (emoji, user_id, show),
+    )
diff --git a/main.py b/main.py
index 63a426165e9f04f4a70cb70ef5b9b1a74aabdfd5..6336572b3cdc241d3a10aff0390304e6d2f241f4 100644
--- a/main.py
+++ b/main.py
@@ -8,7 +8,7 @@ from datetime import date, datetime, timedelta
 from itertools import groupby
 from pprint import pformat
 from textwrap import dedent
-from typing import Dict, Optional, Set
+from typing import Dict, Literal, Optional, Set
 
 from dotenv import load_dotenv
 from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
@@ -24,12 +24,16 @@ from telegram.ext import (
 from crawler import Day, Location, LocationDays, get_location_days
 from database import (
     delete_all_schedules_from_user,
+    delete_menu_item_indicator_preference,
     get_location_by_command,
     get_locations,
     get_meals,
     get_meals_by_location_name,
+    get_menu_item_indicators,
     get_schedules_for_user,
     get_schedules_matching_datetime,
+    get_shown_menu_item_indicators_for_user,
+    insert_menu_item_indicator_preference,
     upsert_schedule,
 )
 from model import Meal, Schedule
@@ -65,8 +69,9 @@ def format_user(user):
     return f'{user_id}{username}:"{name}"'
 
 
-def format_location_days(location_days):
+def format_location_days(location_days, visible_menu_item_indicators):
     days, location, update_datetime = location_days
+    visible_menu_item_indicators = set(visible_menu_item_indicators)
     used_indicators = set()
     strings = []
     strings.append(f"<b>RU {location.name}</b>")
@@ -74,7 +79,9 @@ def format_location_days(location_days):
         for day in days:
             for menu in day.menus:
                 for item in menu.items:
-                    used_indicators |= item.indicators
+                    used_indicators |= (
+                        item.indicators & visible_menu_item_indicators
+                    )
         strings.append(
             "\n\n".join(
                 f"<b>{day.date_raw}</b>\n"
@@ -85,6 +92,7 @@ def format_location_days(location_days):
                         + "".join(
                             indicator.emoji
                             for indicator in sorted(item.indicators)
+                            if indicator in visible_menu_item_indicators
                         )
                         for item in menu.items
                     )
@@ -150,6 +158,7 @@ def answer_start_command(update: Update, context: CallbackContext) -> None:
             """
             <b>Estes são meus comandos:</b>
                 • /agendar · Configura notificações de cardápio
+                • /indicadores · Configura visiblidade dos indicadores
         """
         )
         + "\n".join(
@@ -171,13 +180,89 @@ def answer_cardapio_command(update: Update, context: CallbackContext) -> None:
         command = command[: command.index("@")]
 
     location = get_location_by_command(command[len("cardapio_") :])
-    location_days = get_location_days(location)
+    menu_item_indicators = get_menu_item_indicators()
+    location_days = get_location_days(location, menu_item_indicators)
+    visible_menu_item_indicators = get_shown_menu_item_indicators_for_user(
+        update.effective_user.id
+    )
     update.message.reply_text(
-        format_location_days(location_days), parse_mode=PARSEMODE_HTML
+        format_location_days(location_days, visible_menu_item_indicators),
+        parse_mode=PARSEMODE_HTML,
     )
     logger.info(f"User {format_user(update.effective_user)} used /{command}")
 
 
+@dataclass
+class CustomizeIndicatorsCallbackData:
+    action: Literal["insert", "delete"]
+    emoji: str
+
+
+def answer_customize_indicators(user_id):
+    menu_item_indicators = get_menu_item_indicators()
+    visible_menu_item_indicators = set(
+        get_shown_menu_item_indicators_for_user(user_id)
+    )
+    buttons = []
+    for indicator in menu_item_indicators:
+        if indicator in visible_menu_item_indicators:
+            buttons.append(
+                InlineKeyboardButton(
+                    f"Remover {indicator.emoji}",
+                    callback_data=CustomizeIndicatorsCallbackData(
+                        "delete", indicator.emoji
+                    ),
+                )
+            )
+        else:
+            buttons.append(
+                InlineKeyboardButton(
+                    f"Adicionar {indicator.emoji}",
+                    callback_data=CustomizeIndicatorsCallbackData(
+                        "insert", indicator.emoji
+                    ),
+                )
+            )
+    buttons = [buttons[i : i + 3] for i in range(0, len(buttons), 3)]
+    buttons.append(
+        [InlineKeyboardButton("Pronto", callback_data=ReadyCallbackData())]
+    )
+
+    return (
+        "<b>Indicadores</b>\n\n"
+        + "\n".join(
+            f'  • {"✅" if indicator in visible_menu_item_indicators else "❌"}'
+            f" · {indicator.emoji} · {indicator.description}"
+            for indicator in menu_item_indicators
+        ),
+        InlineKeyboardMarkup(buttons),
+    )
+
+
+def answer_customize_indicators_command(
+    update: Update, context: CallbackContext
+) -> None:
+    body, keyboard = answer_customize_indicators(update.effective_user.id)
+    update.message.reply_text(
+        body, reply_markup=keyboard, parse_mode=PARSEMODE_HTML
+    )
+
+
+def answer_customize_indicators_callback(
+    update: Update, context: CallbackContext
+) -> None:
+    data = update.callback_query.data
+    user_id = update.effective_user.id
+    if data.action == "insert":
+        delete_menu_item_indicator_preference(data.emoji, user_id)
+    else:
+        insert_menu_item_indicator_preference(data.emoji, user_id, False)
+    body, keyboard = answer_customize_indicators(user_id)
+    update.callback_query.message.edit_text(
+        body, reply_markup=keyboard, parse_mode=PARSEMODE_HTML
+    )
+
+
 def answer_schedule(user_id):
     schedules = get_schedules_for_user(user_id)
     keyboard = [
@@ -386,8 +471,8 @@ def answer_schedule_before_opening_callback(
     week_days_step = data.meals_by_name[meal_step_name]
     buttons = []
     for meal in meals_step:
+        new_data = deepcopy(data)
         if meal in week_days_step:
-            new_data = deepcopy(data)
             new_data.meals_by_name[meal_step_name].remove(meal)
             buttons.append(
                 InlineKeyboardButton(
@@ -395,7 +480,6 @@ def answer_schedule_before_opening_callback(
                 )
             )
         else:
-            new_data = deepcopy(data)
             new_data.meals_by_name[meal_step_name].add(meal)
             buttons.append(
                 InlineKeyboardButton(
@@ -499,9 +583,12 @@ def send_scheduled(context: CallbackContext) -> None:
     )
     logging.info(f"Getting schedules matching {dt}")
     schedules = get_schedules_matching_datetime(dt)
+    menu_item_indicators = get_menu_item_indicators()
 
     for schedule in schedules:
-        days, location, update_datetime = get_location_days(schedule.location)
+        days, location, update_datetime = get_location_days(
+            schedule.location, menu_item_indicators
+        )
         location_days = LocationDays(
             days=[
                 Day(
@@ -517,9 +604,12 @@ def send_scheduled(context: CallbackContext) -> None:
             location=location,
             update_datetime=update_datetime,
         )
+        visible_menu_item_indicators = get_shown_menu_item_indicators_for_user(
+            schedule.user_id
+        )
         context.dispatcher.bot.send_message(
             schedule.user_id,
-            format_location_days(location_days),
+            format_location_days(location_days, visible_menu_item_indicators),
             parse_mode=PARSEMODE_HTML,
         )
         logger.info(
@@ -565,6 +655,15 @@ def main() -> None:
             answer_schedule_callback, pattern=ScheduleCallbackData
         )
     )
+    updater.dispatcher.add_handler(
+        CommandHandler("indicadores", answer_customize_indicators_command)
+    )
+    updater.dispatcher.add_handler(
+        CallbackQueryHandler(
+            answer_customize_indicators_callback,
+            pattern=CustomizeIndicatorsCallbackData,
+        )
+    )
     updater.dispatcher.add_handler(
         CallbackQueryHandler(answer_ready_callback, pattern=ReadyCallbackData)
     )
diff --git a/model.py b/model.py
index fe0219b58c4ad4a3bb48a84840fb2fce27a7131b..45d0b24ec4c6496503d407120539de724394d4c4 100644
--- a/model.py
+++ b/model.py
@@ -36,26 +36,12 @@ WorkingWeekDay = [
 ]
 
 
-class MenuItemIndicator(Enum):
-    VEGAN = (1, "🌱", "Indicado para veganos")
-    GLUTEN = (2, "🌾", "Não indicado para celíacos por conter glúten")
-    LACTOSE = (
-        3,
-        "🥛",
-        "Não indicado para intolerantes à lactose por conter lactose",
-    )
-    ANIMAL = (4, "🥩", "Contém produtos de origem animal")
-    EGG = (5, "🥚", "Contém ovo")
-    HONEY = (6, "🍯", "Contém mel")
-    ALERGIC = (7, "⚠️", "Contém produto(s) alergênico(s)")
-
-    def __new__(cls, ordering, emoji, description):
-        obj = object.__new__(cls)
-        obj._value_ = (emoji, description)
-        obj.ordering = ordering
-        obj.emoji = emoji
-        obj.description = description
-        return obj
+@dataclass(frozen=True)
+class MenuItemIndicator:
+    emoji: str
+    description: str
+    find_text: str
+    ordering: int
 
     def __lt__(self, other):
         if self.__class__ is other.__class__:
diff --git a/pyproject.toml b/pyproject.toml
index 1e75c2fbdb5a9d9880b5d8adda2aeed67e656e7e..d84cc51b8629f633aaf6b38791ef418e6f1d52f8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,3 +3,4 @@ line-length = 79
 
 [tool.isort]
 profile = "black"
+line_length = 79
diff --git a/seed.py b/seed.py
index 732445b2b7adfe19a3ae4d635626c7721064cc39..a2d16df982cdb920755e22f82ba8aceb3f40c281 100644
--- a/seed.py
+++ b/seed.py
@@ -128,3 +128,50 @@ def get_seed_meals():
             for week_day in WorkingWeekDay
         ]
     )
+
+
+def get_seed_menu_item_indicators():
+    return [
+        (
+            "🌱",
+            "Indicado para veganos",
+            "vegano",
+            1,
+        ),
+        (
+            "🌾",
+            "Não indicado para celíacos por conter glúten",
+            "gluten",
+            2,
+        ),
+        (
+            "🥛",
+            "Não indicado para intolerantes à lactose por conter lactose",
+            "leite",
+            3,
+        ),
+        (
+            "🥩",
+            "Contém produtos de origem animal",
+            "animal",
+            4,
+        ),
+        (
+            "🥚",
+            "Contém ovo",
+            "ovo",
+            5,
+        ),
+        (
+            "🍯",
+            "Contém mel",
+            "mel",
+            6,
+        ),
+        (
+            "⚠️",
+            "Contém produto(s) alergênico(s)",
+            "alergenicos",
+            7,
+        ),
+    ]