> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myme.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Spaces

> Spaces as the data boundary, credentials as space scope

A space is the canonical data boundary. One space per isolated data partition. A user typically has one space — or several by choice (personal vs. work vs. a side project).

<Info>
  **"Space" and `tenant`.** "Space" is the user-facing word for this boundary. The API and wire shapes call the same thing a `tenant` — the `tenant_id` field, the `tenant_admin` role, the `/tenants` endpoints. One concept, two names: "space" in product language, `tenant` in the technical surface.
</Info>

## Spaces are first-class

* **User-owned.** A space belongs to one user.
* **Per-credential.** An app authenticates with a credential scoped to a single space. The credential resolves the space; URLs don't carry `tenant_id`.
* **One session = one space.** An app session sees the space the credential belongs to and behaves as if that's the world.

Apps that support space switching (management consoles, user-facing apps with account switching) swap credentials at the session boundary — they don't carry `tenant_id` in requests.

## No filter-by-workspace convention

Marfa does not use the "every row has a `workspace_id`, filter by it" pattern common in other multi-tenant systems.

Space isolation happens **at the credential layer**: the server resolves the space from the bearer token; all queries and writes are implicitly scoped.

This has two consequences worth knowing:

1. **Apps rarely see `tenant_id`.** It's present in the JSON, but apps shouldn't branch on it. Trust the credential to have scoped correctly.
2. **Item IDs are globally unique.** UUIDv7 across the whole system, not per-space. An item id from one space is never a valid id in another.

## Cross-space access

A user can grant another principal (another user, or an app acting for another user) access to a specific scope within their space:

* A specific item.
* Items matching a tag.
* A group item and its members.
* An extension namespace.

The sharing user's space remains the data home. The sharee sees only the granted scope. There are no cross-space edges — if a relationship needs to exist across spaces, it's represented by item duplication with appropriate provenance (`derived-from` edges, new space-scoped items), not by cross-space references.

## Deployment-mode implications

* **Server-synced mode.** The full space model applies. Credentials are stamped with their space server-side.
* **Local-only mode.** A single trivial space (the device). No space switching.
* **Third-party-synced mode.** A space typically maps to the third-party account — one iCloud account is one space.

Same SDK surface across all three. An app that works against one deployment mode works against the others; it just sees different space boundaries.

## Admin vs per-space

A few operations are admin-scoped and don't fit the per-space model:

* Creating spaces.
* Purging items (hard delete).
* Querying cross-space metrics.
* Managing the global type registry.

Admin credentials bypass space scoping for these operations. Non-admin credentials don't see cross-space data at all.
