Available API Scopes in the Omi Backend: A Complete Guide

The Omi backend defines eight granular API scopes—conversations:read, conversations:write, memories:read, memories:write, action_items:read, action_items:write, goals:read, and goals:write—in backend/utils/scopes.py, with tokens lacking explicit scopes defaulting to read-only access.

The basedhardware/omi repository implements a fine-grained authorization system to protect API resources. Understanding the available API scopes is essential for developers integrating with the Omi backend, as these permissions control access to conversations, memories, action items, and goals.

Complete List of API Scopes in Omi

The Omi backend organizes API scopes into four functional resource categories. Each category supports both read and write operations:

  • Conversations: conversations:read, conversations:write
  • Memories: memories:read, memories:write
  • Action Items: action_items:read, action_items:write
  • Goals: goals:read, goals:write

These eight scopes represent the complete permission set available for API access in the Omi system.

How API Scopes Are Defined in the Source Code

All scope definitions reside in backend/utils/scopes.py. The implementation uses a Scopes class to declare scope constants and provides validation utilities.

The scope constants follow a naming convention mapping to the string values:

from backend.utils.scopes import Scopes

# Accessing scope constants

print(Scopes.CONVERSATIONS_READ)    # "conversations:read"

print(Scopes.MEMORIES_WRITE)        # "memories:write"

print(Scopes.ACTION_ITEMS_READ)     # "action_items:read"

print(Scopes.GOALS_WRITE)           # "goals:write"

The file maintains two critical collections:

  1. AVAILABLE_SCOPES: A list containing all eight valid scope strings for validation purposes
  2. READ_ONLY_SCOPES: A subset containing only the four read scopes (conversations:read, memories:read, action_items:read, goals:read)

Validating and Checking API Scopes

The Omi backend provides two primary functions for scope enforcement: has_scope() for permission checking and validate_scopes() for input validation.

Checking Permissions with has_scope()

The has_scope() function determines whether a token's scope list includes a required permission. It handles the default read-only behavior when scopes are None or empty.

from backend.utils.scopes import has_scope, Scopes

# Token with explicit write permission

user_scopes = ["conversations:write", "memories:read"]
if has_scope(user_scopes, Scopes.CONVERSATIONS_WRITE):
    print("User can write conversations")

# Token without explicit scopes defaults to read-only

empty_scopes = None
assert has_scope(empty_scopes, Scopes.MEMORIES_READ) is True   # Granted

assert has_scope(empty_scopes, Scopes.MEMORIES_WRITE) is False # Denied

Validating Scope Requests

When creating API keys or OAuth tokens, use validate_scopes() to ensure requested permissions exist in AVAILABLE_SCOPES:

from backend.utils.scopes import validate_scopes

requested = ["conversations:read", "memories:write", "invalid:scope"]
is_valid = validate_scopes(requested)

# Returns False because "invalid:scope" is not in AVAILABLE_SCOPES

Default Read-Only Behavior

A critical security feature in the Omi backend is the read-only default. When a token lacks an explicit scopes field or contains an empty list, the system automatically grants only the permissions defined in READ_ONLY_SCOPES.

This behavior is implemented in the has_scope() function logic found in backend/utils/scopes.py. The four default read scopes are:

  • conversations:read
  • memories:read
  • action_items:read
  • goals:read

Any attempt to perform write operations with a token lacking explicit write scopes will fail permission checks, protecting data integrity while allowing basic read access for unscoped tokens.

Summary

  • The Omi backend defines eight API scopes in backend/utils/scopes.py, organized into read/write pairs for conversations, memories, action items, and goals.
  • Scope constants are accessed via the Scopes class (e.g., Scopes.MEMORIES_WRITE), with all valid values collected in AVAILABLE_SCOPES.
  • The has_scope() function checks token permissions and implements default read-only access when no scopes are explicitly assigned.
  • Use validate_scopes() to verify requested permissions against the allowed set when generating API keys or OAuth tokens.

Frequently Asked Questions

What are the available API scopes in the Omi backend?

The Omi backend provides eight granular API scopes defined in backend/utils/scopes.py: conversations:read, conversations:write, memories:read, memories:write, action_items:read, action_items:write, goals:read, and goals:write. These cover read and write access to four core resource types.

How does the Omi backend handle tokens without explicit scopes?

When a token lacks explicit scopes, the Omi backend defaults to read-only access through the has_scope() function in backend/utils/scopes.py. The system automatically grants the four read scopes (conversations:read, memories:read, action_items:read, goals:read) while denying any write operations.

How do I validate API scopes when creating a new API key?

Use the validate_scopes() function imported from backend/utils/scopes.py to check requested permissions against the AVAILABLE_SCOPES list. This function returns True only if all requested scope strings exist in the allowed set, preventing invalid or typo-ridden permissions from being assigned to tokens.

Where are API scopes enforced in the Omi backend?

API scopes are enforced in route handlers using the has_scope() helper, typically imported from backend/utils/scopes.py and utilized in backend/dependencies.py. Endpoint logic checks the authenticated token's scope list against required permissions (such as Scopes.MEMORIES_WRITE) before executing protected operations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →