Skip to main content
Customers and Users are your entities, not Synap’s. You provide the customer_id and user_id strings, and Synap uses them to organize and isolate memories. You do not need to register these identifiers in advance — simply pass them during ingestion and retrieval.

What is a Customer?

A Customer represents a tenant or organization in your application. If you are building a B2B SaaS product, each of your client companies is a Customer. If you are building a consumer app, each household or account group could be a Customer. Customers are identified by a customer_id string that you provide. This string is opaque to Synap — it can be a UUID, a slug, a database ID, or any identifier that is unique within your application. Synap uses it to create a memory boundary at the CUSTOMER scope level in the scope chain. Examples of Customers:
  • "acme_corp" — Acme Corporation, one of your enterprise clients
  • "startup_xyz" — A startup using your platform
  • "household_9a3f" — A family unit in a consumer application
  • "team_engineering" — An internal team in a workplace tool

What Customer scope provides

All memories ingested with a given customer_id (but without a user_id) are stored at the Customer scope. This means:
  • Every user within that customer organization can access these memories
  • Users in other customer organizations cannot see them
  • These memories surface alongside user-specific memories during retrieval, with lower priority than user-scoped memories
Customer-scoped memories are ideal for shared organizational knowledge: company policies, team structure, project context, terminology, and preferences that apply to everyone in the organization.

What is a User?

A User represents an individual end-user of your application. Each person interacting with your AI agent is a User. Users are identified by a user_id string that you provide, following the same rules as customer_id — it is opaque to Synap and can be any unique identifier. Users map to the USER scope in the scope chain, which is the narrowest and most private scope level. Memories stored at the User scope are visible only when that specific user_id is provided in a retrieval query. Examples of Users:
  • "user_alice_chen" — An individual employee at Acme Corp
  • "u_8b2f4a91" — A UUID-based user identifier
  • "github|12345" — An OAuth-sourced user ID
  • "employee_0042" — An internal employee number

What User scope provides

Memories ingested with both a user_id and a customer_id are stored at the User scope:
  • Only that specific user can access these memories during retrieval
  • Other users in the same customer organization cannot see them
  • These memories have the highest retrieval priority in the scope chain

Entity hierarchy

Synap’s entity model forms a strict hierarchy. Understanding this hierarchy is essential for designing your memory scoping strategy.
CLIENT (your application)
  └── INSTANCE (a deployed Synap agent)
        └── CUSTOMER (a tenant/organization in your app)
              └── USER (an individual end-user)
Each level nests inside the one above it:
LevelWhat it representsWho creates itIdentifierScope level
ClientYour organization / applicationSynap (on signup)cli_<hex16>CLIENT
InstanceA deployed AI agentYou (via SDK/API/Dashboard)inst_<hex16>
CustomerA tenant in your applicationYou (implicitly, by passing customer_id)Any string you chooseCUSTOMER
UserAn individual end-userYou (implicitly, by passing user_id)Any string you chooseUSER
Clients and Instances are explicitly created and managed through the Synap API. Customers and Users are implicitly created — they come into existence the first time you pass their IDs during ingestion or retrieval. There is no separate registration step.

How customer_id and user_id drive scoping

The combination of customer_id and user_id you pass during ingestion determines where memories are stored. The combination you pass during retrieval determines which memories are returned.

Ingestion scoping rules

Parameters providedResulting scopeWhat gets stored
user_id + customer_idUSERPersonal memories for that individual user
customer_id onlyCUSTOMERShared memories for the organization
NeitherCLIENTApplication-wide memories visible to all

Retrieval scoping rules

Parameters providedScopes searchedPriority order
user_id + customer_idUSER + CUSTOMER + CLIENT + WORLDUser first, then Customer, then Client, then World
customer_id onlyCUSTOMER + CLIENT + WORLDCustomer first, then Client, then World
NeitherCLIENT + WORLDClient first, then World

Code examples

Ingesting with full user and customer context

The most common pattern — storing a conversation that belongs to a specific user within a specific customer organization:
from synap import Synap

sdk = Synap(api_key="your_api_key")

# Ingest a user's conversation -- stored at USER scope
await sdk.memories.create(
    document="""
    User: I prefer getting summaries before detailed explanations.
    Assistant: Got it! I'll lead with summaries going forward.
    User: Also, I'm working on the Q2 budget review this week.
    Assistant: Noted. I'll keep that in mind for context.
    """,
    document_type="ai-chat-conversation",
    user_id="user_alice",
    customer_id="acme_corp"
)

Ingesting customer-scoped knowledge

Shared organizational knowledge that all users in the customer should benefit from:
# Ingest company documentation -- stored at CUSTOMER scope
await sdk.memories.create(
    document="""
    Acme Corp Engineering Standards:
    - All services use Python 3.11+ and PostgreSQL
    - Code reviews require two approvals before merge
    - Deployments happen on Tuesdays and Thursdays
    - The on-call rotation follows the schedule in PagerDuty
    """,
    document_type="document",
    customer_id="acme_corp"
    # No user_id -- this is shared across all users at Acme
)

Ingesting client-scoped knowledge

Application-wide knowledge visible to everyone:
# Ingest product documentation -- stored at CLIENT scope
await sdk.memories.create(
    document="""
    Release Notes v3.2:
    - Added bulk CSV import for memory ingestion
    - Improved retrieval latency by 40%
    - New webhook support for pipeline completion events
    """,
    document_type="document"
    # No user_id or customer_id -- visible to all customers and users
)

Retrieving with scope chain

# Full scope chain retrieval for a specific user
context = await sdk.user.context.fetch(
    user_id="user_alice",
    customer_id="acme_corp",
    search_query=["budget review process"]
)

# context may include:
# - USER scope: "Alice is working on Q2 budget review" (highest priority)
# - CUSTOMER scope: "Acme Corp deployments happen Tues/Thurs" (if relevant)
# - CLIENT scope: "v3.2 added bulk CSV import" (if relevant)

# Customer-only retrieval (no user-specific memories)
context = await sdk.customer.context.fetch(
    customer_id="acme_corp",
    search_query=["engineering standards"]
)

When to use customer_id vs user_id

When ingesting AI chat conversations, always provide both identifiers. This ensures personal preferences and conversation history are scoped to the individual user, while the customer association enables scope chain retrieval that includes organizational context.
When ingesting company-wide documents (policies, handbooks, project plans), provide only customer_id. This makes the knowledge available to every user in that organization without duplicating it per user.
When ingesting your own product documentation, feature announcements, or domain knowledge that should be universally available, omit both identifiers. This stores at Client scope, visible to all customers and users.
In Synap’s scope model, a User always belongs to a Customer. While the system will accept a user_id without a customer_id, best practice is to always include the customer context to ensure proper scope chain behavior during retrieval.

Comparison table

AspectClientInstanceCustomerUser
What it isYour organizationA deployed AI agentA tenant in your appAn individual end-user
Who creates itSynap (on signup)You (SDK/API/Dashboard)Implicit (first use)Implicit (first use)
Identifier formatcli_<hex16>inst_<hex16>Any string you chooseAny string you choose
Scope levelCLIENTCUSTOMERUSER
Memory visibilityAll customers, all usersAll users in that customerOnly that user
Typical count1 per application1-10 per clientHundreds to thousandsThousands to millions
Example”Your SaaS company""Production support bot""Acme Corp""Alice Chen”

Next steps

Memory Scopes

Deep dive into the four-level scope chain and how retrieval priority works.

Clients & Instances

Understand the infrastructure hierarchy that Customers and Users operate within.

Memories & Context

Learn how memories are structured and delivered as context to your agent.

Multi-User Scoping Guide

Step-by-step guide to implementing multi-user, multi-tenant memory.