---
title: "Add a user to a space"
method: POST
path: "/v2/spaces/{space_id}/users"
tags: ["Spaces"]
---

# Add a user to a space

`POST /v2/spaces/{space_id}/users`

Add a single existing account user to a space with a specified role.

**Payload Requirements**
- `user_id` is required and must be a valid user identifier (base64).
- `role` is required and must be a role assignment object with a `type` discriminator:
  - `{ "type": "PREDEFINED", "name": "ADMIN" }` — one of the predefined roles: `ADMIN`, `MEMBER`, `READ_ONLY`, `ANNOTATOR`.
  - `{ "type": "CUSTOM", "id": "<role_id>" }` — a custom RBAC role, using its unique identifier.
- If the user is already a member, their role is updated to the specified value (upsert).
- The user must already be a member of the space's parent organization; auto-enrollment is not performed (400 if not a member).

**Role constraints**
- Users with an `annotator` account role can only be assigned the `annotator` predefined space role.
- Users with a non-annotator account role cannot be assigned the `annotator` predefined space role.

**Authorization**
Requires space admin role when using a `PREDEFINED` role, or `ROLE_BINDING_CREATE`
permission (RBAC) when using a `CUSTOM` role.

<Note>This endpoint is in beta, read more [here](https://arize.com/docs/ax/rest-reference#api-version-stages).</Note>

## Path parameters

- `space_id` string, required — A universally unique identifier (base64-encoded opaque string).

## Request body

- AddSpaceUserRequest
  - `user_id` string, required — A universally unique identifier (base64-encoded opaque string).
  - `role` union, required — Strict request form of SpaceRoleAssignment. Used in write request bodies. - `PREDEFINED`: `{ "type": "PREDEFINED", "name": "ADMIN" | "MEMBER" | "READ_ONLY" | "ANNOTATOR" }` - `CUSTOM`: `{ "type": "CUSTOM", "id": "<encoded-role-id>" }`
    - PredefinedRoleAssignmentRequest — A predefined space role assignment in a write request (strict form of PredefinedRoleAssignment).
      - `type` 'PREDEFINED' | 'CUSTOM', required
      - `name` 'ADMIN' | 'MEMBER' | 'READ_ONLY' | 'ANNOTATOR', required — Space-level role for the user. - `ADMIN`: Full access to the space and its resources. - `MEMBER`: Standard access to the space. - `READ_ONLY`: Read-only access to the space. - `ANNOTATOR`: Limited access for annotation tasks only.
    - CustomRoleAssignmentRequest — A custom RBAC role assignment in a write request (strict form of CustomRoleAssignment).
      - `type` 'PREDEFINED' | 'CUSTOM', required
      - `id` string, required — A universally unique identifier (base64-encoded opaque string).

## Response `200`

User successfully added to the space

- SpaceMembership — A space membership record.
  - `id` string, required — A universally unique identifier (base64-encoded opaque string).
  - `user_id` string, required — A universally unique identifier (base64-encoded opaque string).
  - `space_id` string, required — A universally unique identifier (base64-encoded opaque string).
  - `role` union, required — Specifies which role to assign within a space. Discriminated by `type`: - `PREDEFINED`: a built-in platform role — `{ "type": "PREDEFINED", "name": "ADMIN" | "MEMBER" | "READ_ONLY" | "ANNOTATOR" }` - `CUSTOM`: a custom RBAC role identified by its ID — `{ "type": "CUSTOM", "id": "<encoded-role-id>" }` Used wherever a space-level role assignment is required (memberships, service key bindings, etc.).
    - PredefinedRoleAssignment — A predefined space role assignment.
      - `type` 'PREDEFINED' | 'CUSTOM', required
      - `name` 'ADMIN' | 'MEMBER' | 'READ_ONLY' | 'ANNOTATOR', required — Space-level role for the user. - `ADMIN`: Full access to the space and its resources. - `MEMBER`: Standard access to the space. - `READ_ONLY`: Read-only access to the space. - `ANNOTATOR`: Limited access for annotation tasks only.
    - CustomRoleAssignment — A custom RBAC role assignment.
      - `type` 'PREDEFINED' | 'CUSTOM', required
      - `id` string, required — A universally unique identifier (base64-encoded opaque string).
      - `name` string — Human-readable name of the custom role. Returned in responses only; ignored on input.

## Other responses

- `400` — Invalid request
- `401` — Authentication is required
- `403` — Insufficient permissions to access this resource
- `404` — Not found
- `422` — Unprocessable entity
- `429` — Rate limit exceeded

---

[API](https://skmtc.net/arize-ai/apis/arize-rest-api.md) · [All operations](https://skmtc.net/arize-ai/apis/arize-rest-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/arize-ai/arize-rest-api/versions/2ce448f1de13/schema)
