Skip to content

Add a user to an organization

POST
/organizations/{oid}/user/{uid}
curl --request POST \
--url https://apisandbox.puurk.com/organizations/example/user/example \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "status": "active", "start_date": "2026-04-15T12:00:00Z", "termination_date": "2026-04-15T12:00:00Z", "commission_basis": "profit", "commission_fixed": 1, "commission_rate": 1, "commission_trigger": "sale", "role": "owner" }'

Add or set a user’s membership and role in an organization. This writes the organization’s roles map as well as the user record, so it is always a role modification. Setting a role requires one of: an organization role of owner or agencyadmin in this organization; a superadmin claim; or a service token holding the admin scope action on organizations (globally or for this organization). admin is a scope action, not an organization role, and is rejected as a role value with 400.

oid
required
string

Organization ID

uid
required
string

User ID

Request body

Media typeapplication/json

Body for POST /organizations/{oid}/user/{uid} and PATCH /organizations/{oid}/user/{uid}. Every field is optional. On POST, role defaults to read; on PATCH, omitting role leaves it unchanged.

object
status

Membership status.

string
nullable
Allowed values: active terminated
start_date

When the person started with this organization. ISO 8601, or null to clear.

string format: date-time
nullable
termination_date

When the person left. ISO 8601, or null to clear.

string format: date-time
nullable
commission_basis
string
nullable
Allowed values: profit retail
commission_fixed

Fixed commission amount in cents

integer
nullable
commission_rate

Commission rate

number
nullable
commission_trigger
string
nullable
Allowed values: sale service
role

The role to grant. Setting a role requires one of: an organization role of owner or agencyadmin in this organization; a superadmin claim; or a service token holding the admin scope action on organizations (globally or for this organization). admin is a scope action, not an organization role, and is rejected as a role value with 400.

string
Allowed values: owner manager read write provider accountant officeadmin agencyadmin agencyuser none

User added. The body is the organization user record plus the resolved role.

Media typeapplication/json

An organization user record with its role from the organization’s roles map. role is null for an orphaned record — one that exists in the users subcollection with no entry in roles.

object
id

Organization user document ID

string
uid

User ID

string
nullable
oid

Organization ID

string
nullable
status
string
nullable
Allowed values: active terminated
start_date
string format: date-time
nullable
termination_date
string format: date-time
nullable
commission_basis
string
nullable
Allowed values: profit retail
commission_fixed

Fixed commission amount in cents

integer
nullable
commission_rate

Commission rate

number
nullable
commission_trigger
string
nullable
Allowed values: sale service
puurk_trained_at
string format: date-time
nullable
role
string
Allowed values: owner manager read write provider accountant officeadmin agencyadmin agencyuser none
Example
{
"status": "active",
"commission_basis": "profit",
"commission_trigger": "sale",
"role": "owner"
}

bad_request — invalid body or date field, or role is not an OrganizationRole (Invalid role. Must be one of: owner, manager, read, write, provider, accountant, officeadmin, agencyadmin, agencyuser, none). admin is rejected here: it is a scope action, not a role.

Media typeapplication/json

The standard error body. error is a stable, machine-readable code — branch on it rather than on message, which is for humans and may change.

object
error

Machine-readable error code.

string
message

Human-readable detail.

string
Example
{
"error": "merchant_account_missing",
"message": "The organization has no merchant account. Complete Stripe Connect onboarding for this organization before generating pricing."
}

Unauthorized

forbidden — the caller may not set this user’s role. Either the caller is the target user, or the caller holds none of: an organization role of owner or agencyadmin, a superadmin claim, or a service token with the admin scope action on organizations. Nothing is created.

Media typeapplication/json

The standard error body. error is a stable, machine-readable code — branch on it rather than on message, which is for humans and may change.

object
error

Machine-readable error code.

string
message

Human-readable detail.

string
Example
{
"error": "merchant_account_missing",
"message": "The organization has no merchant account. Complete Stripe Connect onboarding for this organization before generating pricing."
}

not_found — the organization does not exist.

Media typeapplication/json

The standard error body. error is a stable, machine-readable code — branch on it rather than on message, which is for humans and may change.

object
error

Machine-readable error code.

string
message

Human-readable detail.

string
Example
{
"error": "merchant_account_missing",
"message": "The organization has no merchant account. Complete Stripe Connect onboarding for this organization before generating pricing."
}

conflict — this would remove the organization’s last owner.

Media typeapplication/json

The standard error body. error is a stable, machine-readable code — branch on it rather than on message, which is for humans and may change.

object
error

Machine-readable error code.

string
message

Human-readable detail.

string
Example
{
"error": "merchant_account_missing",
"message": "The organization has no merchant account. Complete Stripe Connect onboarding for this organization before generating pricing."
}