# Available API Scopes in the Omi Backend: A Complete Guide

> Explore the eight granular API scopes available in the Omi backend including conversations, memories, action items, and goals. Understand read and write permissions.

- Repository: [omi/omi](https://github.com/basedhardware/omi)
- Tags: api-reference
- Published: 2026-02-26

---

**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`](https://github.com/basedhardware/omi/blob/main/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`](https://github.com/basedhardware/omi/blob/main/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:

```python
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.

```python
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`:

```python
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`](https://github.com/basedhardware/omi/blob/main/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`](https://github.com/basedhardware/omi/blob/main/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`](https://github.com/basedhardware/omi/blob/main/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`](https://github.com/basedhardware/omi/blob/main/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`](https://github.com/basedhardware/omi/blob/main/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`](https://github.com/basedhardware/omi/blob/main/backend/utils/scopes.py) and utilized in [`backend/dependencies.py`](https://github.com/basedhardware/omi/blob/main/backend/dependencies.py). Endpoint logic checks the authenticated token's scope list against required permissions (such as `Scopes.MEMORIES_WRITE`) before executing protected operations.