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

# Invite Members

> Invites people to the org by email. New emails become pending members and receive an invite email; existing members are unchanged.



## OpenAPI

````yaml api-reference/openapi-generated.json POST /v1/members/invite
openapi: 3.0.3
info:
  title: Periskope API
  version: 1.0.0
  description: >-
    Periskope external API.


    Responses use a flat, unwrapped shape: most endpoints return the resource at
    the top level, and list endpoints return a wrapper object with pagination
    inline (e.g. `{ from, to, count, chats: [...] }`). The documented response
    schemas describe these shapes directly.
servers:
  - url: https://api.periskope.app
security:
  - bearerAuth: []
paths:
  /v1/members/invite:
    post:
      tags:
        - Members
      summary: Invite members
      description: >-
        Invites people to the org by email. New emails become pending members
        and receive an invite email; existing members are unchanged.
      operationId: inviteMembers
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                emails:
                  type: array
                  items:
                    type: string
                  minItems: 1
                  description: >-
                    Email addresses to invite. Emails that already belong to the
                    org are skipped and reported in the errors array of the
                    response instead of failing the request.
                  example:
                    - user@example.com
                    - user@example.com
                role:
                  type: string
                  enum:
                    - admin
                    - member
                  description: >-
                    Role given to every invitee. Defaults to 'member'. Admins
                    have universal access, so labels and orgPhones are not
                    applied to admin invites.
                  example: member
                labels:
                  type: array
                  nullable: true
                  items:
                    type: string
                  description: >-
                    Names (not ids) of chat labels to scope the new members’
                    chat access to. Matched case-insensitively against the org’s
                    existing chat labels — unknown names reject the whole
                    request, create the labels first. Applied only when role is
                    member.
                  example:
                    - Support
                orgPhones:
                  type: array
                  nullable: true
                  items:
                    type: string
                  description: >-
                    Phone numbers to scope the new members’ chat access to, as
                    country code + number without symbols or spaces (e.g.
                    911111111111) — the @c.us suffix is optional. Every phone
                    must already exist in the org, otherwise the whole request
                    is rejected. Applied only when role is member.
                  example:
                    - '911111111111'
              required:
                - emails
      responses:
        '200':
          description: The added members and any per-email failures
          content:
            application/json:
              schema:
                type: object
                properties:
                  addedMembers:
                    type: array
                    items:
                      $ref: '#/components/schemas/Member'
                    description: >-
                      The newly created member rows, with label_ids and
                      org_phones already reflecting any labels/orgPhones passed
                      in the request (member invites only). Empty when every
                      email already existed or the user limit was reached.
                  errors:
                    type: array
                    items:
                      $ref: '#/components/schemas/MemberOperationError'
                    description: >-
                      Per-email failures: emails that already belong to the org,
                      invite emails that could not be sent, or a single email:
                      null entry when the org’s user limit was reached (in which
                      case nobody is added)
              examples:
                default:
                  summary: Response body
                  value:
                    addedMembers:
                      - org_id: 00000000-0000-0000-0000-000000000000
                        email: user@example.com
                        role: member
                        user_id: 00000000-0000-0000-0000-000000000000
                        member_name: John Doe
                        member_image: null
                        member_color: '#25D366'
                        org_phones:
                          - 911111111111@c.us
                        label_ids:
                          - label-aaaaaaaaaaaa
                        is_active: true
                        is_online: false
                        is_owner: false
                        invited_at: '2026-01-15T09:30:00.000Z'
                        invited_by: user@example.com
                        member_metadata: null
                        preferences: {}
                        created_at: '2026-01-15T09:30:00.000Z'
                    errors:
                      - email: user@example.com
                        error:
                          message: User user@example.com already exists
        '401':
          description: Invalid, expired or missing API token
          content:
            application/json:
              examples:
                error:
                  summary: Invalid, expired or missing API token
                  value:
                    code: UNAUTHORIZED_ERROR
                    message: Invalid bearer auth token
                    status: 401
              schema:
                type: object
                properties:
                  code:
                    type: string
                    example: UNAUTHORIZED_ERROR
                  message:
                    type: string
                    example: Invalid bearer auth token
                  status:
                    type: integer
                    example: 401
                example:
                  code: UNAUTHORIZED_ERROR
                  message: Invalid bearer auth token
                  status: 401
        '422':
          description: Request validation failed
          content:
            application/json:
              examples:
                error:
                  summary: Request validation failed
                  value:
                    code: VALIDATION_ERROR
                    message: Request validation failed
                    status: 422
                    fields:
                      body.chat_id:
                        message: chat_id is required
              schema:
                type: object
                properties:
                  code:
                    type: string
                    example: VALIDATION_ERROR
                  message:
                    type: string
                    example: Request validation failed
                  status:
                    type: integer
                    example: 422
                  fields:
                    type: object
                    additionalProperties:
                      type: object
                      properties:
                        message:
                          type: string
                        value: {}
                    example:
                      body.chat_id:
                        message: chat_id is required
                example:
                  code: VALIDATION_ERROR
                  message: Request validation failed
                  status: 422
                  fields:
                    body.chat_id:
                      message: chat_id is required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              examples:
                error:
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMIT_ERROR
                    message: You can only make 100 requests per second
                    status: 429
              schema:
                type: object
                properties:
                  code:
                    type: string
                    example: RATE_LIMIT_ERROR
                  message:
                    type: string
                    example: You can only make 100 requests per second
                  status:
                    type: integer
                    example: 429
                example:
                  code: RATE_LIMIT_ERROR
                  message: You can only make 100 requests per second
                  status: 429
        '500':
          description: Internal server error
          content:
            application/json:
              examples:
                error:
                  summary: Internal server error
                  value:
                    code: UNKNOWN_ERROR
                    message: Internal server error
                    status: 500
              schema:
                type: object
                properties:
                  code:
                    type: string
                    example: UNKNOWN_ERROR
                  message:
                    type: string
                    example: Internal server error
                  status:
                    type: integer
                    example: 500
                example:
                  code: UNKNOWN_ERROR
                  message: Internal server error
                  status: 500
      security:
        - bearerAuth: []
      x-codeSamples:
        - lang: typescript
          label: TypeScript
          source: |-
            import { PeriskopeApi } from '@periskope/periskope-client';

            const client = new PeriskopeApi({
              authToken: 'YOUR_API_KEY',
            });

            async function main() {
              const response = await client.members.inviteMembers({
                emails: [
                  'user@example.com',
                  'user@example.com',
                ],
              });
              console.log(response);
            }

            main();
        - lang: bash
          label: cURL
          source: |-
            curl -X POST 'https://api.periskope.app/v1/members/invite' \
              -H 'Authorization: Bearer YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "emails": [
                  "user@example.com",
                  "user@example.com"
                ]
              }'
components:
  schemas:
    Member:
      type: object
      properties:
        org_id:
          type: string
          description: Id of the organization the member belongs to
          example: 00000000-0000-0000-0000-000000000000
        email:
          type: string
          description: >-
            Email address of the member — the identifier every members endpoint
            uses to reference them
          example: user@example.com
        role:
          type: string
          enum:
            - admin
            - member
          description: >-
            Role of the member. 'admin' members have universal access to every
            chat and phone in the org; 'member' access is scoped by org_phones
            and label_ids.
          example: member
        user_id:
          type: string
          description: >-
            Id of the member’s Periskope user account. null while the invite is
            pending — set once the invitee signs up and joins the org.
          example: 00000000-0000-0000-0000-000000000000
        member_name:
          type: string
          description: Display name of the member. null until the member sets one.
          example: John Doe
        member_image:
          type: string
          description: URL of the member’s avatar image. null when not set.
          example: null
        member_color:
          type: string
          description: >-
            Hex color used to represent the member in the dashboard, assigned
            randomly when the member is added
          example: '#25D366'
        org_phones:
          type: array
          items:
            type: string
          description: >-
            Phones the member’s chat access is scoped to, stored with the @c.us
            suffix. Only meaningful for role member — always null for admins,
            who can access every phone. null when no phone scoping is
            configured.
          example:
            - 911111111111@c.us
        label_ids:
          type: array
          items:
            type: string
          description: >-
            Ids of the chat labels the member’s chat access is scoped to
            (label-xxxx). Only meaningful for role member — always null for
            admins. null when no label scoping is configured.
          example:
            - label-aaaaaaaaaaaa
        is_active:
          type: boolean
          description: Whether the member is active in the org
          example: true
        is_online:
          type: boolean
          description: >-
            Whether the member is currently online in the dashboard. null when
            never tracked.
          example: false
        is_owner:
          type: boolean
          description: >-
            true for the org owner. The owner cannot be removed or modified via
            the members endpoints. null or false for everyone else.
          example: false
        invited_at:
          type: string
          description: >-
            When the member was invited, as an ISO 8601 timestamp. null when
            unknown.
          example: '2026-01-15T09:30:00.000Z'
        invited_by:
          type: string
          description: Email of the user who invited this member. null when unknown.
          example: user@example.com
        member_metadata:
          description: Free-form JSON metadata attached to the member. null when not set.
          example: null
        preferences:
          description: Dashboard preferences of the member, as a JSON object
          example: {}
        created_at:
          type: string
          description: When the member row was created, as an ISO 8601 timestamp
          example: '2026-01-15T09:30:00.000Z'
      description: >-
        An org member — one row of the workspace’s team list, identified by
        email within the org. Admins have universal access to every chat and
        phone; members have their chat access scoped by org_phones and
        label_ids. user_id stays null until the invitee signs up on Periskope.
    MemberOperationError:
      type: object
      properties:
        email:
          type: string
          description: >-
            Email address of the entry that failed. null for org-level failures
            that are not tied to one email (e.g. the user limit being reached).
          example: user@example.com
        error:
          description: Details of the failure, typically an object with a message field
          example:
            message: User user@example.com already exists
      description: >-
        A per-entry failure reported by a bulk member operation. The overall
        request still responds 200 — inspect this list to find entries that were
        not applied.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Your Periskope API token, sent as `Authorization: Bearer <token>`.
        Generate one from the Periskope dashboard under **Settings → API &
        Webhooks**. API access requires an active Pro or Enterprise plan.

````

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