Orders export format

Orders export lives under Reports → Orders export. Pick a date range, choose a mode, click Download. Two format modes: summary (one row per order) and line items (one row per ordered product line).

Orders are export-only via CSV — there's no CSV import flow for orders. Orders are created via the storefront, the dashboard's "+ New order" flow, or the REST API; their richer constraints (line items, stock decrement, customer linkage, price-override application) don't map cleanly to a flat CSV import.

Two modes

When it ships, the orders export will offer two download options from a single button:

Summary — one row per order

Intended for dashboards, monthly sales reports, and accounting imports that don't need line-level detail.

Columns:

orderId,createdAt,status,total,itemCount,customerEmail,customerName,poNumber,notes,shippingCity,shippingRegion,shippingCountry
ColumnDescription
orderIdThe order's unique ID, e.g. clxxorder123...
createdAtISO 8601 UTC timestamp of order creation
statusOne of SUBMITTED, CONFIRMED, SHIPPED, DELIVERED, CANCELLED
totalOrder total, 2 decimal places
itemCountCount of distinct line items (not total quantity)
customerEmailEmail of the linked customer, or blank for dashboard-created orderless-accounts
customerNameCustomer display name, or blank
poNumberPurchase order reference if supplied, else blank
notesFree-text notes on the order
shippingCityFrom the order's shipping address snapshot
shippingRegionState / region from the snapshot
shippingCountry2-letter country code from the snapshot

One row per order. Line items are collapsed into itemCount + total.

Line items — one row per ordered product

Intended for item-level analytics — top-sellers by revenue, stock reconciliation against orders, category breakdowns.

Columns:

orderId,createdAt,status,customerEmail,productSku,productName,quantity,unitPrice,lineTotal

Each order contributes N rows, one per item. orderId repeats across those rows so you can group client-side.

ColumnDescription
orderIdSame ID as above; shared across all items in one order
createdAtOrder timestamp (duplicated per row for convenience)
statusOrder status (duplicated per row)
customerEmailCustomer email (duplicated per row)
productSkuSKU of the product at the time of purchase
productNameProduct name, frozen at purchase time
quantityUnits ordered
unitPricePrice charged per unit, 2 decimals
lineTotalquantity × unitPrice, 2 decimals

Product name and SKU come from the product's current record (not a frozen snapshot) — if a product is renamed after an order is placed, the export reflects the new name.

What the export respects

  • Date range. Both the preset picker (This month / Last month / This quarter / etc.) and custom from/to dates scope the export. Orders outside the range aren't included.
  • All statuses. Every order from SUBMITTED through CANCELLED is included — cancelled orders land with their original total but carry the CANCELLED status, so you can filter client-side.
  • Every row, not just a page. The orders dashboard paginates at 25; the export ignores pagination and pulls everything in the range.
  • ISO 8601 UTC timestamps. 2026-04-16T14:22:00.000Z. Convert to local time in your spreadsheet if needed.
  • Dated filename. orders-summary-{from}-to-{to}.csv or orders-items-{from}-to-{to}.csv, where both dates are YYYY-MM-DD.

Neither export format is round-trippable — uploading one back to Distribu won't create or modify orders.

Other ways to get orders out

The dashboard export is the fastest path for accountants and one-off reports. For automated pipelines, two alternatives:

The REST API

GET /api/v1/orders returns every order with full line items, totals, customer reference, and shipping address as JSON. Page through with ?page=N&perPage=M (max 100 per page).

curl "https://your-domain.com/api/v1/orders?perPage=100" \
  -H "Authorization: Bearer dk_YOUR_API_KEY"

From there, pipe into a script to produce whatever CSV your accounting package expects. Here's a minimal Node example that generates the order-summary format from above:

import fs from "fs";

async function paginate(url, apiKey) {
  let page = 1;
  const all = [];
  for (;;) {
    const res = await fetch(`${url}&page=${page}`, {
      headers: { Authorization: `Bearer ${apiKey}` },
    });
    const { data, pagination } = await res.json();
    all.push(...data);
    if (!pagination.hasMore) break;
    page++;
  }
  return all;
}

const orders = await paginate(
  "https://your-domain.com/api/v1/orders?perPage=100",
  process.env.DISTRIBU_API_KEY
);

const header = "orderId,createdAt,status,total,itemCount,customerEmail\n";
const rows = orders.map(o =>
  [
    o.id,
    o.createdAt,
    o.status,
    o.total,
    o.items.length,
    o.customer?.email ?? "",
  ].join(",")
);

fs.writeFileSync("orders-summary.csv", header + rows.join("\n"));

Filter server-side with query params when you can — ?status=CONFIRMED&customerId=clxx... is cheaper than pulling everything and filtering in your script. See REST API → Orders endpoints for the full list of filters.

Webhooks for real-time feeds

If you'd rather have new orders pushed to you as they come in (instead of a daily pull), subscribe to the order.created and order.status_changed webhooks and write rows into your warehouse / spreadsheet as they arrive. See Webhooks → Event types.

Webhooks aren't a substitute for a bulk export (your endpoint only hears about orders placed after the webhook was registered), but they pair well with it: webhooks for "new activity today," the eventual CSV export for "everything in Q1 for the finance review."

Related


That wraps up the CSV Formats section. Next up: Billing — plans, limits, and how your subscription is managed.