> ## 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.

# Create an end user

> Create a single end-user record. Duplicate emails or phones return 409 DUPLICATE_ENDUSER.

Creates one end-user record. Email and phone are normalized on write.

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

<ParamField body="origin" type="string" required>
  `inbound`, `imported`, or `manual`.
</ParamField>

<ParamField body="name" type="string">
  Display name.
</ParamField>

<ParamField body="email" type="string">
  Email address.
</ParamField>

<ParamField body="phone" type="string">
  Phone number.
</ParamField>

<ParamField body="channelIdentifiers" type="object">
  Per-channel identifiers.
</ParamField>

<ParamField body="tags" type="string[]">
  Tags to apply.
</ParamField>

## Response

Success returns `201`.

<ResponseField name="success" type="boolean">
  `true` on success.
</ResponseField>

<ResponseField name="endUserId" type="string">
  ID of the created record, used in the by-ID endpoints.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST \
    https://us.api.hellotars.com/api/endusers \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{ "origin": "manual", "name": "Ada Point", "email": "ada@example.com" }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://us.api.hellotars.com/api/endusers",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.TARS_API_KEY}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        origin: "manual",
        name: "Ada Point",
        email: "ada@example.com"
      })
    }
  );

  const data = await response.json();
  ```

  ```python Python theme={null}
  import os
  import requests

  response = requests.post(
      "https://us.api.hellotars.com/api/endusers",
      headers={
          "Authorization": f"Bearer {os.environ['TARS_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
          "origin": "manual",
          "name": "Ada Point",
          "email": "ada@example.com",
      },
  )

  data = response.json()
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  { "success": true, "endUserId": "eu_123" }
  ```

  ```json 409 theme={null}
  { "error": "An end user with this email already exists", "code": "DUPLICATE_ENDUSER" }
  ```
</ResponseExample>

## Errors

| Status | Code                            | Cause                                                           |
| ------ | ------------------------------- | --------------------------------------------------------------- |
| `400`  | `INVALID_BODY`, `CREATE_FAILED` | Malformed body, unknown or missing `origin`, or creation failed |
| `401`  | `UNAUTHORIZED`                  | Missing, invalid, or revoked key                                |
| `403`  | `FORBIDDEN`                     | Key lacks the **End-users** permission                          |
| `409`  | `DUPLICATE_ENDUSER`             | Email or phone already exists on another record                 |


## OpenAPI

````yaml api-reference/openapi.json POST /api/endusers
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:
    post:
      tags:
        - End users
      summary: Create an end user
      operationId: createEndUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateEndUser'
      responses:
        '201':
          description: End user created
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    description: True when the record was created.
                  endUserId:
                    type: string
                    description: >-
                      The new record's ID. Pass it to the single-record
                      endpoints.
                required:
                  - success
                  - endUserId
        '400':
          description: Malformed body or creation failure (INVALID_BODY, CREATE_FAILED)
          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'
        '409':
          description: Email or phone already exists on another record (DUPLICATE_ENDUSER)
          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.

````