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

# Actions guide

## Overview

The Actions API allows you to programmatically execute enrichments and other actions on your contacts and companies. This endpoint enables you to automate complex data enrichment pipelines by chaining multiple actions together in a single request.

An "actions run" is a concatenated series of actions that executes one or more enrichments on a set of contacts or companies. Each action runs sequentially on each entity.

## Request Body

The request must include a `actions` array and **one** of the following target specifiers:

| Field             | Type       | Description                          |
| ----------------- | ---------- | ------------------------------------ |
| `contactIds`      | `number[]` | Array of contact IDs to process      |
| `companyIds`      | `number[]` | Array of company IDs to process      |
| `contactGroupIds` | `number[]` | Array of contact list IDs to process |
| `companyGroupIds` | `number[]` | Array of company list IDs to process |

Each action object in the array must have:

| Field     | Type            | Description                                                  |
| --------- | --------------- | ------------------------------------------------------------ |
| `type`    | `ActionType`    | The type of action to execute (see Available actions below)  |
| `options` | `custom object` | Configuration options specific to the action type (optional) |

## Available Actions

#### Get contact from LinkedIn

Scrapes complete profile information from LinkedIn.

**Type**: `SCRAPE_LEAD_FROM_LINKEDIN`

**Options:**

```typescript theme={null}
{
  skipCompanyScrape?: boolean  // Skip scraping associated company data
  skipContactMerge?: boolean // Skip contact merge if a duplicate is found in Enginy
}
```

**Use When:** You have LinkedIn URLs and want complete profile data

***

#### Enrich with email

Finds professional email addresses for contacts.

**Type**: `ENRICH_WITH_EMAIL`

**Options:**

```typescript theme={null}
{
  sortedApis?: string[]           // e.g., ["CREDITS", "APOLLO", "DROPCONTACT"]
  stopType?: "NONE" | "VERIFIED_EMAIL" | "PHONE"
  speed?: "SLOW" | "FAST"         // SLOW = more thorough, FAST = quicker
  maxTimeToWait?: number          // Milliseconds
}
```

**Use When:** You need to find email addresses for contacts

**Tip:** Combine with `VERIFY_LEAD_EMAIL` for best results

***

#### Enrich with phone

Finds phone numbers for contacts.

**Type**: `ENRICH_WITH_PHONE`

**Options:**

```typescript theme={null}
{
  sortedApis?: string[]           // e.g., ["CREDITS", "APOLLO", "DROPCONTACT"]
  stopType?: "NONE" | "VERIFIED_EMAIL" | "PHONE"
  speed?: "SLOW" | "FAST"
  maxTimeToWait?: number          // Milliseconds
}
```

**Use When:** You need phone numbers for outreach

***

#### Verify contact email addresses

Verifies email addresses for deliverability.

**Type**: `VERIFY_LEAD_EMAIL`

**Options:** None required

**Use When:** You have email addresses and want to verify they're valid before sending

**Best Practice:** Always verify emails before running email campaigns

***

#### Verify contact phone number

Verifies phone numbers for validity.

**Type**: `VERIFY_LEAD_PHONE`

**Options:** None required

**Use When:** You have phone numbers and want to verify they're valid

***

#### Search contacts from company

Finds and imports LinkedIn contacts working at a target company. Targets companies (`companyIds` / `companyGroupIds`).

**Type**: `SEARCH_LEADS_FROM_LINKEDIN_COMPANY`

**Options:**

```typescript theme={null}
{
  // Filter source — provide exactly one of `text`, `savedFilterId`, or `filters`.
  // `keyword` may be supplied on its own or alongside `savedFilterId` / `filters`.
  //
  // Agents and MCP clients should generally prefer `text`: AI Finder turns a
  // natural-language description into the Sales Nav filter payload, which
  // produces better results than manually-constructed `filters` / `keyword`.

  text?: string                       // RECOMMENDED for agents/MCP. Natural-language
                                      // description (≤500 chars). Example:
                                      // "Heads of Sales who changed jobs in the past 90 days".

  savedFilterId?: number              // Reuse a stored Sales Nav filter (type=LEAD) from
                                      // GET /v1/saved-filters. Sub-second, deterministic.

  filters?: Record<string, unknown>   // Raw Sales Nav filter payload (same shape
                                      // GET /v1/saved-filters returns under `filters`).
                                      // Shape-validated server-side.

  keyword?: string | string[]         // Extra Sales Nav keyword(s) merged into the search.

  maxLeadsToImport?: number           // Default 5, max 10.
  destinationContactGroupId?: number  // Optional contact list to import discovered contacts into.
  onlyIncludeIfCompanyUrnMatch?: boolean // Only keep results LinkedIn maps to the exact target URN.
  importOnlyNewContacts?: boolean     // Skip contacts already in your Enginy workspace.
}
```

**Mutex rules:**

* `text` is exclusive with `savedFilterId`, `filters`, and `keyword`.
* `savedFilterId` is exclusive with `filters` (but can be combined with `keyword`).
* At least one of `text`, `savedFilterId`, `filters`, or `keyword` must be provided.

**Recommended payload (agents / MCP / new integrations):**

```json theme={null}
{
  "actions": [
    {
      "type": "SEARCH_LEADS_FROM_LINKEDIN_COMPANY",
      "options": {
        "text": "Heads of Sales who changed jobs in the past 90 days",
        "maxLeadsToImport": 10,
        "destinationContactGroupId": 12345
      }
    }
  ],
  "companyIds": [98765]
}
```

**Use When:** You have target companies (`companyIds` or `companyGroupIds`) and want LinkedIn contacts matching a role/seniority/persona description imported into Enginy.

***

#### Find company LinkedIn URL

Finds the LinkedIn page of a company and stores its URL on the company record. Targets companies (`companyIds` / `companyGroupIds`).

**Type**: `COMPANY_LINKEDIN_FROM_NAME`

**Options:**

```typescript theme={null}
{
  matchOnlyExactDomain?: boolean  // Only accept a result whose website domain equals the
                                  // domain (or website domain) stored on the company.
                                  // Companies without a stored domain/website find no match.

  matchOnlyExactName?: boolean    // Only accept a result whose LinkedIn name equals the
                                  // company name (case- and accent-insensitive).

  matchOnlySimilarName?: boolean  // Only accept a result whose LinkedIn name is similar to
                                  // the company name (normalized fuzzy match). Ignored when
                                  // matchOnlyExactName is also set.
}
```

With no options the best LinkedIn search result is accepted. Each flag adds a constraint on which result is accepted; a run that matches nothing stores nothing, so the company can be retried with a looser mode.

**Discovery cascade (recommended for maximum coverage):** run the action up to three times over the still-unmatched companies, strictest mode first:

1. `{ "matchOnlyExactDomain": true }` — exact website-domain match
2. `{ "matchOnlyExactName": true }` — exact name match
3. `{ "matchOnlySimilarName": true }` — similar-name match

**Use When:** Companies are missing their LinkedIn URL and you want to find it before scraping (`SCRAPE_COMPANY_FROM_LINKEDIN`) or searching contacts (`SEARCH_LEADS_FROM_LINKEDIN_COMPANY`).

***

#### Export to CRM

Exports enriched contact or company data to your connected CRM.

**Type**: `EXPORT_TO_CRM`

**Options:**

```typescript theme={null}
{
  CRMOwnerId?: {
    value: string      // CRM owner/user ID
    override: boolean  // Whether to override existing owner
  }
  promptLeadFieldsCRMMapping?: {
    [fieldName: string]: {
      value: string
      override: boolean
    }
  }
  promptCompanyFieldsCRMMapping?: {
    [fieldName: string]: {
      value: string
      override: boolean
    }
  }
  overwriteFields?: {
    [fieldName: string]: boolean
  }
  associationType?: string
  exportAssociatedObject?: boolean  // Also export company when exporting contact
}
```

**Use When:** You want to sync enriched data to your CRM

**Tip:** Use this as the last step in your enrichment pipeline

***

#### Sync contacts with CRM

Pulls the latest CRM field values back into Enginy for contacts. By default it uses each contact's stored CRM identifiers for a fast incremental sync. Set `fullResync: true` to clear those identifiers and re-match every contact in the CRM from scratch — use this when records have drifted or were re-keyed in the CRM. Targets contacts (`contactIds` / `contactGroupIds`).

**Type**: `SYNC_LEAD_WITH_CRM`

**Options:**

```typescript theme={null}
{
  fullResync?: boolean  // Default false. Reset stored CRM identifiers and re-match
                        // each contact from scratch instead of an incremental sync.
}
```

**Example (full resync of a contact list):**

```json theme={null}
{
  "actions": [{ "type": "SYNC_LEAD_WITH_CRM", "options": { "fullResync": true } }],
  "contactGroupIds": [12345]
}
```

**Use When:** A connected CRM is the source of truth and you want Enginy contacts refreshed with the latest CRM data.

***

#### Sync companies with CRM

Pulls the latest CRM field values back into Enginy for companies. By default it uses each company's stored CRM identifiers for a fast incremental sync. Set `fullResync: true` to clear those identifiers and re-match every company in the CRM from scratch. Targets companies (`companyIds` / `companyGroupIds`).

**Type**: `SYNC_COMPANY_WITH_CRM`

**Options:**

```typescript theme={null}
{
  fullResync?: boolean  // Default false. Reset stored CRM identifiers and re-match
                        // each company from scratch instead of an incremental sync.
}
```

**Example (full resync of a company list):**

```json theme={null}
{
  "actions": [{ "type": "SYNC_COMPANY_WITH_CRM", "options": { "fullResync": true } }],
  "companyGroupIds": [67890]
}
```

**Use When:** A connected CRM is the source of truth and you want Enginy companies refreshed with the latest CRM data.

***

## Common Use Cases

### New Lead Qualification Pipeline

**Goal:** Quickly qualify and enrich new leads from an event

```json theme={null}
{
  "actions": [
    {"type": "SCRAPE_LEAD_FROM_LINKEDIN"},
    {"type": "ENRICH_WITH_EMAIL"},
    {"type": "VERIFY_LEAD_EMAIL"},
    {
      "type": "EXPORT_TO_CRM",
      "options": {
        "CRMOwnerId": {"value": "sales_rep_123", "override": false}
      }
    }
  ],
  "contactGroupIds": [...]
}
```

**Result:** Fully enriched, verified leads in your CRM ready for outreach

***

### List Cleaning & Verification

**Goal:** Clean and verify an existing contact list

```json theme={null}
{
  "actions": [
    {"type": "VERIFY_LEAD_EMAIL"},
    {
      "type": "EXPORT_TO_CRM",
      "options": {
        "promptLeadFieldsCRMMapping": {
          "Email_Verified__c": {
            "value": "true",
            "override": true
          }
        }
      }
    }
  ],
  "contactGroupIds": [...]
}
```

**Result:** Verified contact list with verification status updated in CRM

***

### Multi-Channel Outreach Preparation

**Goal:** Prepare contacts for both email and phone outreach

```json theme={null}
{
  "actions": [
    {
      "type": "ENRICH_WITH_EMAIL",
      "options": {"stopType": "VERIFIED_EMAIL"}
    },
    {"type": "ENRICH_WITH_PHONE"},
    {"type": "VERIFY_LEAD_EMAIL"},
    {"type": "EXPORT_TO_CRM"}
  ],
  "contactIds": [...]
}
```

**Result:** Contacts with verified emails and phone numbers ready for SDR team
