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

# Check who is already in your CRM

> For a list of LinkedIn people, find out who already exists in your CRM. Run this before creating contacts, to avoid duplicates.

> [!NOTE]
>
> Nothing changes, and LinkedIn is not touched. Attio and HubSpot are searched live, which uses some of your CRM's API quota.

## What this call does

| | |
| - | - |
| **LinkedIn** | None |
| **Your CRM** | Live search on Attio and HubSpot, using your CRM's API quota |
| **Repeating it** | Safe to repeat. |

## Good to know

* `crm_searched: false` for someone with a `slug` means the search did not finish, not that they are absent. Run those people again.

Your AI assistant reaches the same action through the MCP tool `lookup_crm_contacts`.


## OpenAPI

````yaml reference/openapi.json POST /crm/contacts/lookup
openapi: 3.1.0
info:
  title: Groovin API
  version: 1.0.0
  description: >-
    Connect LinkedIn and your CRM. Every call acts on your real LinkedIn account
    and CRM: there is no test mode.
servers:
  - url: https://api.groovin.ai/functions/v1/api/v1
security:
  - apiKey: []
tags:
  - name: LinkedIn
  - name: CRM contacts and companies
  - name: LinkedIn connections import
paths:
  /crm/contacts/lookup:
    post:
      tags:
        - CRM contacts and companies
      summary: Check who is already in your CRM
      description: >-
        For a list of LinkedIn people, find out who already exists in your CRM.
        Run this before creating contacts, to avoid duplicates.
      operationId: lookup_crm_contacts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                profiles:
                  type: array
                  items:
                    type: object
                    properties:
                      linkedin_profile_id:
                        type: string
                        description: Their LinkedIn profile id.
                      slug:
                        type: string
                        description: >-
                          The end of their LinkedIn URL. Needed for the live CRM
                          search.
                      full_name:
                        type: string
                        description: Their full name.
                    required: []
                  description: >-
                    The people to check, up to 10,000 per call. Live search
                    covers up to 500 unlinked people on Attio and 250 on
                    HubSpot.
                org_linkedin_account_id:
                  type: integer
                  description: >-
                    Which LinkedIn account to check for. Leave it out to use
                    your own.
              required:
                - profiles
            examples:
              placeholder:
                summary: Replace every value
                value:
                  profiles:
                    - linkedin_profile_id: REPLACE_WITH_LINKEDIN_PROFILE_ID
                      slug: REPLACE_WITH_SLUG
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LookupCrmContactsResult'
              example:
                org_linkedin_account_id: 4821
                total: 1
                crm_search:
                  supported: true
                  eligible: 1
                  searched: 1
                  not_searched: 0
                  rate_limited: false
                results:
                  - linkedin_profile_id: ACoAAExampleLinkedinProfileId
                    slug: john-smith
                    exists: false
                    source: none
                    crm_contact_id: null
                    crm_searched: true
        '400':
          description: 'Something in the request is wrong: `error` says what.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: The API key is missing, wrong or revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            Your account cannot do this: no CRM connected, inactive
            subscription, Billing admin role, or a teammate's LinkedIn account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: >-
            What you asked for does not exist, or your LinkedIn account is not
            connected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: LinkedIn or your CRM is slowing you down. Wait at least 5 minutes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Something failed on our side.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: >-
            LinkedIn or your CRM could not be reached or gave an unreadable
            answer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    LookupCrmContactsResult:
      type: object
      description: One answer per person you asked about.
      required:
        - org_linkedin_account_id
        - total
        - crm_search
        - results
      properties:
        org_linkedin_account_id:
          type: integer
          description: Groovin's id for the LinkedIn account this answer is about.
        total:
          type: integer
          description: People checked.
        crm_search:
          $ref: '#/components/schemas/LiveCrmSearchReport'
        results:
          type: array
          items:
            $ref: '#/components/schemas/LookupCrmContactItemResult'
          description: One item per person.
    Error:
      type: object
      description: >-
        What every failed request answers, with an HTTP status. The text can
        change: decide what to do from the status, and show the text to a
        person.
      required:
        - error
      properties:
        error:
          type: string
          description: What went wrong, and sometimes what to do next.
    LiveCrmSearchReport:
      type: object
      description: How much of the live CRM search finished.
      required:
        - supported
        - eligible
        - searched
        - not_searched
        - rate_limited
      properties:
        supported:
          type: boolean
          description: '`true` when your CRM has a live search (Attio and HubSpot).'
        eligible:
          type: integer
          description: Unlinked people who have a `slug`, so can be searched.
        searched:
          type: integer
          description: People whose search finished.
        not_searched:
          type: integer
          description: People whose search did not finish. Run these again later.
        rate_limited:
          type: boolean
          description: >-
            `true` when your CRM slowed the search down. Wait about a minute
            before running the rest.
    LookupCrmContactItemResult:
      type: object
      description: Whether one person is already in your CRM.
      required:
        - linkedin_profile_id
        - slug
        - exists
        - source
        - crm_contact_id
        - crm_searched
      properties:
        linkedin_profile_id:
          type:
            - string
            - 'null'
          description: LinkedIn profile id, the `ACoAA…` identifier of a person.
        slug:
          type:
            - string
            - 'null'
          description: >-
            The public part of the person's LinkedIn URL, as in
            `linkedin.com/in/<slug>`.
        exists:
          type: boolean
          description: '`true` when the person matches an existing CRM contact.'
        source:
          type: string
          enum:
            - groovin_pair
            - crm_search
            - none
          description: How that was decided.
        crm_contact_id:
          type:
            - string
            - 'null'
          description: >-
            The matching contact. `null` with `exists: true` means several CRM
            records match: merge them in your CRM.
        crm_searched:
          type: boolean
          description: >-
            `true` when a live CRM search finished for this person. `false` is
            not proof that they are absent: run them again later.
        crm_match_count:
          type: integer
          description: CRM records the live search matched, when there is at least one.
        is_crm_contact_creation_blocked:
          const: true
          description: >-
            Only present, as `true`, when you blocked this person from CRM
            contact creation in Groovin. `crm/contacts` does not enforce the
            block, so check it yourself before creating.
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        Your Groovin API key (`gv_live_…`), created in the extension under
        Settings, MCP and API.

````

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