Users
Use the Users resource when your product has end-users and each user needs isolated data.
The key is user_id. Pass it on agents, runs, tasks, memories, and permissions. Without it, resources are account-level; with it, each end-user gets isolated agents, run history, memory, and permission policies.
Start with user_id
The same user_id on every call keeps one customer's world separate:
The TypeScript SDK wraps all of these: client.agents, client.runs, client.tasks, client.users, client.memories, and client.permissions.
List endpoints take the same filter, so you only fetch one tenant:
Usage and billing
Isolation is about data. For billing, any run carrying a user_id settles on your prepaid balance (the API meter), not on your platform plan. See Billing & Usage. You can still see and cap each end-user individually: GET /api/v2/usage/end-users rolls up each end-user's completed runs, cost, and tokens for the current billing period:
Cap every end-user account-wide, or throttle one specific end-user with a per-profile override:
Cap semantics, error codes, and per-day cost series
- Per-profile overrides win over the account-wide defaults.
run_limit=0blocks an end-user entirely;Noneclears an override back to the account default. - A capped end-user's next run returns
402withEND_USER_RUN_LIMIT_REACHEDorEND_USER_COST_LIMIT_REACHED; rate bursts return429 END_USER_RATE_LIMITED. Other end-users (and your own runs) are unaffected. - The rollup endpoint reports the same counters and the EFFECTIVE caps per row, so the numbers always reconcile.
- For cost attribution over time,
client.billing.usage_timeseries(user_id="cust_123")returns that end-user's daily token + USD buckets.
User profiles
Profiles are auto-created the first time you use a new user_id; manage them directly when you want names and emails attached:
Strict multi-tenant mode
The classic multi-tenancy bug is forgetting user_id on one call: the data silently lands in the account-level scope, invisible to your end-users. Strict mode rejects those requests instead, and it is on by default for new API accounts:
Building for just yourself? Turn it off and drop user_id everywhere:
Where strict mode is enforced, and older accounts
Enforced wherever a request scopes data: agent, task, run, skill, and custom-MCP-server creation (a run inheriting scope from its scoped agent passes without an explicit user_id), plus every memory operation. App connections and replies to pre-existing unscoped runs are exempt.
Accounts created before mid-2026 (and platform-product accounts) default to off; opt in with client.settings.update(require_end_user_id=True).
Best practices
- Use your own stable internal ID as
user_id, and pass it on every relevant request - Do not mix scoped and unscoped writes for the same product flow
- Keep permission policies and memories aligned to the same
user_id - Keep strict mode on so a forgotten
user_idfails loudly instead of writing to the account scope
Next: Runs · Human-in-the-Loop · API Reference
