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

# Add a counsellor

> Makes a person a counsellor of your account. A NEW email gets a dashboard login (active at once) and, unless `send_welcome_email` is false, the welcome email with their username and password. An email whose login belongs to another account on the platform (or to none) is refused with `409 email_in_use_elsewhere`, so your key never sees someone else's details. The login of a person removed from your account earlier is reused: the counsellor role is added back, their name, mobile number and password stay as they are, and no email is sent. The API only ever grants the counsellor role.

Scope: `counsellors:manage`.



## OpenAPI

````yaml /api-reference/openapi.json post /counsellors
openapi: 3.1.0
info:
  title: Telleo API
  version: 1.3.0
  description: >-
    Start AI phone calls, or connect your counsellors to contacts, from your own
    systems and get each call's outcome back. Manage your counsellors and AI
    agents from the same API.
servers:
  - url: https://api.telleo.ai/v1
security:
  - ApiKey: []
tags:
  - name: Calls
  - name: Batches
  - name: Agents
  - name: Human calls
  - name: Counsellors
  - name: Credits
  - name: Webhook
paths:
  /counsellors:
    post:
      tags:
        - Counsellors
      summary: Add a counsellor
      description: >-
        Makes a person a counsellor of your account. A NEW email gets a
        dashboard login (active at once) and, unless `send_welcome_email` is
        false, the welcome email with their username and password. An email
        whose login belongs to another account on the platform (or to none) is
        refused with `409 email_in_use_elsewhere`, so your key never sees
        someone else's details. The login of a person removed from your account
        earlier is reused: the counsellor role is added back, their name, mobile
        number and password stay as they are, and no email is sent. The API only
        ever grants the counsellor role.


        Scope: `counsellors:manage`.
      operationId: createCounsellor
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
            maxLength: 255
          description: Same body + same key within 24 hours returns the first result.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCounsellor'
            example:
              name: Asha Rao
              email: asha@school.in
              mobile_number: '+919876543210'
      responses:
        '200':
          description: >-
            Already a counsellor here (`created: false`), or a replay of this
            `Idempotency-Key` (`idempotent_replay: true`).
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CounsellorWrite'
        '201':
          description: The counsellor was added.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CounsellorWrite'
              example:
                id: 6b7e0c2a-1d3f-4e5a-8b9c-0d1e2f3a4b5c
                object: counsellor
                name: Asha Rao
                email: asha@school.in
                roles:
                  - COUNSELLOR
                status: active
                can_call: true
                blocked_reason: null
                mobile_number: '919876543210'
                airtel_extension: null
                manageable: true
                shared_account: false
                created: true
                existing_account: false
                welcome_email_sent: true
                warnings: []
        '400':
          description: The request is not valid.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                invalid_request:
                  value:
                    error:
                      code: invalid_request
                      message: email is not a valid email address.
                      request_id: req_8f2c1a7e
        '401':
          description: The key is missing, unknown, revoked or expired.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                missing_api_key:
                  value:
                    error:
                      code: missing_api_key
                      message: Send your API key in the X-API-Key header.
                      request_id: req_8f2c1a7e
                invalid_api_key:
                  value:
                    error:
                      code: invalid_api_key
                      message: This API key is not valid.
                      request_id: req_8f2c1a7e
        '403':
          description: >-
            The key lacks the counsellors:manage scope. Keys only have it when
            created with it.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: This API key does not have the counsellors:manage scope.
                      request_id: req_8f2c1a7e
        '409':
          description: The email cannot be made a counsellor through the API.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                account_has_other_role:
                  value:
                    error:
                      code: account_has_other_role
                      message: >-
                        This email belongs to a member of this account with
                        another role (ADMIN)…
                      request_id: req_8f2c1a7e
                email_in_use_elsewhere:
                  value:
                    error:
                      code: email_in_use_elsewhere
                      message: >-
                        This email already has a login on the platform that does
                        not belong to this account…
                      request_id: req_8f2c1a7e
                counsellor_inactive:
                  value:
                    error:
                      code: counsellor_inactive
                      message: >-
                        This counsellor was deactivated. Reactivate them with
                        PATCH …
                      request_id: req_8f2c1a7e
                extension_taken:
                  value:
                    error:
                      code: extension_taken
                      message: >-
                        Airtel extension 201 is already mapped to another person
                        in this account.
                      request_id: req_8f2c1a7e
                idempotency_key_reused:
                  value:
                    error:
                      code: idempotency_key_reused
                      message: >-
                        This Idempotency-Key was already used for a different
                        request.
                      request_id: req_8f2c1a7e
                request_in_progress:
                  value:
                    error:
                      code: request_in_progress
                      message: >-
                        Another request is adding this email right now. Retry in
                        5 seconds.
                      request_id: req_8f2c1a7e
        '429':
          description: Too many requests for this key.
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying.
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limited:
                  value:
                    error:
                      code: rate_limited
                      message: Too many requests. Retry after 12 seconds.
                      request_id: req_8f2c1a7e
        '503':
          description: Your user directory could not be reached for a moment.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                temporarily_unavailable:
                  value:
                    error:
                      code: temporarily_unavailable
                      message: >-
                        Could not reach the account directory right now. Retry
                        shortly.
                      request_id: req_8f2c1a7e
components:
  schemas:
    CreateCounsellor:
      type: object
      required:
        - name
        - email
      properties:
        name:
          type: string
          maxLength: 120
        email:
          type: string
          format: email
          description: >-
            Their dashboard login. An email whose login belongs to another
            account is refused (`email_in_use_elsewhere`); the login of someone
            removed from your account earlier is reused (see
            `existing_account`).
        mobile_number:
          type: string
          description: >-
            E.164. Their phone rings first on a human call, so Vacademy Voice
            and Exotel need it (a warning says so when it is missing). Ignored
            for an existing account.
        airtel_extension:
          type: string
          maxLength: 32
          description: >-
            Their Airtel IQ extension, when your calling provider is Airtel.
            Unique in your account.
        send_welcome_email:
          type: boolean
          default: true
          description: >-
            Email a NEW account its login (username, password, dashboard link).
            Never sent to an existing account.
    CounsellorWrite:
      allOf:
        - $ref: '#/components/schemas/Counsellor'
        - type: object
          properties:
            created:
              type: boolean
              description: >-
                `true` when this request made the person a counsellor here;
                `false` when they already were (nothing changed).
            existing_account:
              type: boolean
              description: >-
                The email already had a login on the platform: it was reused,
                its name, mobile and password were not changed, and no email was
                sent.
            welcome_email_sent:
              type: boolean
            effects:
              type: object
              additionalProperties: true
              description: >-
                On deactivation / reactivation: what else changed (see the
                counsellors guide).
            warnings:
              type: array
              items:
                $ref: '#/components/schemas/Warning'
              description: >-
                Non-fatal notes about what was (not) done, e.g.
                `mobile_number_missing`.
            idempotent_replay:
              type: boolean
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable code. Branch on this, not on the message.
              example: invalid_request
            message:
              type: string
              description: A sentence you can log or show to an operator.
            request_id:
              type: string
              description: Quote this when you contact support.
            details:
              type: object
              additionalProperties: true
              description: >-
                Extra context, e.g. `errors: [{field, message}]` for validation
                errors or `call_id` for conflicts.
    Counsellor:
      type: object
      properties:
        id:
          type: string
          description: Use as `counsellor_id` on `POST /human-calls`.
        object:
          type: string
          const: counsellor
        name:
          type: string
        email:
          type:
            - string
            - 'null'
        roles:
          type: array
          items:
            type: string
          example:
            - COUNSELLOR
        can_call:
          type: boolean
          description: >-
            Whether this person can take a human call right now on your calling
            provider.
        blocked_reason:
          type:
            - string
            - 'null'
          description: >-
            Why `can_call` is false, e.g. no mobile number on their profile
            (Vacademy Voice, Exotel) or no Airtel extension mapped.
        status:
          type: string
          enum:
            - active
            - invited
            - inactive
          description: >-
            `inactive` after `DELETE /counsellors/{id}` (deactivated); `GET
            /counsellors` lists active ones only.
        mobile_number:
          type:
            - string
            - 'null'
          description: >-
            Only on `GET /counsellors/{id}` (and write responses) for keys with
            `counsellors:manage`, and `null` when the login also belongs to
            another account (`shared_account`). Digits with the country code, as
            stored on the profile.
          example: '919876543210'
        airtel_extension:
          type:
            - string
            - 'null'
          description: >-
            Only on single-counsellor responses, for keys with
            `counsellors:manage`.
        manageable:
          type: boolean
          description: >-
            Only for `counsellors:manage` keys: whether the API may change this
            person (their roles here are counsellor roles only). Admins and
            other staff are `false`.
        shared_account:
          type: boolean
          description: >-
            Only for `counsellors:manage` keys: the login also belongs to
            another account on the platform, so its name and mobile number
            cannot be changed through the API.
    Warning:
      type: object
      description: >-
        Something in the request that was accepted but may not do what you
        expect.
      properties:
        field:
          type: string
          example: variables.date
        code:
          type: string
          enum:
            - reserved_variable
        message:
          type: string
          example: >-
            {{date}} in the agent's script is always filled with the current
            date and time; this value does not replace it. The agent receives it
            only as information about the contact.
  headers:
    RequestId:
      schema:
        type: string
      description: Unique id of this request. Quote it to support.
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        Your AI calling API key (`vak_call_…`). `Authorization: Bearer <key>`
        also works.

````

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