Returns CSV import API
returns_v1
Import this template via API. Import return and refund records from CSV. Reason enum-bounded, status walks the RMA workflow.
30-second curl
curl -X POST https://api.adaptivmapr.com/v1/uploads \ -H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \ -F "template=returns_v1" \ -F "file=@your_data.csv"
At a glance
- Pack
- E-commerce
- FHIR resource
- —
- Risk level
- low
- Fields
- 8 (2 required, 0 validated)
Why this template?
The Returns template captures the row that closes the order loop — every refund, exchange, and warranty return. Each row carries an id, a foreign key order_id (required — every return points to an order), an optional customer_id, a reason enum (defective / wrong_item / no_longer_needed / damaged_in_shipping / other), an amount, a currency, a status enum that walks the return through requested → received → inspected → refunded / rejected, and a requested_at timestamp. E-commerce teams use this template for migrations, for monthly returns-rate reporting, and for feeding fraud-detection models that watch the requested_at / received_at gap. The reason enum is intentionally narrow — the canonical set is the cross-platform intersection, and richer taxonomies (size_too_small vs size_too_large) live in a forked template.
order_id is required because a return without an order is a chargeback or a write-off — different schema. amount is optional because some returns are exchanges with no money movement. currency is optional and inherits from the parent order in most downstream systems.
Migration scenarios & common foreign headers
Migration scenarios for the Returns template: feeding a monthly returns-rate report at executive level, importing a 3PL's RMA log for reconciliation against in-house records, migrating between order-management systems where the RMA history must survive, and seeding a fraud-detection model that watches the requested_at / received_at gap as a signal. Foreign headers we see often: "Return ID / Retoure / Retour / Devolución / Reso / Order ID / Bestellnummer / Numéro de commande / Customer / Kunde / Cliente / Grund / Raison / Motivo / Motivazione / Betrag / Montant / Importo / Monto / Status / Statut / Stato / Estado / Requested / Beantragt / Demandé / Solicitado". The reason enum walks the bounded set that supply-chain dashboards aggregate on — extending it via fork is a one-line change when retailer-specific reason codes are needed.
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.
| Column | Type | Required | Validators | Hints |
|---|---|---|---|---|
| id | string | yes | — | — |
| order_id | string | yes | — | — |
| customer_id | string | — | — | — |
| reason | enum | — | — | grund · raison · motivo |
| amount | number | — | — | betrag · montant · importo · monto · amount |
| currency | string | — | — | — |
| status | enum | — | — | — |
| requested_at | date | — | — | — |
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=returns_v1" \ -F "file=@your_data.csv"
The canonical template definition is read-only at GET /v1/templates/returns_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: "returns_v1",
headers: ["id", "order_id", "customer_id", "reason"]
})MCP install instructions →FAQ — Returns CSV import
How do I model partial returns (one item from a multi-item order)?
Returns are at the line-item level in most platforms — use a separate `returns_line_items` template (similar shape to claims line items) and link by return id.
What about exchanges that swap one SKU for another?
Model as two rows: a return for the original SKU and a new order for the replacement. The canonical Returns template is refund-shaped, not exchange-shaped.
Can a return have no associated reason?
Default to "other". The reason enum is bounded so analytics work; "other" is the catch-all when the source ships nothing.
How does the status enum map to RMA workflow tools?
The walk (requested → received → inspected → refunded / rejected) maps cleanly to Shopify's native return flow, Loop Returns, Returnly, and AfterShip Returns. Custom workflows fork the enum without touching the rest of the template.