Skip to main content
An agent keeps one JSON record per end user. These routes read and write that record for the caller or for a named end user, list every record on an agent, and resolve an email address or phone number to an end user. They are the REST twin of the User runtime object. Verified against lua-cli 3.33.0.

Base URL and authentication

Reads need knowledge:read and writes knowledge:write on the agent; the host, the bearer header, and the error envelope are on the REST API overview. The two profile lookups are authorized by the handler as the key’s owner, which a scoped key cannot stand in for: call them with a user session or a legacy key. Records are not partitioned by environment; sandbox and production share them.

The record

A record is { userId, agentId, data, createdAt, updatedAt }, with data the JSON bag your tools wrote and timestamps as Unix time in milliseconds. Reads that find the end user’s Lua profile add _luaProfile, a read-only object the platform maintains; it is never part of data. The routes under /developer/user/data/... unwrap the record and answer data itself with userId added, so a field of yours named userId is overwritten in that answer. Writes merge at the top level: PUT shallow-merges the body’s keys into data (incoming wins, null is stored as a value, nothing is deleted) and creates the record when it is missing; PATCH sets and unsets named top-level keys atomically and needs an existing record.

Endpoints

GET /developer/user/data/agent/:agentId

Returns the caller’s own record on the agent, unwrapped.
string
required
The agent.
Response 200 with data’s fields, plus userId and, when available, _luaProfile. A missing record answers { "userId" } alone; nothing is created by a read. Equivalent: User.get() inside a tool.

GET /developer/user/data/agent/:agentId/user/:userId

Returns a named end user’s record on the agent, unwrapped, in the same shape.
string
required
The agent.
string
required
The end user.
Equivalent: User.get('<userId>').

PUT /developer/user/data/agent/:agentId

Merges the body into the caller’s record, creating it when missing.
string
required
The agent.
object
required
Any JSON object. Top-level keys are shallow-merged into data; nested objects are replaced whole.
Response 200 with the merged data plus userId. Errors Equivalent: user.update({ plan: 'pro' }).

PUT /developer/user/data/agent/:agentId/user/:userId

Merges the body into a named end user’s record, with the same body, response, and errors.

PATCH /developer/user/data/agent/:agentId

Sets and unsets top-level keys of the caller’s record in one atomic write.
string
required
The agent.
object
Keys to write; null is stored as a value.
string[]
Keys to remove.
Response 200 with the resulting data plus userId. Errors Equivalent: user.patch({ set: { tier: 'gold' }, unset: ['trialEndsAt'] }).

PATCH /developer/user/data/agent/:agentId/user/:userId

Same mutation on a named end user’s record. PATCH /developer/agents/:agentId/user-data/:userId is an alias with identical behavior.

DELETE /developer/user/data/agent/:agentId

Deletes the caller’s record on the agent.
string
required
The agent.
Response 200 with an empty body when a record was deleted, or with { "message": "Agent data deleted successfully" } when no record existed; both are success. Equivalent: user.clear().

DELETE /developer/user/data/agent/:agentId/user/:userId

Deletes a named end user’s record. DELETE /developer/agents/:agentId/user-data/:userId is an alias.

GET /developer/agents/:agentId/user-data

Lists the agent’s records, most recently updated first, with the profile of each end user when known.
string
required
The agent.
integer
default:"1"
Page number from 1.
integer
default:"20"
From 1 to 100.
Matches end-user ids and profile fields. When the profile search hits its cap the answer carries searchTruncated: true.
Response 200 with { "data": [...], "pagination": { ... }, "searchTruncated"? }; each item is a full record with _luaProfile when known, and pagination carries currentPage, totalPages, totalCount, limit, hasNextPage, and hasPrevPage. Errors

GET /developer/agents/:agentId/user-data/capabilities

Tells a client whether the caller may write user data on this agent, so a UI can hide its editor. Response 200 with { "canWrite": true | false }.

GET /developer/agents/:agentId/user-data/:userId

Returns one record wrapped, { userId, agentId, data, createdAt, updatedAt, _luaProfile? }. Errors

GET /developer/user/profile/email/:email

Resolves an email address to an end user who has talked to one of your agents.
string
required
The address, URL-encoded; matching is case-insensitive.
string
Limit the lookup to one agent you can access.
Response 200 with the end user’s profile, including id. Errors Equivalent: User.get({ email: '[email protected]' }).

GET /developer/user/profile/phone/:phone

Resolves a phone number the same way. A leading + is optional. Equivalent: User.get({ phone: '+15551234567' }).

See also

  • User — the same record from agent code
  • Identify users — how an end user gets an id on each channel
  • Custom data — agent-wide collections instead of per-user records
  • REST API overview — authentication, scopes, and the error envelope