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

# Batch-create end users

> Create up to 50 end-user records in one request and get per-row results with skipped duplicates.

A batch never fails because of one duplicate row. Tars checks each entry's email and phone against earlier entries in the same request and against existing records. A match is skipped, and the rest of the batch is still created.

Requires a key with the **End-users** permission. See [API authentication](/docs/developer/authentication).

<ParamField body="endUsers" type="object[]" required>
  At most 50 entries. Each entry uses the [create fields](/docs/developer/api/end-users/create) and needs an `origin`.
</ParamField>

## Response

The response reports per-row results.

<ResponseField name="created" type="number">
  Count of records created.
</ResponseField>

<ResponseField name="skipped" type="number">
  Count of entries skipped as duplicates.
</ResponseField>

<ResponseField name="errors" type="object[]">
  One entry per skipped row, with its `index` in the batch and a `reason`.
</ResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "created": 48,
    "skipped": 2,
    "errors": [{ "index": 7, "reason": "duplicate email" }]
  }
  ```
</ResponseExample>

## Errors

| Status | Code           | Cause                                                                                                                  |
| ------ | -------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `400`  | `INVALID_BODY` | Malformed body, an empty or missing `endUsers` array, over 50 entries, or an entry with an unknown or missing `origin` |
| `401`  | `UNAUTHORIZED` | Missing, invalid, or revoked key                                                                                       |
| `403`  | `FORBIDDEN`    | Key lacks the **End-users** permission                                                                                 |


## OpenAPI

````yaml api-reference/openapi.json POST /api/endusers/batch
openapi: 3.1.0
info:
  title: Tars API
  version: 3.0.0
  description: >-
    Public REST API for Tars agents: start conversations at trigger gambits,
    send channel messages, manage end users, and drive webhook campaigns.
servers:
  - url: https://us.api.hellotars.com
    description: United States
  - url: https://eu.api.hellotars.com
    description: European Union
  - url: https://in.api.hellotars.com
    description: India
  - url: https://qa.api.hellotars.com
    description: Qatar
security:
  - bearerAuth: []
tags:
  - name: Triggers
    description: Start conversations at trigger gambits
  - name: Channels
    description: Outbound channel message sends
  - name: End users
    description: End-user record management
  - name: Campaigns
    description: Webhook campaign sends and validation
paths:
  /api/endusers/batch:
    post:
      tags:
        - End users
      summary: Batch-create end users
      operationId: batchCreateEndUsers
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                endUsers:
                  type: array
                  description: >-
                    The records to create, up to 50 per request. Each row is
                    reported separately, so a duplicate skips that row without
                    failing the call.
                  items:
                    $ref: '#/components/schemas/CreateEndUser'
                  minItems: 1
                  maxItems: 50
              required:
                - endUsers
      responses:
        '200':
          description: Batch result; duplicates are skipped, not failed
          content:
            application/json:
              schema:
                type: object
                properties:
                  created:
                    type: integer
                    description: How many records were created.
                  skipped:
                    type: integer
                    description: >-
                      How many rows were skipped, usually because the email or
                      phone already exists.
                  errors:
                    type: array
                    description: >-
                      One entry per rejected row. The rest of the batch is still
                      created.
                    items:
                      type: object
                      description: A row that could not be created.
                      properties:
                        index:
                          type: integer
                          description: >-
                            The row's zero-based position in the endUsers array
                            you sent.
                        reason:
                          type: string
                          description: >-
                            Why the row was rejected, for example duplicate
                            email.
                      required:
                        - index
                        - reason
                required:
                  - created
                  - skipped
                  - errors
        '400':
          description: >-
            Malformed body, empty array, over 50 entries, or invalid origin
            (INVALID_BODY)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EndUserError'
        '401':
          description: Missing, invalid, or revoked API key (UNAUTHORIZED)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EndUserError'
        '403':
          description: Key lacks the endusers scope (FORBIDDEN)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EndUserError'
components:
  schemas:
    CreateEndUser:
      type: object
      description: Fields accepted when creating an end-user record.
      properties:
        name:
          type: string
          description: Display name.
        email:
          type: string
          description: >-
            Email address. Must be unique in your organization, or the call
            returns 409 DUPLICATE_ENDUSER.
        phone:
          type: string
          description: >-
            Phone number in international format. Must be unique in your
            organization, or the call returns 409 DUPLICATE_ENDUSER.
        channelIdentifiers:
          $ref: '#/components/schemas/ChannelIdentifiers'
        tags:
          type: array
          items:
            type: string
          description: Free-form tags to apply to the new record.
        origin:
          type: string
          enum:
            - inbound
            - imported
            - manual
          description: How the record was created. Required.
      required:
        - origin
    EndUserError:
      type: object
      description: An error from the end-user endpoints.
      properties:
        error:
          type: string
          description: A sentence describing what went wrong.
        code:
          type: string
          description: >-
            A stable machine-readable code, for example DUPLICATE_ENDUSER or
            INVALID_ORIGIN.
        details:
          type: object
          description: >-
            Reserved for extra error context. The end-user endpoints do not
            currently return it.
      required:
        - error
        - code
    ChannelIdentifiers:
      type: object
      description: >-
        Where Tars can reach this end user on each channel. Every field is
        optional, and only the channels Tars has seen are present.
      properties:
        web:
          type: string
          description: The end user's identifier on the web channel.
        whatsapp:
          type: object
          description: The end user's WhatsApp identity.
          properties:
            phone:
              type: string
              description: Phone number in international format, for example +15551234567.
            bsuid:
              type: string
              description: An alternate WhatsApp identifier for the end user.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key sent as Authorization: Bearer YOUR_API_KEY. Campaign endpoints
        use campaign-scoped keys; the rest use organization or agent keys with
        the matching permission.

````