Skip to main content
Read Identifiers & Scopes first. This page assumes you know what customer_id and user_id do.
If your account uses the default Client → Customer → User chain, nothing here changes how you integrate. This page matters when that shape does not describe your business.

What a level is

A scope is a position on a ladder. Your account is the top rung, and each rung below it narrows who a memory belongs to. The default ladder has three:
Every memory is filed at exactly one rung, and it carries that rung plus every rung above it. That stored list is what a read filters on.

Which direction a read travels

This is the rule worth reading twice, because it is easy to hold backwards. A request sees its own rung and every rung above it. It never sees a rung below, and never a neighbour. So on the default ladder: A memory filed at the user level is not visible to a request that identifies only the customer. One person’s private context does not surface for their colleague, and it does not surface for a customer-wide question.
A memory’s stored chain is the path down to it. That is the list of rungs the memory can be read from, not a list of places the memory is visible. A fact filed at the user rung carries client, customer, user, and it is still readable only by that user.

Ranking: closer material wins

Filtering decides what a request is allowed to read. Ranking decides what it sees first. Among the memories a request may read, the ones filed closer to the person asking rank above the ones filed further up. A person’s own preference outranks a fact that is true of their whole organization, when both match the question equally well. This is a ranking adjustment only: it never makes a memory readable that was not, and it never hides one that was.

A level’s name can change, its key cannot

Every level has two parts.
  • The label is what people read: “Customer”, “Practice”, “Region”. Change it whenever you like. Nothing stored depends on it.
  • The key is what stored memories resolve through: customer, user. It never changes, because every memory already filed under it would stop resolving.
For the same reason a level can never be deleted, only deprecated. A deprecated level stops being offered for new structure, and everything already filed under it stays readable.

Sending a scope path

Requests normally identify a scope with customer_id and user_id, and Synap maps those onto the default three rungs. That is what almost every integration does, and it needs no change. To address a level beyond those three, send an explicit scope map on a context fetch, naming each rung by its key:
Two rules apply, and both fail loudly rather than guessing:
  • Every rung must be named. A path that skips a level is refused, and the error names the level you left out. Synap never infers a missing id, because a wrong guess at or above the organization level would cross a tenant boundary.
  • The feature must be enabled for your instance. If it is not, sending a scope map is an error rather than being ignored. Ignoring it would widen the request to the whole organization when you asked to narrow it to one team.
The SDKs cannot send a scope map yet. The scope argument on an SDK fetch names which method you called (user, customer, client), not a path. Today an explicit path is only reachable by calling the HTTP API directly. gRPC cannot carry one either.

What you can reach today

Being precise about this matters more than making the feature sound finished. The honest summary: Synap’s scoping is correct and safe on the shape accounts already use. It does not yet let you drive a different shape from an SDK.

Adding a level

A level can be added above, below, or between existing ones. Adding one in the middle is a migration rather than a setting: every node beneath the insertion point is re-parented under a new node at the new level, in one transaction, and Synap creates one placeholder parent per existing group so nothing is left without one. Those placeholders are yours to rename. Reads are unaffected while this happens. Memories above the insertion point are never touched, and no memory changes the group it belongs to.
One thing lags. Existing memories do not immediately carry the new level as one of their ancestors, so a query asking for everything beneath the new level is incomplete until Synap finishes stamping them. Ordinary retrieval is not affected. Ask us to run the backfill after you add a level.