Before creating anything in Odoo, Enginy looks for an existing record. If it finds one, it updates it. If not, it creates one.
That search uses the identifiers you configure under Integrations → Odoo → Sync configuration. It is the decision that most affects whether you end up with duplicates.
Note: This search never creates anything. If it finds no match, it simply does not link, and the export decides whether to create the record.
Contacts
The main signal is email. Enginy normalizes it before comparing, so uppercase letters and stray spaces do not prevent a match.
If the contact has no email, a second signal kicks in: first and last name within the same company. It does not match on name alone, precisely so two different people with the same name are not merged.
Companies
Three signals, from most to least reliable:
Signal | Reliability | Notes |
VAT number | High | Exact match. By far the safest. |
Website domain | Medium | Compares the domain, not the full URL. |
Name | Low | Exact match, not partial. Last resort. |
Note: If you store VAT numbers in Odoo, use them. It is the only company identifier that does not produce false positives.
Leads
They are matched by email, among open leads. When there are several, the most recent one wins.
If the lead has no email, the same logic as contacts applies: first and last name within the same company.
Note: If your workspace has Default object when exporting set to Lead, your Enginy contacts are matched through this path, not the contact one. Everything in this section then applies to them.
Already linked records are not recalculated
When a record arrives in Enginy through an import, it stays linked to its Odoo record. From then on, Enginy checks that the record still exists instead of looking it up again by email or VAT.
This is deliberate. If it re-derived the link every time, a contact without an email would become unlinked and lose its CRM data.
If someone deletes the record in Odoo, the link is removed, which is the correct outcome.
Archived records count too
Important: The search includes archived Odoo records. Without this, an archived contact would be invisible and every export would create a new duplicate. The tradeoff is that Enginy may link an Enginy record to an archived Odoo record. This is the intended behavior, but worth knowing if you see links pointing at records you no longer use.
Custom matching
If the standard identifiers do not fit your conventions, you can define your own by choosing an Odoo field.
Important: In this version, a custom identifier is a single field. You cannot combine several fields with an AND condition for the same record. If you need that combination, talk to us.
The solid paths are still email for people and VAT or domain for companies.
If duplicates appear
Check in this order:
That your Enginy records actually have the identifier field filled in. A contact without an email cannot match by email.
That the configured identifier is the one you really use in Odoo. If you store VAT numbers but name matching is configured, you will get duplicates.
That the API key user has permission to read those records. What it cannot see, it cannot find.
