Customers
A customer is Parlant's special term for anyone who interacts with an agent— whether it's a real person, a bot, or even a human operator.
While agents can operate without knowing who they're talking to ("guest" customers), registering customers lets you personalize interactions based on identity, preferences, and segment.
import parlant.sdk as p
async with p.Server() as server:
customer = await server.create_customer(name="Alice")
Custom IDs
By default, Parlant auto-generates customer IDs. To map directly to your existing user identifiers, pass a custom ID:
customer = await server.create_customer(
id="usr_12345", # Your external system's user ID
name="Alice",
)
This is especially useful when your tools need to look up customer data in external services (CRM, billing, etc.) using the same ID.
Customer Groups
Use tags to segment customers into groups and control group-specific behavior:
vip_tag = await server.create_tag(name="VIP")
customer = await server.create_customer(name="Alice", tags=[vip_tag.id])
Group-Specific Guidelines
To activate guidelines only for customers in a specific group, create an observation with a custom matcher that checks the customer's tags, then make your guidelines depend on it:
# 1. Define a custom code-based matcher that checks for the VIP tag
async def is_vip(
ctx: p.GuidelineMatchingContext,
guideline: p.Guideline
) -> p.GuidelineMatch:
matched = vip_tag.id in p.Customer.current.tags
return p.GuidelineMatch(
id=guideline.id,
matched=matched,
rationale="Customer has VIP tag" if matched else "Customer does not have VIP tag",
)
# 2. Create an observation using that matcher
vip_observation = await agent.create_observation(matcher=is_vip)
# 3. Create guidelines that only activate for VIP customers
vip_guideline = await agent.create_guideline(
condition="The customer asks about pricing",
action="Offer the exclusive VIP discount of 20%",
dependencies=[vip_observation],
)
The matcher letes you bypass the default LLM-based matching with deterministic logic. The dependencies parameter ensures the guideline may only ever activate when the observation also matches, so non-VIP customers will never see VIP-specific behavior.
To learn more about personalization possibilities for specific customers and groups, check out the variables section.
Metadata
Attach custom metadata to customers for use in personalization, tool calls, or custom matchers:
customer = await server.create_customer(name="Alice", metadata={
"location": "USA",
"plan": "enterprise",
})
Here's an example of how you'd access that metadata from a tool:
@p.tool
async def get_customer_location(context: p.ToolContext) -> p.ToolResult:
customer = p.Customer.current
return p.ToolResult(customer.metadata.get("location", "Unknown location"))
Updating Customer Data
You can update a customer's name, metadata, and tags at any time:
from parlant.client import ParlantClient
client = ParlantClient("http://localhost:8800")
client.customers.update(
customer_id=CUSTOMER_ID,
name="Alice Smith",
metadata={
"set": {
"location": "Canada",
},
"remove": ["plan"],
},
tags=[NEW_TAG_ID]
)
Authentication and Mid-Session Identity
Parlant is a backend service—authentication and authorization live in your application layer (OAuth, JWT, etc.). Once you've identified a customer, pass their ID when creating a session to enable personalized interactions.
A common pattern is starting a session in guest mode and associating a customer mid-conversation after they authenticate:
- Python
- TypeScript
from parlant.client import ParlantClient
client = ParlantClient(PARLANT_SERVER_URL)
# User authenticates mid-session
client.sessions.update(
session_id=SESSION_ID,
customer_id="authenticated_user_123"
)
# From now on, the agent can provide a personalized experience
import { ParlantClient } from "parlant-client";
const client = new ParlantClient({ environment: PARLANT_SERVER_URL });
// User authenticates mid-session
await client.sessions.update(SESSION_ID, {
customerId: "authenticated_user_123"
});
// From now on, the agent can provide a personalized experience
Configuring Customer Storage
In the default configuration, during development, Parlant does not persist customers; they're stored in memory and lost when the server restarts.
You can easily configure persistent storage. For local development, the quickest setup is local file storage. For production, Parlant comes with native MongoDB support for its scalability and performance.
If you already have customer data in your own database, implement the p.CustomerStore interface to load customers directly from there. In this way, there's no duplication needed with your existing data.
Local Storage
Saves customers under $PARLANT_HOME/customers.json. Zero setup required.
import asyncio
import parlant.sdk as p
async def main():
async with p.Server(customer_store="local") as server:
# ...
asyncio.run(main())
MongoDB
Specify the connection string to your MongoDB instance:
import asyncio
import parlant.sdk as p
async def main():
async with p.Server(customer_store="mongodb://path.to.your.host:27017") as server:
# ...
asyncio.run(main())
pip install "parlant[mongo]"