---
title: "Bulk create users"
method: POST
path: "/v3/users/bulk"
tags: ["Users"]
---

# Bulk create users

`POST /v3/users/bulk`

## Request

- Base URL: `https://harvest.greenhouse.io`
- URL: `https://harvest.greenhouse.io/v3/users/bulk`
- Auth: OAuth 2
  - Authorization code: `https://auth.greenhouse.io/authorize`
  - Client credentials
  - Token URL: `https://auth.greenhouse.io/token` scopes: `harvest:users:create`

Create up to the bulk-endpoint cap of users in a single request. Pass an array of user payloads in `data`, each matching the body shape of `POST /v3/users`. Each row is processed independently and the response reports per-row success or failure; rows that fail validation do not block the others. Use for HRIS-driven backfills or for provisioning a wave of new hires.

## Request body

- object
  - `callback_url` string: Optional HTTPS URL Greenhouse will POST to when every row in `data` has finished. Omit to poll `GET /v3/bulk_requests/{bulk_action_uuid}` instead.
  - `data` object[], required: Array of single-resource create payloads to process. Each item must match the schema of the matching non-bulk POST endpoint.
    - `send_email_invite` boolean: If `true`, Greenhouse sends the new user an invitation email so they can set a password and sign in. Defaults to `false` — useful when an HRIS sync provisions accounts ahead of the user's actual hire date.
    - `first_name` string, required
    - `last_name` string, required
    - `primary_email` string, email, required: Primary email address for the new user. Sign-in identifier and the address Greenhouse uses for invitation and notification mail. Must be unique within the organization.
    - `job_title` string: Free-form job title to set on the user's Greenhouse profile (e.g. `Senior Recruiter`).
    - `employee_id` string: Partner-supplied external employee identifier — typically the user's HRIS or payroll id. Recommended for HRIS-driven user sync so the user can be looked up later via `employee_ids`.
    - `office_ids` integer[]: Greenhouse office ids to pin the user to. Used for future job permission scoping. Mutually exclusive with `external_office_ids`.
    - `external_office_ids` string[]: External office identifiers (the offices' `external_id`) to pin the user to. Use this when the partner only has external office identifiers. Mutually exclusive with `office_ids`.
    - `department_ids` integer[]: Greenhouse department ids to pin the user to. Used for future job permission scoping. Mutually exclusive with `external_department_ids`.
    - `external_department_ids` string[]: External department identifiers (the departments' `external_id`) to pin the user to. Use this when the partner only has external department identifiers. Mutually exclusive with `department_ids`.
    - `interviewer_tag_ids` integer[]: Ids of interviewer tags to apply to the user, marking them as a qualified interviewer for those skill or panel groupings.
    - `custom_fields` union[]
      - union
        - object
          - `name_key` string, required: Required if custom_field_id is not provided. Exactly one of name_key or custom_field_id must be specified.
          - `custom_field_id` integer: Required if name_key is not provided. Exactly one of name_key or custom_field_id must be specified.
          - `value` union
            - boolean
            - number: User ID
            - union
              - …
            - union
              - …
        - object
          - `name_key` string: Required if custom_field_id is not provided. Exactly one of name_key or custom_field_id must be specified.
          - `custom_field_id` integer, required: Required if name_key is not provided. Exactly one of name_key or custom_field_id must be specified.
          - `value` union
            - boolean
            - number: User ID
            - union
              - …
            - union
              - …

## Response `202`

Accepted

- object
  - `bulk_action_uuid` string: UUID assigned to the new bulk request. Use this with `GET /v3/bulk_requests/{bulk_action_uuid}` to monitor progress and retrieve per-row results.
  - `status` string: Initial lifecycle state of the new bulk request, typically `building` immediately after creation. See the bulk request response schema for the full set of values.
  - `status_url` string: Relative path that returns the current status of the bulk request. Append this to your Harvest base URL to fetch the latest state.

## Other responses

- `401`: Unauthorized
- `413`: Payload is larger than 10MB
- `422`: Validation Error
- `429`: Client has more than 5 active jobs

---

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