Running an HVAC business with Odoo

How do I import customer contacts into Odoo?

Workflow overview: How do I import customer contacts into Odoo?
Workflow overview. Instructional screenshots show the actual demo interface.

Import customer, billing and service-site contacts into Odoo, test the mappings, and update a saved address with the same External ID.

Alex has a small customer list to bring into Odoo. This example imports a customer with separate billing and service addresses, then changes the service address without creating another contact.

Alex Rivera and Demo Air HVAC are fictional training examples. Prices, dates, quantities and business situations in this guide are illustrative.

Before you begin

Tested in stock Odoo 20.0-20260926 Community as the demo owner administrator, with official modules and standard configuration. Complete customer and service-site records. Use Contacts and its native Import action in a training database. This creates a separate H09 example and preserves the H08 customer. Prepare a UTF-8, comma-separated CSV with a header row. No email or telephone fields are needed.

Step-by-step workflow

Import three related contacts, test all mappings, then update the service address with the same External ID and check the final count. This verifies one controlled update, not automatic duplicate detection or company classification.

Use the following eight columns. Put the parent first; the two address rows point to its External ID. Address Type uses the imported values contact, invoice and delivery. Country/External ID uses the installed US country identifier base.us.

csv External ID,Name,Address Type,Related Company/External ID,Street,City,ZIP,Country/External ID demoair_h09.customer,Demo Property Import H09,contact,,130 Demo Registry Road,North Fort Myers,33903,base.us demoair_h09.billing,Demo Billing Import H09,invoice,demoair_h09.customer,135 Demo Billing Road,North Fort Myers,33903,base.us demoair_h09.delivery,Demo Site Import H09,delivery,demoair_h09.customer,140 Demo Site Road,North Fort Myers,33903,base.us

Search the three names before importing and keep a restorable backup of the training database.

Action 18: Inspect the three stable External IDs in the CSV preview. The actual target is highlighted in gold.
Inspect the three stable External IDs in the CSV preview.

Step 2. Upload through Contacts

Open Contacts → Actions menu → Import → Upload and choose the CSV. Check that Odoo shows three rows, the comma separator and the first row as a header. This fixture has no Is a Company or Country/Code column: neither mapped to an editable import field in the tested runtime.

Action 1: Open the app menu. The actual target is highlighted in gold.
Open the app menu.
Action 2: Choose Contacts. The actual target is highlighted in gold.
Choose Contacts.
Action 3: Review existing contacts and keep the H08 customer intact. The actual target is highlighted in gold.
Review existing contacts and keep the H08 customer intact.
Action 4: Open the Contacts Actions menu. The actual target is highlighted in gold.
Open the Contacts Actions menu.
Action 5: Choose the native Import action. The actual target is highlighted in gold.
Choose the native Import action.
Action 6: Upload the reviewed eight-column contacts CSV. The actual target is highlighted in gold.
Upload the reviewed eight-column contacts CSV.
Action 7: Keep the first row as the header. The actual target is highlighted in gold.
Keep the first row as the header.
Action 8: Check UTF-8 encoding. The actual target is highlighted in gold.
Check UTF-8 encoding.
Action 9: Check the comma separator. The actual target is highlighted in gold.
Check the comma separator.

Step 3. Review every field mapping

Match External ID, Name, Address Type, Street, City and ZIP to their fields. Map Related Company/External ID to Related Company / External ID, and Country/External ID to Country / External ID. Confirm all eight columns have a destination. Leave the parent row's Related Company blank; both children reference demoair_h09.customer.

Action 10: Verify External ID maps to External ID. The actual target is highlighted in gold.
Verify External ID maps to External ID.
Action 11: Verify Name maps to Name. The actual target is highlighted in gold.
Verify Name maps to Name.
Action 12: Verify Address Type maps to Address Type. The actual target is highlighted in gold.
Verify Address Type maps to Address Type.
Action 13: Verify Related Company/External ID maps to Related Company / External ID. The actual target is highlighted in gold.
Verify Related Company/External ID maps to Related Company / External ID.
Action 14: Verify Street maps to Street. The actual target is highlighted in gold.
Verify Street maps to Street.
Action 15: Verify City maps to City. The actual target is highlighted in gold.
Verify City maps to City.
Action 16: Verify ZIP maps to Zip. The actual target is highlighted in gold.
Verify ZIP maps to Zip.
Action 17: Verify Country/External ID maps to Country / External ID. The actual target is highlighted in gold.
Verify Country/External ID maps to Country / External ID.

Step 4. Test, then import the three rows

Choose Test. Continue when the preview says Everything seems valid and the rows and mappings match your file. Testing did not create contacts in this example. Choose Import once and wait for 3 records successfully imported. Open the parent and both address records. The parent shows the two cards; the children retain their Related Company and the Invoice Address or Delivery Address type.

Action 19: Test all three rows before importing. The actual target is highlighted in gold.
Test all three rows before importing.
Action 20: Everything seems valid; Test has not created contacts. The actual target is highlighted in gold.
Everything seems valid; Test has not created contacts.
Action 21: Import the tested three-row file once. The actual target is highlighted in gold.
Import the tested three-row file once.
Action 22: Check 3 records successfully imported. The actual target is highlighted in gold.
Check 3 records successfully imported.
Action 23: Review the three newly imported contact rows. The actual target is highlighted in gold.
Review the three newly imported contact rows.
Action 24: Open the new Demo Property Import H09 parent. The actual target is highlighted in gold.
Open the new Demo Property Import H09 parent.
Action 25: Verify the saved parent name. The actual target is highlighted in gold.
Verify the saved parent name.
Action 26: Check the Invoice and Delivery address cards. The actual target is highlighted in gold.
Check the Invoice and Delivery address cards.
Action 27: Return to the imported Contacts list. The actual target is highlighted in gold.
Return to the imported Contacts list.
Action 28: Open Demo Billing Import H09. The actual target is highlighted in gold.
Open Demo Billing Import H09.
Action 29: Billing remains linked to the imported parent. The actual target is highlighted in gold.
Billing remains linked to the imported parent.
Action 30: Check the saved Invoice Address type. The actual target is highlighted in gold.
Check the saved Invoice Address type.
Action 31: Check the saved billing Street. The actual target is highlighted in gold.
Check the saved billing Street.
Action 32: Return to Contacts. The actual target is highlighted in gold.
Return to Contacts.
Action 33: Open Demo Site Import H09. The actual target is highlighted in gold.
Open Demo Site Import H09.
Action 34: The service site remains linked to the same parent. The actual target is highlighted in gold.
The service site remains linked to the same parent.
Action 35: Check the saved Delivery Address type. The actual target is highlighted in gold.
Check the saved Delivery Address type.
Action 36: Check the original service Street before the update. The actual target is highlighted in gold.
Check the original service Street before the update.

Step 5. Update the service address with its existing ID

Prepare a one-row CSV with the same eight columns and the delivery row's original External ID. Change only its Street to 145 Demo Updated Site Road. Upload it through the same Import action, review the mappings and choose Test. Before Import, the saved street remains 140 Demo Site Road. Choose Import and wait for 1 records successfully imported.

Action 37: Return to Contacts for the update file. The actual target is highlighted in gold.
Return to Contacts for the update file.
Action 38: Open the Contacts Actions menu. The actual target is highlighted in gold.
Open the Contacts Actions menu.
Action 39: Choose native Import again. The actual target is highlighted in gold.
Choose native Import again.
Action 40: Upload the one-row same-ID address update. The actual target is highlighted in gold.
Upload the one-row same-ID address update.
Action 41: Keep demoair_h09.delivery as the original External ID. The actual target is highlighted in gold.
Keep demoair_h09.delivery as the original External ID.
Action 42: The file changes Street to 145 Demo Updated Site Road. The actual target is highlighted in gold.
The file changes Street to 145 Demo Updated Site Road.
Action 43: Review all eight mappings for this one-row update. The actual target is highlighted in gold.
Review all eight mappings for this one-row update.
Action 44: Test the address update before importing. The actual target is highlighted in gold.
Test the address update before importing.
Action 45: Test is valid; the saved service Street is still 140. The actual target is highlighted in gold.
Test is valid; the saved service Street is still 140.
Action 46: Import the tested one-row update once. The actual target is highlighted in gold.
Import the tested one-row update once.
Action 47: Check 1 records successfully imported. The actual target is highlighted in gold.
Check 1 records successfully imported.

Step 6. Reopen and check for duplicates

Open Demo Site Import H09 and check Street 145 Demo Updated Site Road, its parent and Delivery Address type. Search the three H09 names again: there are still three records. Their saved IDs and links are unchanged. Preserve the CSV External IDs for future updates; displayed record numbers can differ in another database.

Action 48: Reopen the updated Demo Site Import H09. The actual target is highlighted in gold.
Reopen the updated Demo Site Import H09.
Action 49: Verify the saved Street is 145 Demo Updated Site Road. The actual target is highlighted in gold.
Verify the saved Street is 145 Demo Updated Site Road.
Action 50: The same saved parent link is retained. The actual target is highlighted in gold.
The same saved parent link is retained.
Action 51: Delivery Address type remains unchanged. The actual target is highlighted in gold.
Delivery Address type remains unchanged.
Action 52: Open Contacts from the main navigation. The actual target is highlighted in gold.
Open Contacts from the main navigation.
Action 53: Search all Contacts for Import H09. The actual target is highlighted in gold.
Search all Contacts for Import H09.
Action 54: Exactly the three H09 contact rows remain. The actual target is highlighted in gold.
Exactly the three H09 contact rows remain.

Check the result

The import created customer 14, billing address 15 and service address 16. Both children link to customer 14. Reusing demoair_h09.delivery updated record 16 to 145 Demo Updated Site Road; the contact count stayed ten and exactly three H09 External IDs remained. Original H08 records 7/8/9 and their address links are intact.

If your screen differs

The native importer did not map Is a Company or Country/Code in this test. This procedure establishes the related-contact structure, not company classification. Test success does not replace reviewing a backup, source data and field mappings. A new or missing External ID can create another record; this lesson verifies one correctly identified update, not automatic duplicate detection for arbitrary files.

Frequently asked questions

How do I import customer contacts into Odoo? Open Contacts → Actions menu → Import, upload a reviewed CSV, map all columns and choose Test before Import. This example creates a customer plus billing and delivery addresses linked by External ID.
How do I update Odoo contacts without creating duplicates? In this test, reusing the original delivery contact's External ID updated its Street and preserved its saved record and parent link. Keep the same IDs and check the resulting count; missing or different IDs need separate duplicate review.
Can I import billing and service addresses into Odoo? The tested CSV maps Related Company / External ID to the parent and Address Type to invoice or delivery. Reopening the child records confirms Invoice Address and Delivery Address. Company classification was not established by this file.

Continue building the business

Continue with lead-source labels or the the service quotation.

Talk to an Odoo partner

Bring your current process and the result you need to Onward to plan your Odoo workflow. Talk to an Odoo partner.