Skip to content

Create a tenant operator — owner or member

POST
/admin/operators
curl --request POST \
--url http://localhost:3000/admin/operators \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "email": "hello@example.com", "name": "example", "role": "owner", "tenant_id": "example" }'

Creates the account and issues a one-time invite; the operator sets their own password via POST /operator/invite/accept. Who asked for it is logged.

Platform staff operators CANNOT be created here. There is no network path to a staff account: staff is created at a shell on the host with pnpm operator:seed, writing to the platform database directly. See docs/superpowers/specs/2026-08-12-staff-seeding-design.md.

Media typeapplication/json
object
email
required
string format: email
name
required
string
>= 1 characters
role
required
string
Allowed values: owner member
tenant_id
required

The tenant this operator belongs to. Required; it must exist.

string
>= 1 characters

Created. invite_token is returned once, here — only its sha256 is stored.

Media typeapplication/json
object
operator
required
object
id
required
string
email
required
string format: email
name
required
string
role
required
string
Allowed values: owner member
tenant_id
required
string
status
required
string
Allowed values: active disabled
invite_token
required

One-time invite token. Redeem it with POST /operator/invite/accept.

string
invite_expires_at
required
string format: date-time
Example
{
"operator": {
"role": "owner",
"status": "active"
}
}

Malformed body (bad email, empty name, missing or empty tenant_id), a role other than owner or member — staff is rejected here and seeded at a shell instead — or a tenant_id that does not exist.

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: VALIDATION_FAILED UNAUTHENTICATED FORBIDDEN NOT_FOUND CONFLICT RATE_LIMITED INTERNAL
message
required
string
requestId
required
string
fields

Present only for VALIDATION_FAILED.

Array<object>
object
path
string
message
string
Example
{
"error": {
"code": "VALIDATION_FAILED"
}
}

Authenticated but not permitted.

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: VALIDATION_FAILED UNAUTHENTICATED FORBIDDEN NOT_FOUND CONFLICT RATE_LIMITED INTERNAL
message
required
string
requestId
required
string
fields

Present only for VALIDATION_FAILED.

Array<object>
object
path
string
message
string
Example
{
"error": {
"code": "VALIDATION_FAILED"
}
}

An operator with this email already exists.

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: VALIDATION_FAILED UNAUTHENTICATED FORBIDDEN NOT_FOUND CONFLICT RATE_LIMITED INTERNAL
message
required
string
requestId
required
string
fields

Present only for VALIDATION_FAILED.

Array<object>
object
path
string
message
string
Example
{
"error": {
"code": "VALIDATION_FAILED"
}
}