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

# Identify User

> Creates or updates a user identity with custom properties and aliases.

## User Identity

User identities store custom properties about your users (email, name, plan, etc.)
and allow you to track events by user ID.

## Aliases

Aliases let you reference the same user by multiple identifiers:
- Email addresses
- Usernames
- External system IDs
- Social media handles

## Idempotency

User identity creation is naturally idempotent. Calling identify multiple times
for the same userId will update the properties without creating duplicates.

## Property Merging

Properties are **replaced** on each identify call, not merged. Include all
properties you want to keep.




## OpenAPI

````yaml api-reference/openapi.json post /v1/identify
openapi: 3.1.0
info:
  title: EmitKit API
  version: 1.0.0
  description: >
    Real-time event tracking and notifications API for modern applications.


    ## Authentication


    All API requests require authentication using an API key in the
    Authorization header:

    ```

    Authorization: Bearer emitkit_xxxxxxxxxxxxxxxxxxxxx

    ```


    API keys are scoped to organizations and projects. Create API keys in your
    dashboard.


    ## Rate Limiting


    - Default: 100 requests per minute per API key

    - Rate limit information is returned in response headers:
      - `X-RateLimit-Limit`: Maximum requests allowed
      - `X-RateLimit-Remaining`: Remaining requests in current window
      - `X-RateLimit-Reset`: Unix timestamp when limit resets

    ## Idempotency


    To safely retry requests without creating duplicates, include an
    `Idempotency-Key` header:

    ```

    Idempotency-Key: payment-123-retry-1

    ```


    Idempotency keys are valid for 24 hours. Replayed requests return the
    original response with an `X-Idempotent-Replay: true` header.


    ## Request IDs


    Every response includes a `requestId` field for debugging and support
    purposes.
  contact:
    name: EmitKit Support
    url: https://emitkit.com/support
    email: hey@emitkit.com
  license:
    name: AGPL-3.0
    url: https://www.gnu.org/licenses/agpl-3.0.en.html
servers:
  - url: https://api.emitkit.com
    description: Production API
  - url: http://localhost:5173/api
    description: Local Development
security:
  - bearerAuth: []
tags:
  - name: Events
    description: Create and manage events
  - name: Identity
    description: Track user identities and aliases
  - name: Meta
    description: API metadata and health checks
paths:
  /v1/identify:
    post:
      tags:
        - Identity
      summary: Identify User
      description: >
        Creates or updates a user identity with custom properties and aliases.


        ## User Identity


        User identities store custom properties about your users (email, name,
        plan, etc.)

        and allow you to track events by user ID.


        ## Aliases


        Aliases let you reference the same user by multiple identifiers:

        - Email addresses

        - Usernames

        - External system IDs

        - Social media handles


        ## Idempotency


        User identity creation is naturally idempotent. Calling identify
        multiple times

        for the same userId will update the properties without creating
        duplicates.


        ## Property Merging


        Properties are **replaced** on each identify call, not merged. Include
        all

        properties you want to keep.
      operationId: identifyUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IdentifyUserRequest'
            examples:
              basic:
                summary: Basic user identification
                value:
                  user_id: user_123
                  properties:
                    email: john@example.com
                    name: John Doe
                    plan: pro
              withAliases:
                summary: User with multiple aliases
                value:
                  user_id: user_456
                  properties:
                    email: jane@example.com
                    name: Jane Smith
                    plan: free
                    signupDate: '2025-01-15'
                  aliases:
                    - jane@example.com
                    - janesmith
                    - jane.smith@company.com
              updateProperties:
                summary: Update user properties
                value:
                  user_id: user_123
                  properties:
                    plan: enterprise
                    seats: 50
                    upgradeDate: '2025-01-20'
      responses:
        '200':
          description: User identified successfully (created or updated)
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum requests allowed in the current time window
              example: 100
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Remaining requests in current window
              example: 95
            X-RateLimit-Reset:
              schema:
                type: integer
                format: int64
              description: Unix timestamp (seconds) when the rate limit resets
              example: 1733270400
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdentifyUserResponse'
              examples:
                success:
                  summary: Successful identification
                  value:
                    success: true
                    data:
                      id: user_identity_xxxxxxxxxxxxxxxxxxxxx
                      userId: user_123
                      properties:
                        email: john@example.com
                        name: John Doe
                        plan: pro
                      aliases:
                        created:
                          - john@example.com
                          - johndoe
                      updatedAt: '2025-01-15T10:30:00.000Z'
                    requestId: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                partialAliasFailure:
                  summary: Some aliases failed (duplicate)
                  value:
                    success: true
                    data:
                      id: user_identity_xxxxxxxxxxxxxxxxxxxxx
                      userId: user_456
                      properties:
                        email: jane@example.com
                        name: Jane Smith
                      aliases:
                        created:
                          - janesmith
                        failed:
                          - alias: jane@example.com
                            reason: Alias already exists
                      updatedAt: '2025-01-15T10:31:00.000Z'
                    requestId: b2c3d4e5-f6a7-8901-bcde-f12345678901
        '400':
          description: >-
            Validation error - request body is malformed or missing required
            fields
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
            X-RateLimit-Remaining:
              schema:
                type: integer
            X-RateLimit-Reset:
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
              examples:
                missingUserId:
                  summary: Missing user_id
                  value:
                    success: false
                    error: Validation error
                    details:
                      - path:
                          - user_id
                        message: User ID is required
                    requestId: a1b2c3d4-e5f6-7890-abcd-ef1234567890
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '429':
          description: Rate limit exceeded
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
            X-RateLimit-Remaining:
              schema:
                type: integer
                enum:
                  - 0
            X-RateLimit-Reset:
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
        '500':
          description: Internal server error
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
            X-RateLimit-Remaining:
              schema:
                type: integer
            X-RateLimit-Reset:
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerError'
      x-codeSamples:
        - lang: javascript
          label: Identify User
          source: |-
            import { EmitKit } from '@emitkit/js';
            const client = new EmitKit('emitkit_xxxxxxxxxxxxxxxxxxxxx');

            await client.identify({
              user_id: 'user_123',
              properties: {
                email: 'john@example.com',
                name: 'John Doe',
                plan: 'pro'
              },
              aliases: ['john@example.com', 'johndoe']
            });
        - lang: javascript
          label: Update Properties
          source: |-
            import { EmitKit } from '@emitkit/js';
            const client = new EmitKit('emitkit_xxxxxxxxxxxxxxxxxxxxx');

            // Properties are replaced, not merged
            await client.identify({
              user_id: 'user_123',
              properties: {
                email: 'john@example.com',
                plan: 'enterprise',
                seats: 50,
                upgradeDate: '2025-01-20'
              }
            });
        - lang: javascript
          label: Use Aliases in Events
          source: |-
            import { EmitKit } from '@emitkit/js';
            const client = new EmitKit('emitkit_xxxxxxxxxxxxxxxxxxxxx');

            // First, create aliases
            await client.identify({
              user_id: 'user_123',
              properties: { email: 'john@example.com' },
              aliases: ['john@example.com', 'johndoe']
            });

            // Then use aliases in events - automatically resolved!
            await client.events.create({
              channelName: 'user-activity',
              title: 'User Logged In',
              userId: 'john@example.com',  // ← Alias works!
              metadata: { ip: '192.168.1.1' }
            });
        - lang: bash
          label: cURL
          source: |-
            curl -X POST https://api.emitkit.com/v1/identify \
              -H "Authorization: Bearer emitkit_xxxxxxxxxxxxxxxxxxxxx" \
              -H "Content-Type: application/json" \
              -d '{
                "user_id": "user_123",
                "properties": {
                  "email": "john@example.com",
                  "name": "John Doe",
                  "plan": "pro"
                },
                "aliases": [
                  "john@example.com",
                  "johndoe"
                ]
              }'
components:
  schemas:
    IdentifyUserRequest:
      type: object
      required:
        - user_id
      properties:
        user_id:
          type: string
          minLength: 1
          maxLength: 255
          description: |
            Unique identifier for the user. This is your internal user ID.
            Must be consistent across identify calls for the same user.
          example: user_123
        properties:
          type: object
          additionalProperties: true
          description: >
            Custom properties about the user. Any valid JSON structure is
            accepted.

            Properties are **replaced** on each identify call, not merged.

            Common properties: email, name, plan, createdAt, etc.
          example:
            email: john@example.com
            name: John Doe
            plan: pro
            signupDate: '2025-01-15'
        aliases:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 255
          maxItems: 50
          description: >
            Array of alternative identifiers for this user (emails, usernames,
            external IDs).

            Aliases allow you to reference users by multiple identifiers in your
            events.

            Duplicate aliases are silently ignored and returned in the response.
          example:
            - john@example.com
            - johndoe
            - john.doe@company.com
    IdentifyUserResponse:
      type: object
      required:
        - success
        - data
        - requestId
      properties:
        success:
          type: boolean
          description: Indicates successful user identification
          example: true
        data:
          type: object
          required:
            - id
            - userId
            - properties
            - aliases
            - updatedAt
          properties:
            id:
              type: string
              description: Unique identifier for this user identity record
              example: user_identity_xxxxxxxxxxxxxxxxxxxxx
            userId:
              type: string
              description: The user ID that was identified
              example: user_123
            properties:
              type: object
              additionalProperties: true
              description: User properties that were stored
              example:
                email: john@example.com
                name: John Doe
                plan: pro
            aliases:
              type: object
              required:
                - created
              properties:
                created:
                  type: array
                  items:
                    type: string
                  description: Aliases that were successfully created
                  example:
                    - john@example.com
                    - johndoe
                failed:
                  type: array
                  items:
                    type: object
                    required:
                      - alias
                      - reason
                    properties:
                      alias:
                        type: string
                        description: The alias that failed to be created
                      reason:
                        type: string
                        description: Why the alias creation failed
                  description: >-
                    Aliases that failed to be created (only present if there
                    were failures)
                  example:
                    - alias: duplicate@example.com
                      reason: Alias already exists
            updatedAt:
              type: string
              format: date-time
              description: ISO 8601 timestamp of when the identity was last updated
              example: '2025-01-15T10:30:00.000Z'
        requestId:
          type: string
          format: uuid
          description: Unique request identifier for debugging and support
          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
    ValidationError:
      type: object
      required:
        - success
        - error
        - requestId
      properties:
        success:
          type: boolean
          description: Always false for error responses
          example: false
        error:
          type: string
          description: Error type
          example: Validation error
        details:
          type: array
          description: Array of validation errors with paths and messages
          items:
            type: object
            required:
              - path
              - message
            properties:
              path:
                type: array
                items:
                  type: string
                description: Path to the invalid field
                example:
                  - channelName
              message:
                type: string
                description: Validation error message
                example: Required
              code:
                type: string
                description: Error code for programmatic handling
        requestId:
          type: string
          format: uuid
          description: Unique request identifier
    UnauthorizedError:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: Error type
          example: Unauthorized
        message:
          type: string
          description: Human-readable error message
          example: Invalid or missing authentication credentials
    RateLimitError:
      type: object
      required:
        - success
        - error
        - requestId
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          example: Rate limit exceeded
        message:
          type: string
          example: Too many requests. Please try again later.
        requestId:
          type: string
          format: uuid
    ServerError:
      type: object
      required:
        - success
        - error
        - requestId
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: Error message
          example: Failed to create event
        requestId:
          type: string
          format: uuid
          description: Request ID for support reference
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: |
        API key authentication. Format: `emitkit_xxxxxxxxxxxxxxxxxxxxx`

        Create API keys in your EmitKit dashboard. Keys are scoped to a specific
        organization and project.

````