Docs

CSV import reference

Exact columns for the seven AXIOTRA import files: orders, payments, refunds, shipments, inventory, costs and fees. Required fields, formats, example rows.

How import works

CSV is the data path into a workspace today. Direct Shopify, Amazon and Stripe connections are in development. You upload one file per kind (orders, payments, refunds, shipments, inventory, costs, fees), the rows are validated line by line, and every finding is recomputed after each upload. The detectors run on your ledger exactly as they run on the public example.

Each file needs a header row. Header names are matched after lowercasing and replacing spaces with underscores, so a column called Order ID is read as order_id. Column order does not matter and extra columns are ignored. A file may be at most 8 MB; split larger exports by month. Members with the viewer role cannot import.

Re-importing is safe. Orders and payments are matched on source plus external id and updated in place. Refunds and shipments are replaced by id. An inventory row replaces the earlier snapshot for the same SKU, source and location. A cost row with a later effective_from supersedes the previous cost instead of rewriting history.

If a row fails validation it is reported with its line number and skipped; the rest of the file is still imported. If a required column is missing from the header, nothing is imported and the message names the missing columns.

Formats shared by every file

source: one of shopify, amazon, stripe, csv or warehouse. Use warehouse for your 3PL, WMS or ERP stock file; it is treated as the inventory authority. Use csv for anything that has no better label.

Amounts: decimal with at most two places, for example 129.00. A leading currency symbol, thousands separators and spaces are stripped, so $1,234.56 is accepted. Negative values are allowed but should be avoided; enter refunds and fees as positive amounts in their own files.

Timestamps: ISO 8601 with a zone is safest, for example 2026-08-02T10:14:00Z or 2026-08-02 10:14:00 -0400. A timestamp without a zone is read as UTC. Slash dates such as 08/02/2026 are parsed month first; convert them to ISO before uploading to avoid ambiguity.

Quantities are whole numbers, zero or above. Booleans accept 1, true, yes or y; anything else is false. Currency is an ISO code such as USD. When a row leaves currency empty, the organization reporting currency is used. Money is stored as exact minor units, never as floating point.

orders

Required: order_id, source, placed_at, sku, qty, unit_price, total. Optional: title, discount, tax, shipping, currency, status, customer_ref, name.

One row per line item. Rows that share order_id and source are grouped into one order, so an order with three SKUs is three rows with the same order_id. Order-level values (total, discount, tax, shipping, status, placed_at) are taken from the first row of the group, but placed_at and total must be present on every row. Gross is recomputed as the sum of qty × unit_price across the lines.

Example: order_id,source,placed_at,sku,qty,unit_price,total,discount,tax,shipping,currency,status followed by #1001,shopify,2026-08-02T10:14:00Z,TRAIL-BOOT-9,1,120.00,129.00,0,0,9.00,USD,paid. Status defaults to paid when empty.

payments

Required: payment_id, source, amount, captured_at. Optional: order_id, fee, currency, status.

amount is what the buyer paid for that capture, before processor fees. Put the processor fee in fee. order_id must equal the order_id used in the orders file for the same sale; that string match is how a capture is attributed to an order. A payment without order_id is imported as unattributed cash and will be reported as a processor payment with no commerce order.

Example: payment_id,source,order_id,amount,fee,currency,status,captured_at followed by ch_3P9x,stripe,#1001,129.00,4.04,USD,succeeded,2026-08-02T10:15:00Z.

refunds

Required: refund_id, source, order_id, amount, issued_at. Optional: currency, status, return_received, restocked.

return_received and restocked are the two booleans the refund detector reads. A row with return_received true and restocked false means the unit came back and was never put on the shelf. If your returns system does not export a restock flag, leave the column out and the detector will not raise refund findings; it does not guess.

Example: refund_id,source,order_id,amount,currency,status,issued_at,return_received,restocked followed by re_1,stripe,#1001,129.00,USD,refunded,2026-08-09T08:00:00Z,true,false.

shipments

Required: shipment_id, source, order_id, status. Optional: tracking, shipped_at, delivered_at.

The fulfillment detector looks for the literal status marked_shipped combined with an empty tracking value. Use marked_shipped for shipments your platform reports as fulfilled without a carrier reference, and shipped or delivered for the rest. shipped_at and delivered_at become timeline events when present.

Example: shipment_id,source,order_id,status,tracking,shipped_at,delivered_at followed by shp_1,shopify,#1001,delivered,1Z999,2026-08-03T09:00:00Z,2026-08-05T14:00:00Z.

inventory

Required: sku, source, on_hand, as_of. Optional: title, location, available, reserved, committed, incoming, damaged, return_pending, sellable, opening_on_hand.

Each row is a snapshot of one SKU in one source at one moment. Upload one row per SKU per source: the warehouse count and the Shopify or Amazon count for the same SKU, taken on the same day. available defaults to on_hand when omitted. location defaults to the source name.

opening_on_hand is the count at the start of the period covered by your orders file. When it is present, expected stock is opening + returns restocked − units sold; when it is absent, the warehouse row is used and the expectation is warehouse on_hand plus units sold since. Reserved units from the warehouse row are subtracted from expected available before it is compared with each storefront.

Example: sku,title,source,location,on_hand,available,reserved,as_of,opening_on_hand with TRAIL-BOOT-9,Trail Boot Size 9,warehouse,WH-1,113,110,3,2026-08-31T00:00:00Z,140 on one row and TRAIL-BOOT-9,Trail Boot Size 9,shopify,online,111,111,0,2026-08-31T00:00:00Z, on the next.

costs

Required: sku, cost. Optional: currency, effective_from, effective_to, title, list_price.

cost is the landed unit cost used for contribution margin and for the stranded-COGS part of refund findings. effective_from lets a SKU carry several costs over time; when it is empty the cost applies from the beginning. list_price is optional and only used when a SKU never appears in an order.

Example: sku,title,cost,currency,effective_from followed by TRAIL-BOOT-9,Trail Boot Size 9,43.00,USD,2026-01-01.

fees

Required: fee_id, source, kind, amount, charged_at. Optional: order_id, currency.

kind is a free label such as referral, fba, payment or subscription. Duplicate detection groups rows by source, order_id, kind and amount, so two rows with the same four values are reported as a duplicate charge. The Amazon margin check reads rows with kind referral for each order. Fees without order_id are imported but never matched to a sale.

Example: fee_id,source,kind,amount,currency,order_id,charged_at followed by fee_77,amazon,referral,18.00,USD,113-2948014,2026-08-02T11:00:00Z.

Which files each detector needs

Payment and order mismatch: orders and payments. Every order without a payment row is reported as an order with no captured payment, so import payments right after orders and read the findings once both are in. Amount differences are reported per payment; unattributed captures are reported per payment row without order_id.

Inventory divergence: an inventory file with a warehouse row and at least one shopify or amazon row per SKU, plus orders for the period. Exposure is the unit gap multiplied by contribution margin, which needs a cost row; without cost the finding is still raised and money at risk is UNKNOWN.

Refund not restocked: refunds with return_received and restocked. Adding orders links the refund to its SKU, and adding costs turns the stranded COGS into a number. Fulfillment mismatch: shipments only. Duplicate fees: fees only. Negative contribution on Amazon: amazon orders plus costs, improved by referral fee rows and payment rows carrying fee.

Payout discrepancy has no CSV file today. Payout records are only produced by the public example and by the Stripe connection that is in development, so that detector does not raise findings on imported ledgers yet.