---
title: "Create a user"
method: POST
path: "/api/v1/users"
tags: ["users"]
---

# Create a user

`POST /api/v1/users`

## Request

- Base URL: `https://app.accessowl.io`
- URL: `https://app.accessowl.io/api/v1/users`
- Auth: HTTP bearer

Creates a new user with the given identity and org info (department/team/job_title/location/employment_type + manager). Does not onboard — call POST /users/:user_id/onboard to onboard. Fails if a user with the email already exists.

## Headers

- `Idempotency-Key` string

## Request body

- CreateUser: Request body for creating a new user. The org-info fields are set on the new user. Does not onboard — call POST /users/{user_id}/onboard afterwards, or create and onboard in one step with POST /users/onboard.
  - `departments` string[]: Departments the user belongs to
  - `email` string, email, required: Email address
  - `employment_type` 'full_time' | 'part_time' | 'contract' | 'freelance' | 'internship' | 'apprenticeship' | 'working_student' | 'training', nullable: Employment type
  - `first_name` string, required: First name
  - `job_title` string, nullable: Job title
  - `last_name` string, required: Last name
  - `location_city` string, nullable: City location
  - `manager_user_id` string, uuid, nullable: Manager (user)
  - `teams` string[]: Teams the user belongs to

## Response `201`

User created

- User: A user in the organization
  - `deactivated_at` string, date-time, nullable: Deactivation timestamp
  - `departments` string[]: Departments the user belongs to
  - `email` string, email, required: Email address
  - `employment_type` 'full_time' | 'part_time' | 'contract' | 'freelance' | 'internship' | 'apprenticeship' | 'working_student' | 'training', nullable: Employment type
  - `first_name` string, required: First name
  - `full_name` string: Full name (computed)
  - `id` string, uuid, required: User ID
  - `inserted_at` string, date-time: Creation timestamp
  - `job_title` string, nullable: Job title
  - `last_name` string, required: Last name
  - `location_city` string, nullable: City location
  - `manager_user_id` string, uuid, nullable: Manager user ID
  - `offboarding_scheduled_at` string, date-time, nullable: When the planned offboarding starts
  - `onboarding_scheduled_at` string, date-time, nullable: When the planned onboarding starts provisioning
  - `status` 'active' | 'inactive' | 'onboarding' | 'onboarding_provisioning_planned' | 'offboarding' | 'offboarding_planned' | 'offboarded', required: Current status
  - `teams` string[]: Teams the user belongs to
  - `updated_at` string, date-time: Last update timestamp

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden
- `409`: Conflict
- `422`: Validation error
- `429`: Too many requests

## Changes

- **2026-10-31** `5a1f071e40d8`: 2 breaking, 3 warning, 3 info
  - response property `errors/additionalProperties/items/` list-of-types was widened by adding types `object` to media type `application/json` of response `422`
  - removed the required property `message` from the response with the `401` status
  - removed the optional property `errors` from the response with the `401` status
  - removed the optional property `errors` from the response with the `403` status
  - …4 more
- **2026-09-30** `1cc0fedf0bf8`: 2 info
  - added the optional property `offboarding_scheduled_at` to the response with the `201` status
  - added the optional property `onboarding_scheduled_at` to the response with the `201` status
- **2026-09-22** `1dba1160cea4`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/accessowl/apis/accessowl-api/changes/api/v1/users/post.md)

---

[API](https://skmtc.dev/accessowl/apis/accessowl-api.md) - [All operations](https://skmtc.dev/accessowl/apis/accessowl-api/llms.txt) - [OpenAPI document](https://skmtc.dev/accessowl/apis/accessowl-api/revisions/ff38c63d8807?raw)
