> ## 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 somebody, or give somebody more access

> 201 when an account was created for the address and an invitation emailed. 200 when the address already belongs to somebody in your account: the access you asked for is added, no second account is created and no email is sent — `alreadyExisted` and `invitationEmailed` in the response say which happened. 404 when any organisation named is not yours.

State the access as either `organisationIds` or `allOrganisations: true`, never both. `allOrganisations` grants account-wide access — every organisation the account owns, including ones added later — and only somebody who already holds it may grant it (403 `whole_customer_access_denied` otherwise). Every organisation named is checked against what you can reach, so nobody grants wider than they hold.

**Guests** (`asGuest: true`): somebody from another business, invited into the organisations you pick and nothing else. They never see your other organisations, your people or your settings; you see only the access you granted, and can take it back at any time. `organisationIds` is required and `allOrganisations` is refused for a guest. If they have no account, one is created for them in their own right — never a place in yours.

**Sign-in** follows your account's set-up (`GET /customer`, `signIn`). Where your account links people to an identity provider and passwords are not `Allowed`, the new person is linked instead of emailed: `invitationEmailed` is false, they open Flow Payroll from the provider, and there is no password to reset. `signIn: Password` asks for a password of their own, for somebody outside the provider such as a bureau; 409 `password_sign_in_denied` where your account never issues passwords, and 409 `identity_provider_not_configured` for `signIn: IdentityProvider` where it has no provider. Giving somebody more access never changes how they sign in.

An account may hold 500 people. Only a new account of your own uses one of those places, so an invitation that turns out to be an access change works at the limit, and an account already past the limit keeps everyone it has. Three things answer 409, told apart by `message.token`:
- `user_limit_reached` — the account already holds 500 people. The account owner can remove somebody who no longer needs access with `DELETE /users/{principalId}`, or contact support to raise the allowance.
- `email_already_in_use` — that address already signs in to a different account, so it cannot be invited here — unless you invite them as a guest.
- `account_needs_repair` — that address has an older account that support must repair before it can be given access.



## OpenAPI

````yaml /api-reference/specs/administration.json post /users
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:
    post:
      tags:
        - Users
      summary: Invite somebody, or give somebody more access
      description: >-
        201 when an account was created for the address and an invitation
        emailed. 200 when the address already belongs to somebody in your
        account: the access you asked for is added, no second account is created
        and no email is sent — `alreadyExisted` and `invitationEmailed` in the
        response say which happened. 404 when any organisation named is not
        yours.


        State the access as either `organisationIds` or `allOrganisations:
        true`, never both. `allOrganisations` grants account-wide access — every
        organisation the account owns, including ones added later — and only
        somebody who already holds it may grant it (403
        `whole_customer_access_denied` otherwise). Every organisation named is
        checked against what you can reach, so nobody grants wider than they
        hold.


        **Guests** (`asGuest: true`): somebody from another business, invited
        into the organisations you pick and nothing else. They never see your
        other organisations, your people or your settings; you see only the
        access you granted, and can take it back at any time. `organisationIds`
        is required and `allOrganisations` is refused for a guest. If they have
        no account, one is created for them in their own right — never a place
        in yours.


        **Sign-in** follows your account's set-up (`GET /customer`, `signIn`).
        Where your account links people to an identity provider and passwords
        are not `Allowed`, the new person is linked instead of emailed:
        `invitationEmailed` is false, they open Flow Payroll from the provider,
        and there is no password to reset. `signIn: Password` asks for a
        password of their own, for somebody outside the provider such as a
        bureau; 409 `password_sign_in_denied` where your account never issues
        passwords, and 409 `identity_provider_not_configured` for `signIn:
        IdentityProvider` where it has no provider. Giving somebody more access
        never changes how they sign in.


        An account may hold 500 people. Only a new account of your own uses one
        of those places, so an invitation that turns out to be an access change
        works at the limit, and an account already past the limit keeps everyone
        it has. Three things answer 409, told apart by `message.token`:

        - `user_limit_reached` — the account already holds 500 people. The
        account owner can remove somebody who no longer needs access with
        `DELETE /users/{principalId}`, or contact support to raise the
        allowance.

        - `email_already_in_use` — that address already signs in to a different
        account, so it cannot be invited here — unless you invite them as a
        guest.

        - `account_needs_repair` — that address has an older account that
        support must repair before it can be given access.
      operationId: InviteUser
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InviteUserRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserInvitedResponseResponseBody'
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserInvitedResponseResponseBody'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectResponseBody'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectResponseBody'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectResponseBody'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectResponseBody'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectResponseBody'
components:
  schemas:
    InviteUserRequest:
      type: object
      properties:
        email:
          type: string
          description: >-
            Required. The address they sign in with. It is also their identity
            here, so inviting the same

            address twice is recognised as the same person and answered as an
            access change.
          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. State exactly one of this and
            `allOrganisations`.
          nullable: true
        allOrganisations:
          type: boolean
          description: >-
            Give access to every organisation the account owns, including ones
            added later. Only somebody who

            already holds account-wide access may grant it. State exactly one of
            this and

            `organisationIds`; a request giving both is refused rather than
            merged.
        asGuest:
          type: boolean
          description: >-
            The person belongs to another business. They are invited into the
            organisations you pick, never

            into the account: they cannot see your other organisations, your
            people or your settings, and

            you can take the access back at any time. Requires OrganisationIds;

            AllOrganisations is refused for guests.
        signIn:
          type: string
          description: >-
            How they sign in. `IdentityProvider` links them to your account's
            identity provider;

            `Password` gives them a password of their own, for somebody outside
            your identity provider

            such as a bureau. Leave it out to use your account's default.
            `Password` is refused when your

            account signs people in through its identity provider only, and
            `IdentityProvider` when it

            has none.
          nullable: true
      additionalProperties: false
      description: >-
        Invites somebody into your account, or gives more access to somebody
        already in it.
    UserInvitedResponseResponseBody:
      type: object
      properties:
        message:
          $ref: '#/components/schemas/MessageWithTokenResponse'
        content:
          $ref: '#/components/schemas/UserInvitedResponseContentResponse'
        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
    MessageWithTokenResponse:
      type: object
      properties:
        text:
          type: string
        token:
          type: string
        tokenArguments:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssueArgument'
          nullable: true
      additionalProperties: false
    UserInvitedResponseContentResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/UserInvitedResponse'
        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
    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.
    ContentMetadataResponse:
      type: object
      properties:
        dateFormat:
          type: string
        dateTimeFormat:
          type: string
        paginationToken:
          type: string
          nullable: true
      additionalProperties: false
  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.