Skip to main content

Custom Categories

Mem0 automatically tags every memory, but the default labels (travel, sports, music, etc.) may not match the names your app uses. Custom categories let you replace that list so the tags line up with your own wording.
Use custom categories when…
  • You need Mem0 to tag memories with names your product team already uses.
  • You want clean reports or automations that rely on those tags.
  • You’re moving from the open-source version and want the same labels here.
You can set the list once for the whole project, or pass a different list on an individual add call.

Configure access

  • Ensure MEM0_API_KEY is set in your environment or pass it to the SDK constructor.
  • If you scope work to a specific organization/project, initialize the client with those identifiers.

How it works

  • Default list: Each project starts with 15 broad categories like travel, sports, and music.
  • Project override: When you call project.update(custom_categories=[...]), that list replaces the defaults for future memories.
  • Per-call override: When you pass custom_categories=[...] to client.add(...), that list is used for the memories extracted from that call.
  • Automatic tags: As new memories come in, Mem0 picks the closest matches from the active list and saves them in the categories field.

Which list wins

Mem0 resolves the category catalog for each add call in this order, and stops at the first one it finds:
  1. custom_categories passed on the add call
  2. custom_categories set on the project
  3. The built-in default catalog
A per-call list fully replaces the project list for that call. The two are not merged, so a memory added with a per-call list can only be tagged with categories from that list. Categories are applied at ingestion time. Changing the project list, or passing a new per-call list, does not re-tag memories that already exist.
Default catalog: personal_details, family, professional_details, sports, travel, food, music, health, technology, hobbies, fashion, entertainment, milestones, user_preferences, misc.

Configure it

1. Set custom categories at the project level

2. Confirm the active catalog

get echoes back the shape you set. update also accepts a plain list of names, such as ["billing", "support"], in which case get returns that same list of names. Descriptions are optional here, and the classifier uses them to disambiguate when it has them.
add is stricter than update. Every entry in a per-call custom_categories list must be an object mapping a name to a description. Passing bare names to add fails with 400 Expected a dictionary of items but got type "str".

3. Override categories on a single add call

Pass custom_categories directly to add when one call needs a different catalog than the project default. The memories created by that call are tagged from the list you pass, and the project list is left untouched.
The memory is tagged from health_categories alone. The project catalog is not consulted for this call, and it is not modified.

Per-user categories inside one project

The main reason to reach for a per-call list is to give different users, tenants, or entities their own vocabulary without splitting them across projects. Keep one project, and pass the list that fits the entity you are writing for.

See it in action

Add a memory (uses the project catalog automatically)

Retrieve memories and inspect categories

get_all returns a paginated object. The memories are under results, and each one carries its own categories list.
Extraction is model driven, so the exact wording and the number of memories vary between runs. The categories are drawn from the active list.
Sample memory payload
Categorization runs asynchronously, a moment after the memory itself is written. A memory fetched immediately after add may not show up in get_all yet, or can come back with categories: null and pick up its tags a moment later. Poll until categories is populated rather than reading once.
Need ad-hoc labels for a single call? Pass custom_categories on that add call. Use metadata instead when the label is a fixed value you already know, rather than something the classifier should infer.

Default categories (fallback)

If you do nothing, memories are tagged with the built-in set below.
You can verify the defaults are active by checking:
A project that has never set a list returns null. One you have reset with project.update(custom_categories=[]) returns []. Both mean the default catalog is active.

Verify the feature is working

  • client.project.get(["custom_categories"]) returns the category list you set.
  • client.get_all(filters={"user_id": ...}) shows populated categories lists on new memories.
  • The Mem0 dashboard (Project → Memories) displays the custom labels in the Category column.

Best practices

  • Keep category descriptions concise but specific; the classifier uses them to disambiguate.
  • Review memories with empty categories to see where you might extend or rename your list.
  • Set the catalog your app uses most often at the project level, and reserve per-call lists for the calls that genuinely need a different vocabulary.
  • If a per-call list should also keep the project categories, include them in the list you pass. Passing a list replaces, it does not extend.

Advanced Memory Operations

Explore other ingestion tunables like custom prompts and selective writes.

Travel Assistant Cookbook

See custom tagging drive personalization in a full agent workflow.