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

# Authenticate a widget user by your own user id

> Get a verified widget contact token for a user identified by your own user ID. Use when several of your users can share an email or phone, or when users can change them.

Call this endpoint from your backend with an API key that has the `widget:write` scope. It returns the same verified token as [Authenticate contact](/api-reference/widget/authenticate-contact). Pass that token to the widget through `user.token`.

* **Matching:** the contact is found by `external_id` alone. Email and phone are optional details on the contact: they can change, and several contacts can share them.
* **First call:** a new contact is created with the `external_id` and the details you send, even when another contact already has the same email or phone.
* **Later calls:** the contact with that `external_id` is updated with the details you send, such as a new email or phone.
* **Other ways in:** email, phone, and messaging channels, and [Authenticate contact](/api-reference/widget/authenticate-contact), keep identifying people by email or phone. They never match a contact that has an `external_id`, so a message from the same address belongs to a separate contact.
* **Validation:** `external_id` is required, can't be blank, and is at most 255 characters.

The other fields match [Authenticate contact](/api-reference/widget/authenticate-contact), including `http_action_overrides` for your AI actions and `mcp_access` for personal connections.

`external_id` identifies the contact. It is different from the widget's `user.externalId` option, which only scopes session history in the browser.


## OpenAPI

````yaml post /widget/authenticate-user-by-external-id
openapi: 3.1.0
info:
  title: OpenCX API
  description: >

    OpenCX is an AI-powered, all-in-one platform for customer support and
    outbound communications.


    Use this API to manage your OpenCX organization's AI agents, actions,
    conversations, contacts, and more.


    To get started, generate a new API key from the dashboard.


    ## Authentication

    All API endpoints require authentication using a Bearer token. You can
    generate an API key from your OpenCX dashboard.


    ## Rate Limiting

    API requests are rate limited to ensure fair usage. The current limits are:

    - 100 requests per minute for standard endpoints

    - 1000 requests per minute for streaming endpoints


    ## Error Handling

    The API uses standard HTTP status codes and returns detailed error messages
    in the response body.
  version: 1.0-beta
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
servers:
  - url: http://localhost:8080
    description: Development
  - url: https://api.open.cx
    description: Production
security:
  - bearerAuth: []
paths:
  /widget/authenticate-user-by-external-id:
    post:
      summary: Authenticate a widget user by your own user id
      description: >-
        Returns a token for the contact with this external_id, creating the
        contact when none exists and otherwise updating it with the fields sent.
        The contact is matched by external_id alone: email and phone are
        optional, can change, and can be shared with other contacts. Channels
        that identify people by email or phone, such as inbound email, keep
        their own contacts and never resolve to this one.
      operationId: authenticateWidgetUserByExternalId
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AuthenticateUserByExternalIdPayloadDto'
      responses:
        '201':
          description: Default Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerifiedWidgetContactTokenResponseDto'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorDto'
components:
  schemas:
    AuthenticateUserByExternalIdPayloadDto:
      $schema: https://json-schema.org/draft/2020-12/schema
      $id: '#/components/schemas/AuthenticateUserByExternalIdPayloadDtoInput'
      type: object
      properties:
        email:
          type: string
          format: email
          pattern: >-
            ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
        mcp_access:
          type: object
          properties:
            server_ids:
              maxItems: 50
              type: array
              items:
                type: string
                format: uuid
                pattern: >-
                  ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            account_id:
              type: string
              minLength: 1
              maxLength: 200
        name:
          type: string
        avatar_url:
          anyOf:
            - type: string
            - type: 'null'
        phone:
          type: string
        language:
          $ref: '#/components/schemas/LanguageIsoCodeValues'
        customData:
          type: object
          propertyNames:
            type: string
          additionalProperties:
            anyOf:
              - type: string
              - type: number
              - type: boolean
        chat_context:
          type: string
        http_action_overrides:
          $ref: '#/components/schemas/PublicAPIHttpOverrides'
        external_id:
          type: string
          minLength: 1
          maxLength: 255
          description: >-
            The user's stable id in your system. The contact is matched by this
            id alone, so email and phone can change or be shared with other
            contacts.
      required:
        - external_id
    VerifiedWidgetContactTokenResponseDto:
      $schema: https://json-schema.org/draft/2020-12/schema
      $id: '#/components/schemas/VerifiedWidgetContactTokenResponseDto'
      type: object
      properties:
        token:
          type: string
          description: The JWT token to use for further requests
        contact:
          type: object
          properties:
            id:
              type: string
          required:
            - id
          additionalProperties: false
      required:
        - token
        - contact
      additionalProperties: false
    ErrorDto:
      type: object
      properties:
        statusCode:
          type: integer
        message:
          type: string
        error:
          type: string
    LanguageIsoCodeValues:
      $schema: https://json-schema.org/draft/2020-12/schema
      $id: '#/components/schemas/LanguageIsoCodeValuesInput'
      type: string
      enum:
        - en
        - fr
        - de
        - nl
        - pl
        - pt
        - es
        - it
        - ru
        - ja
        - ko
        - zh
        - ar
        - tr
        - sv
        - da
        - 'no'
        - fi
        - el
        - cs
        - hu
        - th
        - vi
        - id
        - he
        - hi
        - uk
        - ro
        - bg
        - hr
        - sk
        - sl
        - sr
        - et
        - lv
        - lt
        - is
        - ga
        - ms
        - tl
        - fa
        - bn
        - ta
        - te
        - ur
        - sw
        - zu
        - af
        - sq
        - hy
        - az
        - eu
        - be
        - bs
        - ca
        - cy
        - ku
        - ckb
        - kmr
    PublicAPIHttpOverrides:
      $schema: https://json-schema.org/draft/2020-12/schema
      $id: '#/components/schemas/PublicAPIHttpOverridesInput'
      type: object
      properties:
        query_params:
          type: object
          propertyNames:
            type: string
          additionalProperties:
            type: string
        path_params:
          type: object
          propertyNames:
            type: string
          additionalProperties:
            type: string
        body_params:
          type: object
          propertyNames:
            type: string
          additionalProperties:
            type: string
        headers:
          type: object
          propertyNames:
            type: string
          additionalProperties:
            type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````

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