> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flowpayroll.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Invite several people at once

> State the access once in `defaults`; any entry may override it. Leave a field out of an entry to inherit the default, or set it to override. An entry that names organisations replaces the default set for that person rather than adding to it, and `allOrganisations: false` on an entry opts that person out of a default of `true`.

Each person is invited exactly as `POST /users` would invite them, so nothing about the authorisation differs. 201 when every entry went through, 207 when some did, 400 when none did. In all three the body lists what happened to each entry, and a failed entry carries the same `reason` token the single endpoint would have answered with in `message.token`. Partial success is normal and is not rolled back: invitations already sent stay sent.

The account's limit of 500 people is counted once for the whole batch. A batch carrying more new people than there is room for fills the remaining places and answers `user_limit_reached` on the rest; entries that turn out to be access changes for people already in the account use no place at all.



## OpenAPI

````yaml /api-reference/specs/administration.json post /users/bulk
openapi: 3.0.1
info:
  title: Administration API
  description: >-
    Manage your Flow Payroll account: the organisations it owns, the people who
    can sign in to it, the API tokens it holds, its brand, and a feed of recent
    administration activity. Every resource is scoped to the account your
    credentials belong to, so no request ever names a customer and the
    `X-Org-Id` header is not used.
  version: v1
servers:
  - url: https://api.sandbox.flowpayroll.ai/v1/administration
security:
  - X-Auth-Token: []
tags:
  - name: Customer
    description: >-
      Your account: the customer every other resource on this API belongs to.
      Read it and rename it.
  - name: Organisations
    description: >-
      The organisations your account owns: list them with headcounts and your
      access to each, get one in full, and add one or several at a time.
  - name: Users
    description: >-
      The people who can sign in to your account: list, invite (one or many),
      resend invitations, and manage each person's direct grants and
      account-wide access.
  - name: API tokens
    description: >-
      The client credentials your integrations authenticate with: create (the
      secret is shown once), rename, rotate, revoke, and manage which
      organisations each token reaches.
  - name: Activity
    description: Recent administration actions in your account, newest first.
paths:
  /users/bulk:
    post:
      tags:
        - Users
      summary: Invite several people at once
      description: >-
        State the access once in `defaults`; any entry may override it. Leave a
        field out of an entry to inherit the default, or set it to override. An
        entry that names organisations replaces the default set for that person
        rather than adding to it, and `allOrganisations: false` on an entry opts
        that person out of a default of `true`.


        Each person is invited exactly as `POST /users` would invite them, so
        nothing about the authorisation differs. 201 when every entry went
        through, 207 when some did, 400 when none did. In all three the body
        lists what happened to each entry, and a failed entry carries the same
        `reason` token the single endpoint would have answered with in
        `message.token`. Partial success is normal and is not rolled back:
        invitations already sent stay sent.


        The account's limit of 500 people is counted once for the whole batch. A
        batch carrying more new people than there is room for fills the
        remaining places and answers `user_limit_reached` on the rest; entries
        that turn out to be access changes for people already in the account use
        no place at all.
      operationId: BulkInviteUsers
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkInviteUsersRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkInviteUsersResponseResponseBody'
        '207':
          description: Multi-Status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkInviteUsersResponseResponseBody'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkInviteUsersResponseResponseBody'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectResponseBody'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectResponseBody'
components:
  schemas:
    BulkInviteUsersRequest:
      type: object
      properties:
        defaults:
          $ref: '#/components/schemas/BulkInviteDefaultsRequest'
        entries:
          type: array
          items:
            $ref: '#/components/schemas/BulkInviteEntryRequest'
          description: >-
            The people to invite. Each is processed exactly as `POST /users`
            would process it.
          nullable: true
      additionalProperties: false
      description: >-
        Invites several people in one request: shared defaults plus per-entry
        overrides.
    BulkInviteUsersResponseResponseBody:
      type: object
      properties:
        message:
          $ref: '#/components/schemas/MessageWithTokenResponse'
        content:
          $ref: '#/components/schemas/BulkInviteUsersResponseContentResponse'
        validationIssues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          nullable: true
      additionalProperties: false
    ObjectResponseBody:
      type: object
      properties:
        message:
          $ref: '#/components/schemas/MessageWithTokenResponse'
        content:
          $ref: '#/components/schemas/ObjectContentResponse'
        validationIssues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          nullable: true
      additionalProperties: false
    BulkInviteDefaultsRequest:
      type: object
      properties:
        organisationIds:
          type: array
          items:
            type: string
          description: >-
            The organisations to grant to every entry that does not name its
            own.
          nullable: true
        allOrganisations:
          type: boolean
          description: >-
            Give every entry account-wide access unless it opts out with
            `allOrganisations: false`.
      additionalProperties: false
      description: >-
        The access every person in the request gets unless their own entry says
        otherwise.
    BulkInviteEntryRequest:
      type: object
      properties:
        email:
          type: string
          description: Required. The address they sign in with.
          nullable: true
        givenName:
          type: string
          description: Their first name, used in the invitation.
          nullable: true
        familyName:
          type: string
          description: Their last name, used in the invitation.
          nullable: true
        organisationIds:
          type: array
          items:
            type: string
          description: >-
            The organisations to grant this person. Replaces the default set
            rather than adding to it.
          nullable: true
        allOrganisations:
          type: boolean
          description: >-
            Nullable so that `false` can opt this person out of a default of
            `true`. Omit it to inherit.
          nullable: true
      additionalProperties: false
      description: >-
        One person in a bulk invitation. Leave a field out to inherit the
        default; set it to override.
    MessageWithTokenResponse:
      type: object
      properties:
        text:
          type: string
        token:
          type: string
        tokenArguments:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssueArgument'
          nullable: true
      additionalProperties: false
    BulkInviteUsersResponseContentResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/BulkInviteUsersResponse'
        metadata:
          $ref: '#/components/schemas/ContentMetadataResponse'
      additionalProperties: false
    ValidationIssue:
      type: object
      properties:
        field:
          type: string
        reason:
          type: string
        reasonToken:
          type: string
        reasonTokenArguments:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssueArgument'
          nullable: true
      additionalProperties: false
    ObjectContentResponse:
      type: object
      properties:
        data:
          nullable: true
        metadata:
          $ref: '#/components/schemas/ContentMetadataResponse'
      additionalProperties: false
    ValidationIssueArgument:
      type: object
      properties:
        name:
          type: string
        value:
          nullable: true
      additionalProperties: false
    BulkInviteUsersResponse:
      type: object
      properties:
        invited:
          type: array
          items:
            $ref: '#/components/schemas/UserInvitedResponse'
          description: >-
            The entries that went through, including access changes for people
            already in the account.
        failed:
          type: array
          items:
            $ref: '#/components/schemas/BulkFailureResponse'
          description: The entries that were refused, each with the reason.
      additionalProperties: false
      description: >-
        What a bulk invitation did, person by person. The status code says
        whether all, some or none of

        the entries went through; this body says which.
    ContentMetadataResponse:
      type: object
      properties:
        dateFormat:
          type: string
        dateTimeFormat:
          type: string
        paginationToken:
          type: string
          nullable: true
      additionalProperties: false
    UserInvitedResponse:
      type: object
      properties:
        principalId:
          type: string
          description: The person invited or changed.
        alreadyExisted:
          type: boolean
          description: >-
            True when the address already belonged to somebody in your account,
            so this was an access change

            rather than a new invitation.
        grantedOrganisationIds:
          type: array
          items:
            type: string
          description: Organisations this call added.
        alreadyHeldOrganisationIds:
          type: array
          items:
            type: string
          description: >-
            Organisations they already held, so asking again changed nothing for
            them.
        coversWholeCustomer:
          type: boolean
          description: Whether they hold account-wide access after this call.
        invitationEmailed:
          type: boolean
          description: >-
            Whether an invitation email was sent. False on an access change:
            they already have a working

            account, and a second invitation would reset a temporary password
            they may be part way through

            using.
      additionalProperties: false
      description: What an invitation did.
    BulkFailureResponse:
      type: object
      properties:
        reference:
          type: string
          description: >-
            The entry as you sent it, so you can find it in your own request:
            the email address for a person,

            the legal name for an organisation.
        reason:
          type: string
          description: >-
            The same stable snake_case token the single-item endpoint would
            answer with in `message.token`,

            so there is one set of reasons to handle.
        message:
          type: string
          description: A sentence explaining the refusal.
      additionalProperties: false
      description: One entry of a bulk request that was refused.
  securitySchemes:
    X-Auth-Token:
      type: apiKey
      description: FlowPayroll JWT (raw token, no Bearer prefix)
      name: X-Auth-Token
      in: header

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.