Customers CSV import API

customers_v1

low9 fields · 2 required · 2 validatedPack · E-commerce

Import this template via API. Import e-commerce customers from CSV. Email-validated, phone-validated, lifetime stats carried as numbers.

30-second curl

curl -X POST https://api.adaptivmapr.com/v1/uploads \
  -H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \
  -F "template=customers_v1" \
  -F "file=@your_data.csv"

At a glance

Pack
E-commerce
FHIR resource
Risk level
low
Fields
9 (2 required, 2 validated)

Why this template?

The Customers template is the buyer-side counterpart to Orders. Each row carries an id, a validated email (required), optional first and last names, an optional phone, an optional default shipping address id, a created_at timestamp, and two lifetime stats: lifetime_orders and lifetime_value. The lifetime fields are denormalised because most downstream tools expect them on the customer row rather than computed at query time; that denormalisation is per-workspace policy, and the template carries it cleanly. E-commerce teams use this template to migrate between platforms, to seed a CDP, to refresh an RFM segmentation, and to feed a loyalty program. The cascade catches multilingual "lifetime value" variants without escalation because that header is one of the most-localised in retail data.

email is required because cross-platform customer identity is built on email — phone-only customers belong in a separate template. lifetime_value carries the same locale-tolerant number parsing as the orders template. created_at is the customer's creation timestamp, not their first order — those two often diverge and the template preserves the difference.

Migration scenarios & common foreign headers

Migration scenarios for the Customers template: cross-platform customer base migrations during a re-platforming project, CDP seeding for the first time (Segment, mParticle, RudderStack), refreshing an RFM segmentation before a marketing campaign, and feeding a loyalty program with a year of order-derived lifetime stats. Foreign headers we see weekly: "Customer ID / Kundennr / Numéro client / Email / E-Mail / Correo / Courriel / Vorname / Prénom / Nombre / Nachname / Nom / Apellido / Telefon / Téléphone / Teléfono / Default Shipping / Lieblings-Lieferadresse / Anzahl Bestellungen / Nombre de commandes / Número de pedidos / Lifetime Value / Umsatz Gesamt / Chiffre d'affaires total / Ricavi totali". The cross-platform header coverage is heavy on commerce-specific vocabulary that does not appear elsewhere in the catalogue.

Schema

The canonical column set, with the type each row carries, whether it is required, the field-level validators that fire on commit, and the multilingual header hints the cascade resolves against.

ColumnTypeRequiredValidatorsHints
idstringyes
emailemailyesemaile-mail · mail · correo · courriel
first_namestringvorname · prenom · prénom · nombre · given name
last_namestringnachname · nom · cognome · apellido · surname
phonephonephonetelefon · téléphone · telefono · phone · mobile
default_shipping_address_idstring
created_atdate
lifetime_ordersnumberanzahl bestellungen · nombre de commandes · numero ordini · número de pedidos
lifetime_valuenumberlifetime value · umsatz gesamt · chiffre d'affaires total · ricavi totali · valor total

How AdaptivMapr maps your headers to this template

Five layers run in order, cheapest first. Layer 1 (Statistics) auto-accepts headers that have been mapped the same way across past uploads. Layer 2 (Heuristic) compares your header to the column name, the optional label, and every registered hint (DE / FR / IT / EN / ES) after a Unicode-and-punctuation-normalising pass. Layer 3 (Fuzzy) catches typos and reordered words. Layer 4 (Semantic) uses cached embeddings to catch the long tail of paraphrases. Layer 5 (LLM) only fires on genuinely ambiguous columns, constrained to the template’s allowed column set so it cannot invent a field. When a layer auto-accepts, the lower-cost layers below it never run — that is the cost lever.

REST · POST /v1/uploads

Pass the template_id; the cascade picks up the rest.

curl -X POST https://api.adaptivmapr.com/v1/uploads \
  -H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \
  -F "template=customers_v1" \
  -F "file=@your_data.csv"

The canonical template definition is read-only at GET /v1/templates/customers_v1.

MCP · Cursor / Claude Desktop

Drop AdaptivMapr into your IDE. Schema-only calls are free and unlimited.

// In Cursor or Claude Desktop with the AdaptivMapr MCP server installed:
adaptivmapr.match_headers({
  template: "customers_v1",
  headers: ["id", "email", "first_name", "last_name"]
})
MCP install instructions →

FAQ — Customers CSV import

How do I model B2B customers (company accounts)?

Use the CRM Accounts template alongside Customers — the e-commerce row is person-level; B2B accounts are company-level. Link via a custom field on a forked Customers row.

Can lifetime_orders and lifetime_value be derived?

They can be left null on import and computed downstream. The template carries them if the source ships them; otherwise they stay null.

What about customer tags / segments?

Add a `tags` array field via a fork. The canonical row stays narrow because tag taxonomies vary too much across teams.

How do lifetime_orders and lifetime_value stay in sync with the order history?

They do not, automatically — the values reflect the moment of import. Most teams re-derive both at warehouse-load time from the orders table and overwrite the customer row periodically.

Keep exploring

Browse other templates in the E-commerce pack