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

# Enrich a lead profile

> Look up a single person and get their profile and current company.

<Note>
  **This endpoint is synchronous. It costs 0.1 credit per profile found**, and nothing when no
  profile matches.

  There is no `request_id` and nothing to poll: the profile comes back in the same response. Expect
  a couple of seconds.
</Note>

<Warning>
  This endpoint returns **profile data only**. It never returns an email address or a phone number.
  For contact data, use [Enrich leads](/api-reference/endpoint/create).
</Warning>

## Identifying the lead

There are two ways in, and they are not equivalent.

<CardGroup cols={2}>
  <Card title="By LinkedIn URL" icon="linkedin" iconType="solid">
    Send `linkedin_url` alone. This is the most reliable form and the one to prefer whenever you have
    the URL.
  </Card>

  <Card title="By name and company" icon="user-magnifying-glass" iconType="solid">
    Send `first_name`, `last_name` and `company_domain` together. All three are required.
  </Card>
</CardGroup>

<Warning>
  **`company_domain` is required in the second form, a company name is not enough.** Sending
  `first_name` + `last_name` + `company` without `company_domain` is rejected with `422`. You can
  send `company` in addition to `company_domain`, but never instead of it.
</Warning>

When `linkedin_url` is present the other attributes are ignored.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.bettercontact.rocks/api/v2/enrich_profile/lead \
    -H "X-API-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "linkedin_url": "https://www.linkedin.com/in/veronick-martinuzzi-a4533373" }'
  ```

  ```javascript Node.js theme={null}
  const res = await fetch(
    "https://app.bettercontact.rocks/api/v2/enrich_profile/lead",
    {
      method: "POST",
      headers: {
        "X-API-Key": process.env.BETTERCONTACT_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        linkedin_url: "https://www.linkedin.com/in/veronick-martinuzzi-a4533373",
      }),
    }
  );

  const { success, data } = await res.json();
  if (!success) throw new Error("Lookup failed");
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.post(
      "https://app.bettercontact.rocks/api/v2/enrich_profile/lead",
      headers={"X-API-Key": os.environ["BETTERCONTACT_API_KEY"]},
      json={"first_name": "Veronick", "last_name": "Martinuzzi", "company_domain": "hondaresearch.com"},
  )

  body = res.json()
  if not body["success"]:
      raise RuntimeError(body["error"])

  profile = body["data"]
  ```
</CodeGroup>

## Authentication

The key goes **either** in the `X-API-Key` header, like every other endpoint, **or** as an `api_key`
attribute in the body. The header is the recommended form: it keeps the key out of your request
payloads and out of your logs.

## What you get back

25 fields describing the person and their current company. Unlike the enrichment and Lead Finder
payloads, there are **no extra always-null legacy keys**: what you see is the whole response.

A few fields deserve a note:

| Field                                  | Note                                                                                                          |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `contact_linkedin_headline`            | Often an **empty string** rather than `null` when the profile has no headline.                                |
| `contact_location_continent` / `_city` | Frequently `null` even when country and state are filled. Do not assume the location block is all-or-nothing. |
| `company_headquarters_city`            | Can carry a full street address rather than a bare city name.                                                 |
| `company_employees_range_end`          | `null` on open ended ranges: a company in `10001+` has a start and no end.                                    |
| `company_keywords`                     | An array of strings, not a comma separated string.                                                            |
| `company_type`, `company_founded_year` | Frequently `null`.                                                                                            |

Values are capitalised on the way out, which is why a job title comes back as
`Development solutions sr. principal engineer` rather than in its original casing.


## OpenAPI

````yaml POST /enrich_profile/lead
openapi: 3.0.1
info:
  title: BetterContact API
  description: >-
    The official BetterContact API to find new leads and enrich them with
    verified work emails and mobile phone numbers.
  version: 2.0.0
  contact:
    name: BetterContact Support
    email: contact@bettercontact.rocks
    url: https://doc.bettercontact.rocks
servers:
  - url: https://app.bettercontact.rocks/api/v2
security:
  - apiKey: []
paths:
  /enrich_profile/lead:
    post:
      summary: Enrich a lead profile
      description: >-
        Look up a single person and get their profile plus their current
        company. This endpoint is **synchronous**: the profile comes back in the
        same response, there is no `request_id` to poll.


        **Cost: 0.1 credit per profile found.** Nothing is charged when no
        profile matches.


        It returns profile data only. It does **not** return an email address or
        a phone number: for that, use [Enrich
        leads](/api-reference/endpoint/create).


        Authentication accepts either the `X-API-Key` header like every other
        endpoint, or an `api_key` attribute in the request body.
      operationId: enrichLead
      requestBody:
        description: Lead to look up
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EnrichLeadRequest'
            examples:
              byLinkedin:
                summary: By LinkedIn URL (recommended)
                value:
                  linkedin_url: https://www.linkedin.com/in/veronick-martinuzzi-a4533373
              byNameAndDomain:
                summary: By name and company domain
                value:
                  first_name: Veronick
                  last_name: Martinuzzi
                  company_domain: hondaresearch.com
      responses:
        '200':
          description: Profile found.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/LeadProfile'
        '400':
          description: No request body was sent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              example:
                success: false
                error: Data parameter is required.
        '401':
          description: Unauthorized. The API key is missing, invalid or deactivated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '402':
          description: Not enough credits to run the lookup.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              example:
                success: false
                error: You do not have enough credits to perform a profile search.
        '404':
          description: No profile matched. Nothing is charged.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              example:
                success: false
                error: Profile was not found.
        '422':
          description: >-
            Neither `linkedin_url` nor the `first_name` + `last_name` +
            `company_domain` combination was provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              example:
                success: false
                error: >-
                  Linkedin url OR First_name, last_name, company and company
                  domain is missing
      security:
        - apiKey: []
components:
  schemas:
    EnrichLeadRequest:
      type: object
      description: >-
        Identify the lead in one of two ways:


        - **By LinkedIn URL**: send `linkedin_url` alone. This is the most
        reliable form.

        - **By name and company**: send `first_name`, `last_name` and
        `company_domain`.


        `linkedin_url` takes precedence: when it is present the other attributes
        are ignored.
      properties:
        linkedin_url:
          type: string
          description: Public LinkedIn profile URL of the contact. Sufficient on its own.
          example: https://www.linkedin.com/in/veronick-martinuzzi-a4533373
        first_name:
          type: string
          description: First name. Required when you do not send `linkedin_url`.
          example: Veronick
        last_name:
          type: string
          description: Last name. Required when you do not send `linkedin_url`.
          example: Martinuzzi
        company_domain:
          type: string
          description: Company domain. Required when you do not send `linkedin_url`.
          example: hondaresearch.com
        company:
          type: string
          description: Company name. Complements `company_domain`, it cannot replace it.
          example: Honda R&D Americas
        api_key:
          type: string
          description: Your API key. Only needed if you do not send the `X-API-Key` header.
    LeadProfile:
      type: object
      description: >-
        The lead profile. These are all the keys returned: unlike the enrichment
        and Lead Finder payloads there are no extra always-null legacy keys.
      properties:
        contact_id:
          type: integer
          description: BetterContact internal contact identifier.
          example: 98012430
          nullable: true
        contact_first_name:
          type: string
          description: First name.
          example: Veronick
          nullable: true
        contact_last_name:
          type: string
          description: Last name.
          example: Martinuzzi
          nullable: true
        contact_full_name:
          type: string
          description: First and last name concatenated.
          example: Veronick Martinuzzi
          nullable: true
        contact_job_title:
          type: string
          description: Current job title.
          example: Development solutions sr. principal engineer
          nullable: true
        contact_seniority:
          type: string
          description: Seniority level.
          example: Senior
          nullable: true
        contact_industry:
          type: string
          description: Industry of the contact.
          example: Motor vehicle manufacturing
          nullable: true
        contact_linkedin_headline:
          type: string
          description: LinkedIn headline. Often an empty string rather than null.
          example: ''
          nullable: true
        contact_linkedin_profile_url:
          type: string
          description: Public LinkedIn profile URL.
          example: https://www.linkedin.com/in/veronick-martinuzzi-a4533373
          nullable: true
        contact_location_continent:
          type: string
          description: Continent.
          nullable: true
        contact_location_country:
          type: string
          description: Country.
          example: United states
          nullable: true
        contact_location_state:
          type: string
          description: State or region.
          example: Ohio
          nullable: true
        contact_location_city:
          type: string
          description: City.
          nullable: true
        company_name:
          type: string
          description: Company name.
          example: Honda rd americas
          nullable: true
        company_domain:
          type: string
          description: Company domain.
          example: hondaresearch.com
          nullable: true
        company_description:
          type: string
          description: Company description.
          nullable: true
        company_linkedin_url:
          type: string
          description: Company LinkedIn page URL.
          example: https://www.linkedin.com/company/honda-r&d
          nullable: true
        company_industry:
          type: string
          description: Company industry.
          example: Motor vehicle manufacturing
          nullable: true
        company_type:
          type: string
          description: Company type.
          nullable: true
        company_founded_year:
          type: integer
          description: Year the company was founded.
          nullable: true
        company_employees_range_start:
          type: integer
          description: Lower bound of the headcount range.
          example: 10001
          nullable: true
        company_employees_range_end:
          type: integer
          description: >-
            Upper bound of the headcount range. `null` on open ended ranges such
            as `10001+`.
          nullable: true
        company_headquarters_city:
          type: string
          description: >-
            Headquarters city. Can carry a full street address rather than a
            bare city name.
          example: Ohio center; 21001 state route 739; raymond
          nullable: true
        company_headquarters_country:
          type: string
          description: Headquarters country.
          example: United states
          nullable: true
        company_keywords:
          type: array
          items:
            type: string
          description: Keywords associated with the company.
          example:
            - automotive
            - auto development
            - design
            - research
            - products
            - honda
    ApiError:
      type: object
      description: >-
        Generic error envelope. Depending on the endpoint the human readable
        text is carried by `error` or by `message`, so always read both.
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: Human readable error message.
        message:
          type: string
          description: Human readable error message.
    UnauthorizedError:
      type: object
      properties:
        success:
          type: boolean
          example: false
          description: Not returned by the enrichment endpoints.
        error:
          type: string
          example: Your are not authorized. Please check your api_key.
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-Key

````