Your Implementation Required
These endpoints must be implemented on your server
Overview
The sync and update endpoints allow bidirectional data flow between Enginy and your CRM:| Endpoint | Purpose |
|---|---|
POST /contacts/sync | Find existing contacts and optionally return properties to Enginy |
PUT /contacts | Update contacts that already exist in your CRM |
Key Principle: All matching logic lives in your CRM, not Enginy. You decide how to identify contacts
(by email, LinkedIn URL, phone, etc.) and what data to sync back.
How Matching Works
When Enginy sends contacts to sync, your CRM should:- Look up each contact using your preferred identifier(s)
- Return matches with your CRM’s internal ID (
crmId) - Optionally return properties you want synced back to Enginy
Common Matching Strategies
Email (Most Common)
Match by
email field - the most reliable identifier for contactsLinkedIn URL
Match by
linkedinUrl - useful for B2B contactsPhone Number
Match by
phone or mobilePhone - normalize formats firstComposite Key
Combine multiple fields (email + company) for higher accuracy
Sync Contacts
Request
Request Body
Enginy sends all contacts it wants to sync:Response
Return only contacts that exist in your CRM:Contact
lead-789 is not in the response because it doesn’t exist in your CRM. Only return matches.Example Implementation
Here’s how to implement the matching logic:Update Contacts
After syncing, Enginy knows which contacts have CRM IDs. The update endpoint receives only contacts that were previously matched.Request
Request Body
Response
Example Implementation
Properties You Can Sync Back
When you returnproperties in your response, Enginy will store these values on the contact. Common properties to sync:
| Property | Type | Description |
|---|---|---|
email | string | Contact’s email address |
phone | string | Contact’s phone number |
mobilePhone | string | Contact’s mobile phone number |
leadScore | number | Your CRM’s lead scoring value |
lifecycleStage | string | Lead, MQL, SQL, Opportunity, Customer |
lastActivityDate | string | ISO 8601 date of last activity |
owner | string | Assigned sales rep ID or name |
dealValue | number | Associated deal/opportunity value |
tags | array | CRM tags or labels |
customField_* | any | Any custom fields you want to sync |
You can return any properties you want. Enginy will store them as custom fields on the contact.
Handling Null Values
To prevent accidentally clearing data in Genesy, follow these guidelines:| Your CRM returns | Result in Genesy |
|---|---|
"email": "[email protected]" | Email is updated to [email protected] |
"email": null | Email is cleared (set to null) |
| Field not included in response | Email is cleared (set to null) |
properties that you explicitly want to sync back. If you don’t want to modify a field, don’t include it in the properties object.
Available Contact Fields
Enginy sends these fields (when available):| Field | Type | Description |
|---|---|---|
externalId | string | Enginy’s internal contact ID (use for mapping) |
email | string | Primary email address |
firstName | string | First name |
lastName | string | Last name |
fullName | string | Full name |
phone | string | Phone number |
mobilePhone | string | Mobile phone |
company | string | Company name |
title | string | Job title |
linkedinUrl | string | LinkedIn profile URL |
location | string | Location/address |
city | string | City |
state | string | State/region |
country | string | Country |
industry | string | Industry |
website | string | Personal website |
bio | string | Biography/description |
tags | array | Tags/labels |
customFields | object | Any custom fields |
Engagement Field Updates
When contacts engage with campaigns (reply, connect, click links, etc.), Enginy sends engagement updates through the samePUT /contacts endpoint. These updates contain custom field names configured by the user in their campaign settings.
Example Engagement Update
Available Engagement Fields
Users can configure which fields to sync and what to name them. Here are all the fields Enginy can send:| Enginy Field | Type | Example Value | Description |
|---|---|---|---|
campaignEngagementStatus | string | Message Replied (2/3) - LINKEDIN | Current engagement status |
campaignSequenceStatus | string | Ongoing | Sequence status: Not Started, Ongoing, Finished, Replied |
campaignSequenceDetails | string | Linkedin Message, Email, Linkedin Message | Sequence step types |
campaignOpens | string | 5 | Number of email opens |
campaignClicks | string | 2 | Number of link clicks |
campaignOpenAnalysis | string | Yes (5) or No | Whether emails were opened |
campaignClickAnalysis | string | Yes (2) or No | Whether links were clicked |
campaignReplyAnalysis | string | Yes (1) or No | Whether contact replied |
activities | string | Connection Request Sent, Message Sent (LINKEDIN) | Comma-separated activity log |
senders | string | John Smith, Jane Doe | Campaign senders |
campaigns | string | Q1 Outreach, Product Launch | Campaign names |
Engagement Status Values
ThecampaignEngagementStatus field follows this progression:
Added to Campaign- Contact added but no action takenConnection Request Sent- LinkedIn connection request sentConnection Accepted- LinkedIn connection acceptedMessage Sent (1/3) - LINKEDIN- First message sent (with type)Message Replied (1/3) - LINKEDIN- Contact replied
Field names are user-configurable. Your CRM should accept any field name and store it appropriately
(either as a known field or as a custom field).
Implementation Tip
Make sure yourPUT /contacts handler stores unknown fields rather than ignoring them:
Error Handling
Partial Success
If some contacts fail, return successful results and errors separately:Update Failures
For updates, indicate failure in the result:Engagement Field Updates
When contacts engage with campaigns (reply, connect, click links, etc.), Enginy sends engagement updates through the samePUT /contacts endpoint. These updates contain custom field names configured by the user in their campaign settings.
Example Engagement Update
Available Engagement Fields
Users can configure which fields to sync and what to name them. Here are all the fields Enginy can send:| Enginy Field | Type | Example Value | Description |
|---|---|---|---|
campaignEngagementStatus | string | Message Replied (2/3) - LINKEDIN | Current engagement status |
campaignSequenceStatus | string | Ongoing | Sequence status: Not Started, Ongoing, Finished, Replied |
campaignSequenceDetails | string | Linkedin Message, Email, Linkedin Message | Sequence step types |
campaignOpens | string | 5 | Number of email opens |
campaignClicks | string | 2 | Number of link clicks |
campaignOpenAnalysis | string | Yes (5) or No | Whether emails were opened |
campaignClickAnalysis | string | Yes (2) or No | Whether links were clicked |
campaignReplyAnalysis | string | Yes (1) or No | Whether contact replied |
activities | string | Connection Request Sent, Message Sent (LINKEDIN) | Comma-separated activity log |
senders | string | John Smith, Jane Doe | Campaign senders |
campaigns | string | Q1 Outreach, Product Launch | Campaign names |
Engagement Status Progression
ThecampaignEngagementStatus field follows this progression:
Added to Campaign- Contact added but no action takenConnection Request Sent- LinkedIn connection request sentConnection Accepted- LinkedIn connection acceptedMessage Sent (1/3) - LINKEDIN- First message sent (with channel type)Message Replied (1/3) - LINKEDIN- Contact replied
Field names are user-configurable. Your CRM should accept any field name and store it appropriately
(either as a known field or as a custom field).
Implementation Tip
Make sure yourPUT /contacts handler stores unknown fields rather than ignoring them:
Reference Implementation
GitHub Repository
See a complete working implementation of contacts sync and update endpoints, including engagement field
handling and activity display.