Operator Users
Taxi & Private Hire › Products › ACL › Operator Users
Generally available
Operator console users — the people who log in to the operator console to manage trips, customers, drivers, etc. Each User has a permission profile (determines what they can read/write), optional fleet and region scoping, email/password credentials, and optional passkey credentials. Authenticates via the USER auth method.
Example request
POST /client/{clientId}/user
{
"firstName": "<string>",
"lastName": "<string>",
"email": "<string>",
"userType": "HUMAN",
"password": "<string>",
"permissionProfile": {
"id": "<id>"
},
"defaultRegion": {
"id": "<id>"
},
"regions": [
{
"id": "<id>"
}
]
}
Example shape, derived from the User fields — indicative,
not the authoritative schema (that arrives with the API reference).
Endpoints
| Method | Path | |
|---|---|---|
POST | /client/{clientId}/user · primary | |
GET | /client/{clientId}/user/{userId} | |
POST | /client/{clientId}/user/{userId} |
Full request/response schemas and an interactive explorer will live in the API reference (coming soon).
Related
Fields
| Field | Type | Description |
|---|---|---|
firstName | string | Given name of the operator user. Surfaced on audit logs + the operator console header. |
lastName | string | Family name of the operator user. |
email | string | Login email — unique per tenant (UNIQ_IDENTIFIER_EMAIL). Acts as the username for the USER auth method. |
roles | array | Symfony security roles array (ROLE_ADMIN, ROLE_USER, etc.). Implicit ROLE_USER is added at runtime. Permission resolution still goes through PermissionProfile for fine-grained ACL. |
userType | UserType · HUMAN | AGENT | Whether this staff member is a HUMAN operator or an AI AGENT acting as staff. Both authenticate via the USER auth method and are bound by the same PermissionProfile; the distinction drives audit attribution and lets the agent surface be governed / revoked independently. |
password | string | Bcrypt hash of the user's password. writeOnly serialization — never read in responses. Set via setPassword() with raw input that the auth layer hashes. |
permissionProfile | PermissionProfile | PermissionProfile that defines what this user can read/write. The runtime permission check walks this profile, not the bare `roles` array. |
defaultRegion | Region | Default Region the user logs into. Drives the initial RegionFilter scope on login; user can switch regions if they have access to several. |
regions | Collection | Regions this user is permitted to operate in. Multi-select; gates the region picker + RegionFilter access. |
clientId | bigint | Tenant scope. Every tenant-aware entity carries this; `ClientFilter` enforces row-level isolation on read; the multi-tenancy routing layer (`/client/{clientId}`) sets it at create time. Surfaced only under `admin` / `tripLog` groups — never to end users. |
internalKey | string | Optional client-supplied external reference / idempotency key. When present, lets external systems correlate platform-side records back to their own source-of-truth ids. Not persisted to a column — populated by the request handler when the caller sets it. |
__objectType | string | Discriminator string (entity class short-name) emitted alongside the id in serialized output. Resolved at read time by `getObjectType()`; lets the FE dispatch entity-specific rendering without inspecting the URL. |
id | bigint | Snowflake-style primary key (unsigned BIGINT). Generated by `IdFactory` at create time; surfaced to the FE / API as a `G`-prefixed string and stripped back to plain bigint server-side before Doctrine lookup. |
createdDate | integer | Unix timestamp the row was first persisted. Set in the entity's PrePersist hook; never rewritten on subsequent updates. |
updatedDate | integer | Unix timestamp the row was last touched. Bumped on every commit that hits the Doctrine UoW for this entity; drives FE invalidation + the listing change cursor. |
passiveUpdatedDate | int | Read-through alias for `updatedDate` exposed under different serializer groups. Lets the FE distinguish "real edit" from "background touch" projections without changing the underlying column. |
listingUpdatedDate | int | Listing-projection timestamp surfaced only under the `listMode` group. Driven by `TripCache` and other listing-shape refreshers separately from `updatedDate` so a listing rebuild doesn't trigger detail-page invalidation. |