# Create or update a contact

Create a new contact in a list, or update an existing one if found. The contact is identified by linkedin_id. If the contact already exists and update_if_exists is true, their data will be updated. Optionally move the contact to the specified list with move_to_list.

Tip: Unlike PUT /leads/api/leads/{uuid}, this endpoint accepts custom_fields so you can set standard and custom fields in a single request.

Endpoint: POST /leads/api/leads/upsert
Version: 2.0.0
Security: bearerAuth

## Request fields (application/json):

  - `lead` (object, required)

  - `lead.linkedin_id` (string, required)
    LinkedIn profile URL or member ID.
    Example: "john-doe-123456"

  - `lead.first_name` (string)
    Example: "John"

  - `lead.last_name` (string)
    Example: "Doe"

  - `lead.company_name` (string)
    Example: "Acme Inc"

  - `lead.ln_id` (string,null)

  - `lead.sn_id` (string,null)

  - `lead.linkedin` (string,null)

  - `lead.email` (string)
    Example: "john@acme.com"

  - `lead.about` (string)

  - `lead.domain` (string)
    Company domain for email discovery.
    Example: "acme.com"

  - `lead.headline` (string,null)

  - `lead.position` (string,null)

  - `lead.raw_address` (string,null)

  - `custom_fields` (object)
    Custom field values as key-value pairs.
    Example: {"field_position":"CTO","field_experience":"10 years"}

  - `list_uuid` (string, required)
    Target list UUID.
    Example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

  - `update_if_exists` (boolean)
    Update the contact if it already exists.

  - `move_to_list` (boolean)
    Move existing contact to the specified list.

## Response 200 fields (application/json):

  - `uuid` (string)
    Example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

  - `team_id` (integer)

  - `user_id` (integer,null)

  - `sender_profile_uuid` (string,null)

  - `list_uuid` (string)

  - `data_source_uuid` (string,null)

  - `pipeline_stage_uuid` (string)

  - `company_uuid` (string,null)

  - `name` (string,null)
    Example: "John Doe"

  - `first_name` (string,null)
    Example: "John"

  - `last_name` (string,null)
    Example: "Doe"

  - `company_name` (string,null)
    Example: "Acme Inc"

  - `company_ln_id` (string,null)

  - `position` (string,null)
    Example: "VP of Sales"

  - `headline` (string,null)
    Example: "VP of Sales at Acme Inc"

  - `about` (string,null)

  - `avatar_url` (string,null)

  - `ln_id` (string,null)
    LinkedIn member ID.

  - `sn_id` (string,null)
    Sales Navigator ID.

  - `linkedin` (string,null)
    Example: "john-doe-123456"

  - `facebook` (string,null)

  - `twitter` (string,null)

  - `work_email` (string,null)
    Example: "john@acme.com"

  - `personal_email` (string,null)

  - `work_phone_number` (string,null)

  - `personal_phone_number` (string,null)

  - `connections_number` (integer,null)

  - `followers_number` (integer,null)

  - `primary_language` (string,null)

  - `supported_languages` (array,null)

  - `has_open_profile` (integer,null)

  - `has_verified_profile` (integer,null)

  - `has_premium` (integer,null)

  - `experience` (array,null)

  - `experience.title` (string)

  - `experience.company` (string)

  - `experience.start_date` (string)

  - `experience.end_date` (string)

  - `posts` (array,null)

  - `posts.content` (string)

  - `posts.date` (string)

  - `educations` (array,null)

  - `educations.school` (string)

  - `educations.degree` (string)

  - `educations.field_of_study` (string)

  - `educations.start_year` (string)

  - `educations.end_year` (string)

  - `skills` (array,null)

  - `raw_address` (string,null)
    Example: "San Francisco, CA, USA"

  - `location` (array,null)

  - `location.address_string` (string)

  - `tags` (array,null)
    Tag UUIDs.

  - `status` (string)
    Example: "ok"

  - `linkedin_status` (string)
    Example: "active"

  - `email_status` (string,null)

  - `unread_counts` (array)

  - `unread_counts.category` (string)

  - `unread_counts.count` (integer)

  - `last_automation_approve_at` (string,null)

  - `created_at` (string,null)

  - `updated_at` (string,null)

## Response 422 fields (application/json):

  - `error` (object)

  - `error.reason` (string)
    Machine-readable error code: validation_error, bad_request, auth_exception, access_denied, payment_required.
    Example: "validation_error"

  - `error.message` (string)
    Example: "The name field is required."

  - `error.data` (object)
    Field-level validation errors (field name → messages).

  - `message` (string)
    Example: "The given data was invalid."

  - `code` (integer)
    Example: 422


