Data sources
Bring companies, contacts, deals, products, quotes, orders, invoices and credit notes in from any ERP, shop or CRM — through a connector, by pushing them yourself, or as rows from a file.
Three ways in, one set of rules. Connectors (SAP Business One, Odoo, Shopify, WooCommerce, HubSpot, Pipedrive, Close, Attio, Copper, Capsule, Insightly, product feeds) read your system on a schedule. Push — any other system (Sage, Cegid, Dynamics, NetSuite, a home-grown ERP, n8n, a script) sends its records to POST /sync/ingest under its own source id custom:<name>. Import sends rows once, like a file. Every record goes through the same normalisation (field names in English, French, German, Spanish and the SAP / Odoo / Sage vocabularies; dates in any format; European decimals; statuses) and the same matching — companies by link, then customer code, then email domain, then name — so nothing is duplicated.
/sync/ingestPush records from any systemPOST/sync/importImport rows once (like a file)GET/sync/providersAvailable connectorsGET/syncConnected sourcesGET/sync/{provider}One sourcePUT/sync/{provider}Connect a sourcePOST/sync/{provider}/testTest credentialsPATCH/sync/{provider}Change what a source syncsPOST/sync/{provider}/runRun a sync nowGET/sync/agent/configWhat a pushing system should send nowGET/sync/{provider}/countriesCustomers per countryDELETE/sync/{provider}Disconnect a source/sync/ingestPush records from any system
Send up to 5,000 records of one object per call. The source is created on the first call (it then appears in Meetzy › Integrations with its status). Records are matched to what Meetzy already has: the same external_id updates, the customer code links invoices to companies, unknown customers named on documents are created. The answer counts what was created, updated, unchanged or skipped and lists rejected records with the reason. Field names don’t need to match: N° facture, Code client, Total TTC, Kunde, Importe are recognised — see the field reference below.
Body
providerstringrequired- Source id:
custom:<name>for your system (custom:sage-100), or a connector id (sap_b1,odoo…) when you send on its behalf. objectstringrequiredcompanies,contacts,products,deals,quotes,orders,invoices,credit_notes, ordocuments(mixed, each record with atype).recordsobject[]required- The records, in your own field names.
labelstring- Display name of your system (“Sage 100”), set on the first call.
date_orderstringdmyormdywhen your dates are ambiguous (05/10/2026). Detected from the batch otherwise.firstboolean- First batch of a full run: resets the run counters.
lastboolean- Last batch of a run: marks the object as synced (its
sincemoves forward). sincedate- This run only sent changes since this date (not a full run).
started_atdatetime- When your run started — recorded as the last success.
keep_onlystring[]- Products: the ids still alive in your system — the others are archived.
currencystring- Default currency for records without one.
Batches can also carry lifecycle markers for long runs: object: "_start", "_error" (for, message) and "_end" (owners, currency).
Up to 5,000 records per call (60,000 for price_rules). 413 above.
curl -X POST "https://meetzy.me/api/v1/sync/ingest" \ -H "Authorization: Bearer $MEETZY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "provider": "custom:sage-100", "label": "Sage 100", "object": "invoices", "records": [ { "N° facture": "F2026-0412", "Date": "30/09/2026", "Échéance": "29/11/2026", "Code client": "C-1001", "Client": "Parfumerie Lumière", "Total HT": "1 250,00", "Total TTC": "1 500,00", "Reste dû": "1 000,00", "Commercial": "Alice Martin", "lines": [ { "Référence": "SKU-100", "Désignation": "Eau de parfum 50 ml", "Qté": 24, "PU HT": 42, "Montant HT": 1008 } ] } ] }'
const res = await fetch("https://meetzy.me/api/v1/sync/ingest", { method: "POST", headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ "provider": "custom:sage-100", "label": "Sage 100", "object": "invoices", "records": [ { "N° facture": "F2026-0412", "Date": "30/09/2026", "Échéance": "29/11/2026", "Code client": "C-1001", "Client": "Parfumerie Lumière", "Total HT": "1 250,00", "Total TTC": "1 500,00", "Reste dû": "1 000,00", "Commercial": "Alice Martin", "lines": [ { "Référence": "SKU-100", "Désignation": "Eau de parfum 50 ml", "Qté": 24, "PU HT": 42, "Montant HT": 1008 } ] } ] }), }); const data = await res.json();
import os, requests
res = requests.post(
"https://meetzy.me/api/v1/sync/ingest",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
json={
"provider": "custom:sage-100",
"label": "Sage 100",
"object": "invoices",
"records": [
{
"N° facture": "F2026-0412",
"Date": "30/09/2026",
"Échéance": "29/11/2026",
"Code client": "C-1001",
"Client": "Parfumerie Lumière",
"Total HT": "1 250,00",
"Total TTC": "1 500,00",
"Reste dû": "1 000,00",
"Commercial": "Alice Martin",
"lines": [
{
"Référence": "SKU-100",
"Désignation": "Eau de parfum 50 ml",
"Qté": 24,
"PU HT": 42,
"Montant HT": 1008
}
]
}
]
},
)
data = res.json(){
"created": 0,
"updated": 1,
"unchanged": 0,
"skipped": 0,
"archived": 0,
"received": 1,
"rejected": 0,
"rejected_samples": [],
"date_order": "dmy"
}/sync/importImport rows once (like a file)
Rows from a spreadsheet or an export, without setting up a source — records are tagged with the source import. Same normalisation and matching as sync/ingest. Invoices spread over several rows (one per line) are grouped by number. Send big files in parts of up to 5,000 rows; first: false on the following parts.
Body
objectstringrequiredcompanies,contacts,deals,quotes,orders,invoices,credit_notesordocuments.recordsobject[]required- The rows, with the file’s own column names.
date_orderstringdmyormdyfor ambiguous dates.overwriteboolean- Update fields of records that already exist (default: only fill what is empty).
cyclestring- Contacts: sales cycle to put new contacts in.
firstbooleanfalsefor the second part of a file onwards.
curl -X POST "https://meetzy.me/api/v1/sync/import" \ -H "Authorization: Bearer $MEETZY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "object": "companies", "records": [ { "Code client": "C-1001", "Raison sociale": "Parfumerie Lumière", "Pays": "France", "Ville": "Lyon", "Commercial": "Alice Martin" } ] }'
const res = await fetch("https://meetzy.me/api/v1/sync/import", { method: "POST", headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ "object": "companies", "records": [ { "Code client": "C-1001", "Raison sociale": "Parfumerie Lumière", "Pays": "France", "Ville": "Lyon", "Commercial": "Alice Martin" } ] }), }); const data = await res.json();
import os, requests
res = requests.post(
"https://meetzy.me/api/v1/sync/import",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
json={
"object": "companies",
"records": [
{
"Code client": "C-1001",
"Raison sociale": "Parfumerie Lumière",
"Pays": "France",
"Ville": "Lyon",
"Commercial": "Alice Martin"
}
]
},
)
data = res.json(){
"created": 0,
"updated": 0,
"unchanged": 1,
"skipped": 0,
"archived": 0,
"received": 1,
"rejected": 0,
"rejected_samples": [],
"date_order": "dmy"
}/sync/providersAvailable connectors
Every source Meetzy can connect: id, name, category, what it can bring in (objects) and by default, its connection methods with the fields they need (secret fields are write-only), options per object, the sync intervals and the object list.
curl "https://meetzy.me/api/v1/sync/providers" \ -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/sync/providers", {
headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();import os, requests
res = requests.get(
"https://meetzy.me/api/v1/sync/providers",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json(){
"categories": [
{
"id": "erp",
"label": "ERP & accounting"
}
],
"intervals": [
{
"min": 15,
"label": "Every 15 minutes"
},
{
"min": 60,
"label": "Every hour"
}
],
"providers": [
{
"id": "odoo",
"name": "Odoo",
"category": "erp",
"versions": "Odoo 14 to 18 — Online, Odoo.sh or on-premise.",
"objects": [
"products",
"companies",
"contacts",
"deals",
"quotes",
"orders",
"invoices",
"credit_notes"
],
"defaults": [
"products",
"companies",
"contacts",
"deals",
"orders",
"invoices"
],
"oauth": false,
"push": false,
"methods": {
"api": {
"label": "Direct connection",
"fields": [
{
"key": "url",
"label": "Odoo address",
"secret": false,
"optional": false
},
{
"key": "database",
"label": "Database",
"secret": false,
"optional": false
},
{
"key": "login",
"label": "Login (email)",
"secret": false,
"optional": false
},
{
"key": "key",
"label": "API key",
"secret": true,
"optional": false
}
],
"options": []
}
},
"object_options": {
"invoices": [
{
"key": "months",
"label": "History",
"type": "select",
"default": 24
},
{
"key": "lines",
"label": "Include the lines (products, quantities, prices)",
"type": "toggle",
"default": false
}
]
}
}
]
}/syncConnected sources
Every connected source: method, account, what it syncs, status (idle, running, error), last run and last success, last error, per-object counters, and how many records each brought in. Secrets are never returned (has_secret tells which are set).
curl "https://meetzy.me/api/v1/sync" \ -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/sync", {
headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();import os, requests
res = requests.get(
"https://meetzy.me/api/v1/sync",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json(){
"migrated": true,
"connected": [],
"counts": {},
"hubspot_oauth": false
}/sync/{provider}One source
One connection (same shape as in GET /sync) and its record counts. provider is the source id (odoo, custom:sage-100…).
Path parameters
providerstringrequired- Source id:
odoo,sap_b1,shopify,custom:sage-100…
curl "https://meetzy.me/api/v1/sync/custom:sage-100" \ -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/sync/custom:sage-100", {
headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();import os, requests
res = requests.get(
"https://meetzy.me/api/v1/sync/custom:sage-100",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json(){
"connection": {
"provider": "custom:sage-100",
"method": "push",
"account_label": "Sage 100",
"credentials": {},
"has_secret": {},
"oauth": false,
"objects": {
"products": {
"enabled": false,
"mode": "sync",
"options": {}
},
"companies": {
"enabled": true,
"mode": "sync",
"options": {}
},
"contacts": {
"enabled": true,
"mode": "sync",
"options": {
"cycle": ""
}
},
"deals": {
"enabled": false,
"mode": "sync",
"options": {}
},
"quotes": {
"enabled": false,
"mode": "sync",
"options": {
"months": 24,
"lines": false
}
},
"orders": {
"enabled": true,
"mode": "sync",
"options": {
"months": 24,
"lines": false
}
},
"invoices": {
"enabled": true,
"mode": "sync",
"options": {
"months": 24,
"lines": false
}
},
"credit_notes": {
"enabled": false,
"mode": "sync",
"options": {
"months": 24,
"lines": false
}
}
},
"settings": {
"interval_min": 60
},
"status": "idle",
"stats": {
"phase": "Done",
"objects": {
"invoices": {
"created": 0,
"skipped": 0,
"updated": 1,
"archived": 0,
"unchanged": 0
}
}
},
"last_error": null,
"last_run_at": "2026-10-07T13:23:58.796+00:00",
"last_success_at": "2026-10-07T13:23:58.796+00:00",
"started_at": null,
"agent_last_seen_at": "2026-10-07T13:23:58.796+00:00",
"agent_info": {
"runtime": "API"
},
"has_agent_key": false,
"created_at": "2026-10-07T13:23:58.721716+00:00",
"interrupted": false
},
"counts": {
"companies": 0,
"price_rules": 0,
"contacts": 0,
"deals": 0,
"products": 0,
"orders": 0,
"credit_notes": 0,
"invoices": 1,
"quotes": 0
}
}/sync/{provider}Connect a source
Saves the connection: method, credentials, what to bring in, options. For api methods Meetzy tests the credentials first (400 with the provider’s message if they fail) and starts a first run. To connect your own system, use provider: custom with credentials.name — it becomes custom:<name>. HubSpot signs in with OAuth from the app.
Path parameters
providerstringrequired- Source id:
odoo,sap_b1,shopify,custom:sage-100…
Body
methodstring- Connection method of the provider (
api,agent,push). credentialsobjectrequired- Values for the method’s fields (see
GET /sync/providers). A secret left empty keeps the saved one. objectsobject{ "invoices": { "enabled": true, "mode": "sync" | "import", "options": { "months": 24, "lines": true } } }. Default: the provider’s defaults.settingsobjectinterval_min(15, 60, 360 or 1440),no_owner(noneorcreator), method options (e.g.insecure_tls).startboolean- Run right away. Default
true.
Returns the saved connection, like GET /sync/{provider}.
curl -X PUT "https://meetzy.me/api/v1/sync/custom:sage-100" \ -H "Authorization: Bearer $MEETZY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "method": "api", "credentials": { "url": "https://acme.odoo.com", "database": "acme", "login": "olivia@acme.com", "key": "odoo_api_key" }, "objects": { "invoices": { "enabled": true, "mode": "sync", "options": { "months": 24, "lines": true } }, "companies": { "enabled": true, "mode": "sync" } }, "settings": { "interval_min": 60 } }'
const res = await fetch("https://meetzy.me/api/v1/sync/custom:sage-100", { method: "PUT", headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ "method": "api", "credentials": { "url": "https://acme.odoo.com", "database": "acme", "login": "olivia@acme.com", "key": "odoo_api_key" }, "objects": { "invoices": { "enabled": true, "mode": "sync", "options": { "months": 24, "lines": true } }, "companies": { "enabled": true, "mode": "sync" } }, "settings": { "interval_min": 60 } }), }); const data = await res.json();
import os, requests
res = requests.put(
"https://meetzy.me/api/v1/sync/custom:sage-100",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
json={
"method": "api",
"credentials": {
"url": "https://acme.odoo.com",
"database": "acme",
"login": "olivia@acme.com",
"key": "odoo_api_key"
},
"objects": {
"invoices": {
"enabled": True,
"mode": "sync",
"options": {
"months": 24,
"lines": True
}
},
"companies": {
"enabled": True,
"mode": "sync"
}
},
"settings": {
"interval_min": 60
}
},
)
data = res.json()See the notes on the left.
/sync/{provider}/testTest credentials
Checks api credentials without saving them (400 with the provider’s message when they fail). Returns the account label and what was found (currency, price lists).
Path parameters
providerstringrequired- Source id:
odoo,sap_b1,shopify,custom:sage-100…
Body
methodstring- Method.
credentialsobjectrequired- Credentials to test.
curl -X POST "https://meetzy.me/api/v1/sync/custom:sage-100/test" \ -H "Authorization: Bearer $MEETZY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "method": "api", "credentials": { "url": "https://acme.odoo.com", "database": "acme", "login": "olivia@acme.com", "key": "odoo_api_key" } }'
const res = await fetch("https://meetzy.me/api/v1/sync/custom:sage-100/test", { method: "POST", headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ "method": "api", "credentials": { "url": "https://acme.odoo.com", "database": "acme", "login": "olivia@acme.com", "key": "odoo_api_key" } }), }); const data = await res.json();
import os, requests
res = requests.post(
"https://meetzy.me/api/v1/sync/custom:sage-100/test",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
json={
"method": "api",
"credentials": {
"url": "https://acme.odoo.com",
"database": "acme",
"login": "olivia@acme.com",
"key": "odoo_api_key"
}
},
)
data = res.json(){
"label": "Acme · Odoo",
"options": {
"currency": "EUR"
}
}/sync/{provider}Change what a source syncs
Turn objects on or off, switch them between sync and one-time import, change options or the interval, and map salespeople — without touching credentials. An object whose options change (lines turned on, more history) is read in full on the next run. Mappings are applied to what is already synced unless apply: false.
Path parameters
providerstringrequired- Source id:
odoo,sap_b1,shopify,custom:sage-100…
Body
objectsobject- Objects and their options.
settingsobject- Interval and options.
ownersobject- Salesperson mapping:
{ "<salesperson code in your system>": "teammate@acme.com" }(empty string removes). country_ownersobject- Owner of customers without a salesperson, per country:
{ "Nigeria": "alice@acme.com" }. country_firstboolean- When
true, the country rules win even over the salesperson of the source: every customer of a country with a rule goes to its owner (with contacts, documents and open deals).falsegives them back to their salesperson. applyboolean- Re-assign existing companies, contacts, documents and deals. Default
true. apply_allboolean- Re-apply every mapping, not only the changed ones.
Returns the updated connection, plus reassigned (companies, contacts, documents, deals) when a mapping changed.
curl -X PATCH "https://meetzy.me/api/v1/sync/custom:sage-100" \ -H "Authorization: Bearer $MEETZY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "objects": { "credit_notes": { "enabled": true, "mode": "sync" } }, "owners": { "12": "alice@acme.com" } }'
const res = await fetch("https://meetzy.me/api/v1/sync/custom:sage-100", { method: "PATCH", headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ "objects": { "credit_notes": { "enabled": true, "mode": "sync" } }, "owners": { "12": "alice@acme.com" } }), }); const data = await res.json();
import os, requests
res = requests.patch(
"https://meetzy.me/api/v1/sync/custom:sage-100",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
json={
"objects": {
"credit_notes": {
"enabled": True,
"mode": "sync"
}
},
"owners": {
"12": "alice@acme.com"
}
},
)
data = res.json()See the notes on the left.
/sync/{provider}/runRun a sync now
Starts a run of a connector (all objects or some). For pushing sources (push, agent) Meetzy cannot start them: full: true asks the next run to send everything again.
Path parameters
providerstringrequired- Source id:
odoo,sap_b1,shopify,custom:sage-100…
Body
objectsstring[]- Only these objects.
fullboolean- Read everything, not only changes.
curl -X POST "https://meetzy.me/api/v1/sync/custom:sage-100/run" \ -H "Authorization: Bearer $MEETZY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "objects": [ "invoices" ], "full": false }'
const res = await fetch("https://meetzy.me/api/v1/sync/custom:sage-100/run", { method: "POST", headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ "objects": [ "invoices" ], "full": false }), }); const data = await res.json();
import os, requests
res = requests.post(
"https://meetzy.me/api/v1/sync/custom:sage-100/run",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
json={
"objects": ["invoices"],
"full": False
},
)
data = res.json(){
"ok": true
}/sync/agent/configWhat a pushing system should send now
For a source that pushes (a script, a job in your ERP): per enabled object, its mode, options and since — the date of the last success, so you only send what changed. Call it at the start of each run.
Query parameters
providerstringrequired- Source id, e.g.
custom:sage-100.
curl "https://meetzy.me/api/v1/sync/agent/config?provider=custom:sage-100" \ -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/sync/agent/config?provider=custom:sage-100", {
headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();import os, requests
res = requests.get(
"https://meetzy.me/api/v1/sync/agent/config?provider=custom:sage-100",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json(){
"provider": "custom:sage-100",
"objects": {
"companies": {
"mode": "sync",
"options": {},
"since": null
},
"contacts": {
"mode": "sync",
"options": {
"cycle": ""
},
"since": null
},
"orders": {
"mode": "sync",
"options": {
"months": 24,
"lines": false
},
"since": null
},
"invoices": {
"mode": "sync",
"options": {
"months": 24,
"lines": false
},
"since": null
}
},
"interval_min": 60,
"run_id": "vVAO_Wf0K6M"
}/sync/{provider}/countriesCustomers per country
How many companies of this source are in each country, and how many have no salesperson — to set country_owners.
Path parameters
providerstringrequired- Source id:
odoo,sap_b1,shopify,custom:sage-100…
curl "https://meetzy.me/api/v1/sync/custom:sage-100/countries" \ -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/sync/custom:sage-100/countries", {
headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();import os, requests
res = requests.get(
"https://meetzy.me/api/v1/sync/custom:sage-100/countries",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json(){
"countries": [
{
"country": "Nigeria",
"companies": 41,
"without_salesperson": 41
},
{
"country": "France",
"companies": 812,
"without_salesperson": 3
}
]
}/sync/{provider}Disconnect a source
Stops syncing and forgets the credentials (and the source’s own key, if any). Records already brought in stay.
Path parameters
providerstringrequired- Source id:
odoo,sap_b1,shopify,custom:sage-100…
curl -X DELETE "https://meetzy.me/api/v1/sync/custom:sage-100" \ -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://meetzy.me/api/v1/sync/custom:sage-100", { method: "DELETE", headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` }, }); const data = await res.json();
import os, requests
res = requests.delete(
"https://meetzy.me/api/v1/sync/custom:sage-100",
headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json(){
"ok": true
}Field reference
Send records in your own field names — or these canonical ones. Names are compared without case, accents, spaces or punctuation (N° Facture reads as nfacture); a few of the recognised names are listed per field — there are many more, in English, French, German, Spanish and the SAP / Odoo / Sage vocabularies. Unknown fields are kept in extra. Documents (quotes, orders, invoices, credit_notes) share the same fields; lines unlock brand and product analytics.
Companies
| Field | What it is | Also recognised |
|---|---|---|
external_idrequired | Id in your system (customer code) — required to update later | id · externalref · sourceid · erpid · uid |
namerequired | Company name | companyname · company · account · accountname · customer |
domain | Email domain (lumiere.fr): matches companies Meetzy already knows | emaildomain · websitedomain |
website | Website | url · site · web · siteweb · homepage |
email | Generic email — its domain is used when there is no website | mail · emailaddress · courriel · e_mail |
phone | Phone | telephone · tel · phonenumber · phone1 · mobile |
address | Street | adresse · street · address1 · addressline1 · street1 |
zip | Postal code | zipcode · postalcode · postcode · codepostal · cp |
city | City | ville · town · locality · commune · stadt |
country | Country — name or 2-letter code | pays · countryname · countrycode · land · pais |
industry | Industry | sector · secteur · activity · activite · branche |
employees | Headcount | headcount · employeecount · nbemployees · numberofemployees · effectif |
type | customer · lead · supplier | kind · customertype · partnertype · cardtype · relationship |
vat_number | VAT / tax number | vat · vatid · taxid · tva · numerotva |
group | Customer group in your system | groupe · customergroup · groupname · groupcode · bpgroup |
payment_terms | Payment terms | terms · conditionsdepaiement · paymentcondition · pymntgroup |
currency | Default currency | devise · currencycode · curr |
credit_limit | Credit limit | creditline · limitedecredit |
balance | Account balance | accountbalance · solde · balancedue · currentbalance |
owner | { code, name, email } — the salesperson; mapped to a Meetzy user in Integrations | salesperson · salesrep · rep · seller · accountmanager |
owner_email | Owner by email (a Meetzy user) | salespersonemail · repemail · assignedto · assignee · assignedemail |
tags | List of labels | labels · tag · label · etiquettes · groups |
linkedin_url | LinkedIn page | linkedin · linkedincompanypage |
notes | Free text | note · comment · comments · remarks · description |
updated_at | Last change — lets Meetzy skip unchanged records | modified · modifiedat · lastmodified · lastmodifieddate · writedate |
extra | Any other fields: kept and shown on the company | custom · customfields · meta · metadata · properties |
{
"external_id": "C-1001",
"name": "Parfumerie Lumière",
"domain": "lumiere.fr",
"phone": "+33 4 72 00 00 00",
"city": "Lyon",
"country": "FR",
"type": "customer",
"industry": "Retail",
"owner": {
"code": "12",
"name": "Alice Martin",
"email": "alice@yourcompany.com"
},
"tags": [
"Perfumery"
],
"updated_at": "2026-10-01T09:00:00Z"
}Contacts
| Field | What it is | Also recognised |
|---|---|---|
external_id | Id in your system | id · externalref · sourceid · erpid · uid |
first_name | First name | prenom · givenname · first · forename · vorname |
last_name | Last name | nom · surname · familyname · last · nachname |
name | Full name, when not split | fullname · contactname · displayname · person · nomcomplet |
emailrequired | Email — matches contacts Meetzy already knows | primaryemail · mail · emailaddress · courriel · e_mail |
phone | Phone | telephone · tel · phonenumber · mobile · mobilephone |
title | Job title | jobtitle · position · fonction · role · job |
company_external_id | Id of the company in your system (links to it) | companyid · accountid · customerid · customercode · clientid |
company | Company name | companyname · organization · organisation · societe · account |
city | City | ville · town · locality |
country | Country | pays · countryname · countrycode |
lifecycle | lead · mql · sql · opportunity · customer | lifecyclestage · stage · statut · leadstatus · contactstatus |
owner | { code, name, email } | salesperson · salesrep · rep · seller · accountmanager |
owner_email | Owner by email | salespersonemail · repemail · assignedto · assignee · assignedemail |
tags | List of labels | labels · tag · label · etiquettes · groups |
linkedin_url | LinkedIn profile | linkedin · linkedinprofile · linkedinprofileurl |
updated_at | Last change | modified · modifiedat · lastmodified · lastmodifieddate · writedate |
{
"external_id": "P-5002",
"first_name": "Nadia",
"last_name": "Benali",
"email": "nadia@lumiere.fr",
"phone": "+33 6 00 00 00 00",
"title": "Buyer",
"company_external_id": "C-1001",
"company": "Parfumerie Lumière",
"country": "FR",
"owner_email": "alice@yourcompany.com",
"updated_at": "2026-10-01T09:00:00Z"
}Deals
| Field | What it is | Also recognised |
|---|---|---|
external_idrequired | Id in your system | id · externalref · sourceid · erpid · uid |
namerequired | Deal name | title · dealname · opportunity · opportunityname · subject |
amount | Amount | value · total · expectedrevenue · montant · revenue |
currency | Currency | devise · currencycode · dealcurrencycode |
status | open · won · lost | state · dealstatus · outcome · result · won |
stage_name | Stage name — matched to your Meetzy pipeline stages by name | stage · dealstage · etape · pipelinestage · step |
probability | 0–100 | probabilite · winprobability · likelihood |
close_date | Expected or actual close date | expectedclosedate · closingdate · datecloture · close · expectedclose |
company_external_id | Id of the company | companyid · accountid · customerid · customercode · clientid |
contact_external_ids | Ids of the contacts | contactids · contacts · personids · contactexternalid · contactid |
owner | { code, name, email } | salesperson · salesrep · rep · seller · accountmanager |
owner_email | Owner by email | salespersonemail · repemail · assignedto · assignee · assignedemail |
updated_at | Last change | modified · modifiedat · lastmodified · lastmodifieddate · writedate |
{
"external_id": "D-77",
"name": "Spring order — Lumière",
"amount": 12500,
"currency": "EUR",
"status": "open",
"stage_name": "Proposal",
"close_date": "2026-11-15",
"company_external_id": "C-1001",
"contact_external_ids": [
"P-5002"
],
"owner_email": "alice@yourcompany.com"
}Products
| Field | What it is | Also recognised |
|---|---|---|
external_id | Id in your system (or the SKU) | id · externalref · sourceid · erpid · uid |
skurequired | SKU / item code | itemcode · reference · ref · code · productcode |
namerequired | Name | title · productname · nom · designation · libelle |
description | Description | longdescription · body · bodyhtml · details · remarks |
unit_price | Sales price | price · prix · prixunitaire · prixht · salesprice |
currency | Currency | devise · currencycode · curr |
cost | Unit cost | unitcost · cout · prixachat · purchaseprice · costprice |
tax_pct | VAT % | vat · tva · tax · taxrate · vatrate |
barcode | EAN / GTIN | ean · ean13 · gtin · upc · codebarre |
category | Category | categorie · itemgroup · itmsgrpnam · groupe · productgroup |
brand | Brand | marque · vendor · manufacturer · fabricant · maker |
stock_qty | Stock | stock · instock · onhand · quantity · qty |
unit | Unit | unite · uom · salesunit · unitofmeasure · baseunit |
image_url | Image URL | image · imagesrc · picture · photo · imagelink |
url | Product page | link · producturl · permalink · productpage |
active | true / false | actif · status · valid · enabled · published |
{
"external_id": "SKU-100",
"sku": "SKU-100",
"name": "Eau de parfum 50 ml",
"unit_price": 42,
"currency": "EUR",
"cost": 18,
"barcode": "3401234567890",
"category": "Fragrances",
"brand": "Maison X",
"stock_qty": 120,
"active": true
}Quotes, orders, invoices, credit notes
| Field | What it is | Also recognised |
|---|---|---|
external_idrequired | Id in your system — or the number | id · externalref · sourceid · erpid · uid |
number | Number shown to the customer | docnumber · documentnumber · docnum · invoicenumber · invoiceno |
type | invoice · order · quote · credit_note (only for a mixed "documents" batch) | doctype · documenttype · kind · movetype · typedocument |
daterequired | Document date | docdate · documentdate · invoicedate · orderdate · issuedate |
due_date | Due date (invoices) or validity date (quotes) | due · paymentdue · echeance · dateecheance · datedecheance |
status | open · paid · closed · cancelled — or whatever your system says; worked out from the amounts when missing | state · paymentstatus · paymentstate · paidstatus · documentstatus |
company_external_idrequired | Id of the customer in your system — matches companies by their code | customerid · customercode · clientid · clientcode · partnerid |
company_name | Customer name — used when the id is unknown to Meetzy | customer · customername · client · clientname · company |
contact_external_id | Id of the contact | contactid · personid · cntctcode · contactpersoncode |
currency | Currency | devise · currencycode · cur · doccurrency · currencyid |
totalrequired | Total incl. tax | amount · grandtotal · totalttc · ttc · amounttotal |
net_total | Total excl. tax — analytics use it | subtotal · net · amountuntaxed · totalht · ht |
tax_total | Tax | tax · vat · tva · amounttax · taxamount |
paid | Amount received so far | paidamount · amountpaid · paidtodate · payments · settled |
unpaid | Amount still due (either paid or unpaid is enough) | balance · amountdue · amountresidual · outstanding · remaining |
lines | Array of { sku, name, quantity, unit_price, discount_pct, total } — brands and products analytics need them | items · lineitems · details · positions · rows |
owner | { code, name, email } — the salesperson | salesperson · salesrep · rep · seller · accountmanager |
customer_ref | Customer PO / reference | ponumber · purchaseorder · customerreference · yourreference · clientorderref |
notes | Comments | note · comment · comments · remarks · memo |
updated_at | Last change | modified · modifiedat · lastmodified · lastmodifieddate · writedate |
{
"external_id": "INV-2026-0412",
"number": "F2026-0412",
"date": "2026-09-30",
"due_date": "2026-11-29",
"status": "open",
"company_external_id": "C-1001",
"company_name": "Parfumerie Lumière",
"currency": "EUR",
"total": 1500,
"net_total": 1250,
"tax_total": 250,
"paid": 500,
"lines": [
{
"sku": "SKU-100",
"name": "Eau de parfum 50 ml",
"quantity": 24,
"unit_price": 42,
"discount_pct": 0,
"total": 1008
}
],
"owner": {
"code": "12",
"name": "Alice Martin"
},
"customer_ref": "PO-889"
}How records are matched
| Order | Companies | Contacts | Documents |
|---|---|---|---|
| 1 | Same source and id (external_id) | Same source and id | Same source, type and id |
| 2 | Customer code in any source (custom.erp.code) | Email address | — |
| 3 | Email / website domain | Company by company_external_id | Customer by company_external_id → code |
| 4 | Normalised name (“ACME S.A.S.” = “Acme SAS”) | — | Customer by name — created when unknown |
Dates: ISO, DD/MM/YYYY, MM/DD/YYYY (decided on the whole batch, or forced with date_order), Excel serial numbers, Unix timestamps. Numbers: 1 234,56, 1,234.56, €1.234,56. Countries: names in any language or ISO codes. Statuses: open, paid, closed, cancelled — or what your system writes (Soldée, bezahlt, O/C…); worked out from the amounts when missing.