> ## 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.

# Custom CRM

> Connect your custom CRM or internal system to Enginy

## Overview

The Custom CRM integration allows you to connect Enginy with your own CRM system or internal database. This enables Enginy to:

* **Export contacts and companies** from Enginy to your CRM
* **Create tasks** directly in your system when sequences or workflows require task creation
* **Create associations** between contacts and companies in your CRM
* **Log activities** (LinkedIn messages, emails) to your CRM
* **Assign owners** to exported records (if your CRM supports users)

<Info>
  This integration is designed for companies with proprietary CRM systems or custom-built internal tools that
  aren't supported by our standard integrations.
</Info>

## How It Works

When you connect a Custom CRM:

1. You provide Enginy with your API base URL and authentication credentials
2. Enginy validates the connection by calling your `/health` endpoint
3. Once connected, Enginy can export contacts, companies, and create tasks in your system

```mermaid theme={null}
sequenceDiagram
    participant G as Enginy
    participant C as Your CRM

    Note over G,C: Connection Setup
    G->>C: GET /health
    C-->>G: 200 OK

    Note over G,C: Export Companies
    G->>C: POST /companies
    C-->>G: { results: [{ externalId, crmId }] }

    Note over G,C: Export Contacts
    G->>C: POST /contacts
    C-->>G: { results: [{ externalId, crmId }] }

    Note over G,C: Create Associations
    G->>C: POST /associations
    C-->>G: { success: true }

    Note over G,C: Task Creation (from sequences)
    G->>C: POST /tasks
    C-->>G: { id: "task-123", ... }
```

## Prerequisites

Before connecting, your CRM must expose the following endpoints:

<CardGroup cols={2}>
  <Card title="Health Endpoint" icon="heart-pulse" href="/api-reference/custom-crm/overview#health-endpoint">
    A `GET /health` endpoint for connection validation
  </Card>

  <Card title="Contacts API" icon="user" href="/api-reference/custom-crm/contacts">
    Batch create contacts endpoint
  </Card>

  <Card title="Companies API" icon="building" href="/api-reference/custom-crm/companies">
    Batch create companies endpoint
  </Card>

  <Card title="Associations API" icon="link" href="/api-reference/custom-crm/associations">
    Link contacts to companies endpoint
  </Card>

  <Card title="Tasks API" icon="list-check" href="/api-reference/custom-crm/tasks">
    Task CRUD and batch endpoints (for sequences)
  </Card>

  <Card title="Activities API" icon="message-dots" href="/api-reference/custom-crm/activities">
    Log LinkedIn and email activities
  </Card>

  <Card title="Users API (Optional)" icon="users" href="/api-reference/custom-crm/endpoints/users/get">
    List users for owner assignment
  </Card>
</CardGroup>

## Authentication

Your CRM must accept API key authentication via a configurable header. When connecting, you'll specify:

| Parameter             | Description                                                       | Default     |
| --------------------- | ----------------------------------------------------------------- | ----------- |
| `baseUrl`             | Your API's base URL (e.g., `https://api.mycrm.com`)               | Required    |
| `apiKey`              | Your API key or secret token                                      | Required    |
| `apiKeyHeader`        | The header name for authentication                                | `X-API-Key` |
| `contactLinkTemplate` | URL template for contact records (use `{{crmId}}` as placeholder) | Optional    |
| `companyLinkTemplate` | URL template for company records (use `{{crmId}}` as placeholder) | Optional    |

Enginy will include this header in all requests:

```bash theme={null}
POST /contacts HTTP/1.1
Host: api.mycrm.com
X-API-Key: your-secret-key
Content-Type: application/json
Accept: application/json
```

## CRM Record Links

When configured, Enginy can generate clickable links to open contact and company records directly in your CRM. This allows users to quickly navigate from Enginy to the corresponding record in your system.

To enable this feature, provide URL templates when connecting your CRM:

```json theme={null}
{
  "baseUrl": "https://api.mycrm.com",
  "apiKey": "your-crm-api-key",
  "apiKeyHeader": "X-API-Key",
  "contactLinkTemplate": "https://mycrm.com/contacts/{{crmId}}",
  "companyLinkTemplate": "https://mycrm.com/companies/{{crmId}}"
}
```

The `{{crmId}}` placeholder will be replaced with the actual CRM ID when generating links. For example:

* Template: `https://mycrm.com/contacts/{{crmId}}`
* Result: `https://mycrm.com/contacts/ABC123`

<Tip>
  The link templates are optional. If not provided, the "Open in CRM" links will not be available for Custom
  CRM records.
</Tip>

## Users/Owners Support (Optional)

If your CRM has a concept of users or owners that can be assigned to contacts, companies, tasks, and activities, you can implement the optional `/users` endpoint to enable owner selection in Enginy.

### How It Works

When you connect your Custom CRM, Enginy automatically tests the `/users` endpoint:

| Response               | Result                                                 |
| ---------------------- | ------------------------------------------------------ |
| **2xx** with user list | ✅ Owner selection enabled in export modal              |
| **404 / 501 / 405**    | Owner selection gracefully disabled (not an error)     |
| **Other errors**       | Owner selection disabled, connection proceeds normally |

<Info>
  This detection happens **every time** Enginy needs to fetch owners, not just during initial connection. This
  means you can add or remove the `/users` endpoint at any time.
</Info>

### What You Get

When users are available, Enginy shows an owner dropdown in:

* **Export modal** - Assign an owner to all exported contacts/companies
* **Task creation** - Set the task owner
* **Activity logging** - Associate activities with the owner

### Implementation

Your `/users` endpoint should return an array of users:

```json theme={null}
GET /users

[
  { "id": "user-123", "name": "John Smith", "email": "john@example.com" },
  { "id": "user-456", "name": "Jane Doe", "email": "jane@example.com" }
]
```

The `id` is sent back to your CRM when creating records with an owner assignment.

<Card title="Users API Reference" icon="users" href="/api-reference/custom-crm/endpoints/users/get">
  See the complete Users endpoint specification
</Card>

## Connecting Your CRM

### Step 1: Implement the Required Endpoints

Before connecting, ensure your CRM implements the required interface. See the [Custom CRM API Reference](/api-reference/custom-crm/overview) for detailed specifications.

<Card title="Reference Implementation" icon="github" href="https://github.com/Genesy-AI/custom-crm-example">
  Clone our open-source reference implementation to get started quickly
</Card>

### Step 2: Test the Connection

Use the test endpoint to validate your configuration:

```bash theme={null}
curl -X POST https://openapi.enginy.ai/v1/custom-crm/test \
  -H "x-api-key: gsk_your_enginy_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "baseUrl": "https://api.mycrm.com",
    "apiKey": "your-crm-api-key",
    "apiKeyHeader": "X-API-Key"
  }'
```

The test response includes information about users support:

```json theme={null}
{
  "success": true,
  "supportsUsers": true,
  "users": [{ "id": "user-123", "name": "John Smith", "email": "john@example.com" }]
}
```

<Tip>
  If `supportsUsers` is `true`, the test also fetches your users to verify the endpoint works correctly.
</Tip>

### Step 3: Connect

Once the test passes, connect your CRM:

```bash theme={null}
curl -X POST https://openapi.enginy.ai/v1/custom-crm/connect \
  -H "x-api-key: gsk_your_enginy_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "baseUrl": "https://api.mycrm.com",
    "apiKey": "your-crm-api-key",
    "apiKeyHeader": "X-API-Key",
    "contactLinkTemplate": "https://mycrm.com/contacts/{{crmId}}",
    "companyLinkTemplate": "https://mycrm.com/companies/{{crmId}}"
  }'
```

<Note>
  The `contactLinkTemplate` and `companyLinkTemplate` parameters are optional. Include them to enable "Open in
  CRM" links.
</Note>

### Step 4: Verify Status

Check your connection status anytime:

```bash theme={null}
curl https://openapi.enginy.ai/v1/custom-crm/status \
  -H "x-api-key: gsk_your_enginy_api_key"
```

## Exporting to Your CRM

Once connected, you can export contacts and companies from Enginy to your Custom CRM:

1. **Select leads/companies** in Enginy
2. **Choose "Export to CRM"** and select Custom CRM
3. Enginy will:
   * First create companies (if any)
   * Then create contacts
   * Finally create associations between contacts and companies
4. **CRM IDs are saved** in Enginy for future reference

<Tip>
  The export is push-only. Enginy sends all available fields as-is to your CRM. Your CRM is responsible for
  mapping and storing the data appropriately.
</Tip>

## Disconnecting

To disconnect your Custom CRM:

```bash theme={null}
curl -X DELETE https://openapi.enginy.ai/v1/custom-crm/disconnect \
  -H "x-api-key: gsk_your_enginy_api_key"
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Contacts API" icon="user" href="/api-reference/custom-crm/contacts">
    View the Contacts API specification
  </Card>

  <Card title="Companies API" icon="building" href="/api-reference/custom-crm/companies">
    View the Companies API specification
  </Card>

  <Card title="Associations API" icon="link" href="/api-reference/custom-crm/associations">
    View the Associations API specification
  </Card>

  <Card title="Tasks API" icon="list-check" href="/api-reference/custom-crm/tasks">
    View the Tasks API specification
  </Card>

  <Card title="Activities API" icon="message-dots" href="/api-reference/custom-crm/activities">
    View the Activities API specification
  </Card>

  <Card title="Users API" icon="users" href="/api-reference/custom-crm/endpoints/users/get">
    Enable owner assignment (optional)
  </Card>

  <Card title="Examples" icon="code" href="/api-reference/custom-crm/examples">
    See complete implementation examples in Node.js, Python, and Go
  </Card>
</CardGroup>
