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

# Create Contact

> Create a new contact or update existing one if matched by email/phone.

**Deduplication:** Automatically matches by email (exact) or phone (normalized).

**Name Parsing:** If only `firstName` is provided with multiple words, automatically splits into first/last name.




## OpenAPI

````yaml POST /v1/people
openapi: 3.0.3
info:
  title: v1.0
  description: >
    ## Authentication


    All API requests require authentication via API key in the `Authorization`
    header with Bearer scheme:


    ```bash

    curl -H "Authorization: Bearer your_api_key_here"
    https://api.clientcommander.com/v1/people

    ```


    Generate API keys from **Settings > API Keys** in your Client Commander
    dashboard.


    ## Rate Limiting


    API requests are rate-limited to ensure system stability:


    - **Rate Limit:** 1000 requests per hour per API key

    - **Headers:** Every response includes rate limit information


    ```

    X-RateLimit-Limit: 1000

    X-RateLimit-Remaining: 999

    X-RateLimit-Reset: 1640995200

    ```


    When rate limit is exceeded, you'll receive a `429 Too Many Requests`
    response with a `Retry-After` header.


    ## Pagination


    List endpoints support pagination with consistent parameters:


    - `limit`: Number of items per page (default: 10, max: 100)

    - `cursor`: Opaque cursor for next page (returned in response)


    Response includes pagination metadata:


    ```json

    {
      "data": [...],
      "meta": {
        "count": 10,
        "hasMore": true,
        "nextCursor": "eyJpZCI6IjEyMyJ9"
      }
    }

    ```


    ## Error Handling


    Errors follow a consistent structure with machine-readable codes:


    ```json

    {
      "error": {
        "code": "VALIDATION_ERROR",
        "message": "Invalid email address",
        "details": [
          {
            "field": "email",
            "message": "Must be a valid email address",
            "code": "INVALID_FORMAT"
          }
        ],
        "requestId": "req_abc123",
        "timestamp": "2023-11-15T10:00:00Z"
      }
    }

    ```



    ## Idempotency


    POST and PUT requests support idempotency via the `Idempotency-Key` header:


    ```bash

    curl -X POST -H "Idempotency-Key: unique-key-123" ...

    ```


    ## Versioning


    - **Current Version:** v1

    - **Version Header:** `X-API-Version: 1` (optional)

    - **Deprecation Policy:** 12 months notice before sunset


    ## Support


    - **Documentation:** https://docs.clientcommander.com

    - **Status Page:** https://status.clientcommander.com

    - **Support:** support@clientcommander.me
  version: 1.0.0
  contact:
    name: Client Commander API Support
    email: api@clientcommander.me
    url: https://clientcommander.com/support
  license:
    name: Proprietary
    url: https://clientcommander.com/terms
servers:
  - url: https://api.clientcommander.com
    description: Production API
    variables: {}
security:
  - Authentication: []
tags:
  - name: People
    description: >
      Contact management endpoints. Create, read, update, and delete contacts
      with rich profile data including emails, phones, addresses, custom fields,
      and lifecycle stages.


      **Permissions:** Requires `people.view.*` and `people.edit.*` scopes based
      on operation.
  - name: Tasks
    description: >
      Task management for contact follow-ups and to-dos. Supports due dates,
      priorities, and assignment to team members.


      **Permissions:** Requires `tasks.manage` scope.
  - name: Deals
    description: >
      Deal pipeline management with customizable stages. Track opportunities,
      revenue, and close dates.


      **Permissions:** Requires `deals.view.*` and `deals.manage` scopes.
  - name: Appointments
    description: >
      Calendar and appointment scheduling. Supports recurring appointments,
      timezones, and guest management.


      **Permissions:** Requires `appointments.manage` scope.
  - name: Activities
    description: >
      Activity logging and interaction history. Track calls, emails, meetings,
      and custom activities.


      **Permissions:** Requires `activities.view` and `activities.create`
      scopes.
  - name: Tags
    description: |
      Tag management for contact categorization and segmentation.

      **Permissions:** Requires `tags.manage` scope.
  - name: Stages
    description: |
      Contact lifecycle stage management (Lead, Prospect, Client, etc.).

      **Permissions:** Requires `stages.manage` scope (Owner/Admin only).
  - name: Pipelines
    description: |
      Deal pipeline configuration and stage management.

      **Permissions:** Requires `pipelines.manage` scope.
  - name: Users
    description: |
      User and agent information endpoints.

      **Permissions:** Requires `users.view` scope.
  - name: Teams
    description: |
      Team and member management.

      **Permissions:** Requires `teams.manage` scope.
  - name: Smart Lists
    description: |
      Dynamic contact segmentation with advanced filtering.

      **Permissions:** Requires `smartlists.manage` scope.
paths:
  /v1/people:
    post:
      tags:
        - People
      summary: Create or update contact
      description: >
        Create a new contact or update existing one if matched by email/phone.


        **Deduplication:** Automatically matches by email (exact) or phone
        (normalized).


        **Name Parsing:** If only `firstName` is provided with multiple words,
        automatically splits into first/last name.
      operationId: createOrUpdatePerson
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyParam'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactInput'
            examples:
              createContact:
                $ref: '#/components/examples/CreateContactRequest'
      responses:
        '201':
          description: Contact created or updated successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          created:
                            type: boolean
                            description: True if new contact, false if updated existing
                          id:
                            type: string
                          person:
                            $ref: '#/components/schemas/Contact'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
      security:
        - Authentication:
            - people.create
            - people.edit
components:
  parameters:
    IdempotencyKeyParam:
      name: Idempotency-Key
      in: header
      description: Unique key for idempotent requests
      schema:
        type: string
        minLength: 16
        maxLength: 64
      example: unique-key-abc123
  schemas:
    ContactInput:
      type: object
      properties:
        firstName:
          type: string
          minLength: 1
          maxLength: 100
        lastName:
          type: string
          minLength: 1
          maxLength: 100
        email:
          type: string
          format: email
          maxLength: 255
        phone:
          type: string
          pattern: ^\+?[1-9]\d{1,14}$
        source:
          type: string
          maxLength: 100
        stage:
          type: string
          description: Stage ID
        price:
          type: number
          format: double
          minimum: 0
        timeframe:
          type: string
          maxLength: 100
        background:
          type: string
          maxLength: 5000
        tags:
          type: array
          maxItems: 20
          items:
            type: string
            minLength: 1
            maxLength: 50
        street:
          type: string
          maxLength: 200
        city:
          type: string
          maxLength: 100
        state:
          type: string
          maxLength: 2
          pattern: ^[A-Z]{2}$
        zipCode:
          type: string
          pattern: ^\d{5}(-\d{4})?$
    SuccessResponse:
      type: object
      required:
        - meta
      properties:
        meta:
          type: object
          required:
            - requestId
            - timestamp
          properties:
            requestId:
              type: string
              format: uuid
              description: Unique request ID for tracing
            timestamp:
              type: string
              format: date-time
              description: Response timestamp
            version:
              type: string
              default: 1.0.0
    Contact:
      type: object
      required:
        - id
        - firstName
        - lastName
        - fullName
        - createdAt
      properties:
        id:
          type: string
          description: Unique contact identifier
          example: jd79abc123def
        firstName:
          type: string
          minLength: 1
          maxLength: 100
          example: John
        lastName:
          type: string
          minLength: 1
          maxLength: 100
          example: Doe
        fullName:
          type: string
          description: Auto-generated from first + last name
          example: John Doe
        emails:
          type: array
          items:
            type: object
            required:
              - value
            properties:
              value:
                type: string
                format: email
                example: john@example.com
              type:
                type: string
                default: home
                example: work
              isPrimary:
                type: boolean
                default: false
        phones:
          type: array
          items:
            type: object
            required:
              - value
            properties:
              value:
                type: string
                pattern: ^\+?[1-9]\d{1,14}$
                example: '+15551234567'
              type:
                type: string
                default: mobile
                example: mobile
              status:
                type: string
                enum:
                  - Valid
                  - Invalid
                default: Valid
              isPrimary:
                type: boolean
              isBad:
                type: boolean
                description: Marked as invalid/bounced
        assignedAgentId:
          type: string
          nullable: true
          description: ID of assigned agent
        assignedAgentName:
          type: string
          nullable: true
          example: Jane Smith
        assignedAgentEmail:
          type: string
          format: email
          nullable: true
        stageId:
          type: string
          nullable: true
          description: Current lifecycle stage ID
        stageName:
          type: string
          nullable: true
          example: Lead
        source:
          type: string
          nullable: true
          maxLength: 100
          example: Website Signup
        tags:
          type: string
          description: Comma-separated list of tags
          example: VIP, Hot Lead, Referral
          nullable: true
        price:
          type: number
          format: double
          nullable: true
          minimum: 0
          description: Budget or property price
          example: 450000
        timeframe:
          type: string
          nullable: true
          description: Buying/selling timeframe
          example: 3-6 months
        background:
          type: string
          nullable: true
          maxLength: 5000
          description: Notes about the contact
        relationship:
          type: boolean
          default: false
          description: Whether this is a relationship contact
        createdAt:
          type: string
          format: date-time
          example: '2023-11-15T10:00:00Z'
        updatedAt:
          type: string
          format: date-time
          nullable: true
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code
              enum:
                - UNAUTHORIZED
                - FORBIDDEN
                - NOT_FOUND
                - VALIDATION_ERROR
                - RATE_LIMIT_EXCEEDED
                - INTERNAL_ERROR
                - BAD_REQUEST
                - CONFLICT
              example: VALIDATION_ERROR
            message:
              type: string
              description: Human-readable error message
              example: Invalid email address format
            details:
              type: array
              description: Field-level validation errors
              items:
                type: object
                properties:
                  field:
                    type: string
                    example: email
                  message:
                    type: string
                    example: Must be a valid email address
                  code:
                    type: string
                    example: INVALID_FORMAT
            requestId:
              type: string
              format: uuid
              description: Request ID for support
            timestamp:
              type: string
              format: date-time
            retryAfter:
              type: integer
              description: Seconds to wait before retry (for rate limits)
  examples:
    CreateContactRequest:
      summary: Create a new contact
      value:
        firstName: John
        lastName: Doe
        email: john@example.com
        phone: '+15551234567'
        source: Website Signup
        tags:
          - VIP
          - Hot Lead
        price: 450000
        timeframe: 3-6 months
        background: Interested in downtown properties
  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            badRequest:
              value:
                error:
                  code: BAD_REQUEST
                  message: Missing required parameter
                  details:
                    - field: personId
                      message: Required field is missing
                      code: REQUIRED_FIELD
                  requestId: 123e4567-e89b-12d3-a456-426614174000
                  timestamp: '2023-11-15T10:00:00Z'
    Unauthorized:
      description: Missing or invalid API key
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalidApiKey:
              value:
                error:
                  code: UNAUTHORIZED
                  message: Invalid or missing API key
                  requestId: 123e4567-e89b-12d3-a456-426614174000
                  timestamp: '2023-11-15T10:00:00Z'
    Forbidden:
      description: Insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            forbidden:
              value:
                error:
                  code: FORBIDDEN
                  message: You do not have permission to access this resource
                  requestId: 123e4567-e89b-12d3-a456-426614174000
                  timestamp: '2023-11-15T10:00:00Z'
    ValidationError:
      description: Request validation failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            validationError:
              value:
                error:
                  code: VALIDATION_ERROR
                  message: Validation failed
                  details:
                    - field: email
                      message: Must be a valid email address
                      code: INVALID_FORMAT
                    - field: phone
                      message: Phone number is required
                      code: REQUIRED_FIELD
                  requestId: 123e4567-e89b-12d3-a456-426614174000
                  timestamp: '2023-11-15T10:00:00Z'
    RateLimitExceeded:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          schema:
            type: integer
            example: 0
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        Retry-After:
          description: Seconds to wait before retry
          schema:
            type: integer
            example: 60
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            rateLimitExceeded:
              value:
                error:
                  code: RATE_LIMIT_EXCEEDED
                  message: Rate limit exceeded. Please retry after 60 seconds.
                  retryAfter: 60
                  requestId: 123e4567-e89b-12d3-a456-426614174000
                  timestamp: '2023-11-15T10:00:00Z'
  headers:
    X-Request-Id:
      description: Unique request identifier for support/debugging
      schema:
        type: string
        format: uuid
        example: 123e4567-e89b-12d3-a456-426614174000
    X-RateLimit-Limit:
      description: Maximum requests per hour
      schema:
        type: integer
        example: 1000
    X-RateLimit-Reset:
      description: Unix timestamp when rate limit resets
      schema:
        type: integer
        example: 1640995200
  securitySchemes:
    Authentication:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: |
        API key for authentication using Bearer token scheme.

        **How to get your API key:**
        1. Log into Client Commander
        2. Go to **Admin > API Keys**
        3. Click **Create API Key**
        4. Copy the key and use it in the Authorization header:

        ```
        Authorization: Bearer ccmd_live_your_key_here
        ```

````