Skip to main content
File transfers can be used as:

Daily data import

Main data source with scheduled daily uploads to keep your analytics up-to-date

Historical data import

Import historical data that isn’t easily available through current main sources or systems
All order types are supported — not just online. You can import retail/in-store, wholesale, and marketplace orders alongside your e-commerce data. Use the `TYPE` field to identify the sales channel (e.g., `ONLINE`, `RETAIL`, `WHOLESALE`) and `EXTERNAL_STOREFRONT_ID` to separate data by store or location.

Supported data types

Costs

Marketing costs data

Indeliveries

Incoming products

Inventory

Stock levels & product attributes

Logistics

Shipping & fulfillment costs

Orders

Customer transactions

Product Attributes

Product metadata & descriptions

Returns

Order return details
Historical data recommendation — For accurate forecasting, marketing-mix modeling, and cohort analytics, we recommend providing data going back to at least two years. Our default start date for data ingestion is January 1, 2023. The more historical data available, the better our ML models perform.

File requirements

Files must follow this naming pattern:
With optional storefront:
File names must be unique. Uploading a new file with the same name will override the existing file.If you need to upload multiple files of the same type for the same date, either:
  • Merge them into a single file before uploading, or
  • Use different dates in the filename to distinguish them
Always use yesterday’s date in the filename. Our daily import job runs each morning and only processes files whose {date} equals the previous calendar day. Naming a file with today’s date (or any future date) will cause it to be skipped, resulting in no rows being imported.
string
required
Your company name
string
required
One of the supported data types: costs, indeliveries, inventory, logistics, orders, productAttributes, returns
string
External storefront ID (optional) - assigns entire file to a specific storefront
YYYY-MM-DD
required
Last date of data in the file. For daily automated imports, this must always be set to yesterday’s date (today − 1 day). Our daily import job runs each morning and looks specifically for files whose date matches the previous calendar day — a file named with today’s date will not be picked up and will result in no data being imported.Example: If today is 2026-04-15, name your file:
Files with dates other than yesterday (e.g., for historical data backfills) require manual import by our team.
string
required
One of: .csv, .xls, .xlsx, .parquet
Each file must be placed in a folder (sFTP subdirectory or Blob Storage prefix) whose name matches the data type. The folder name is the same as the {dataType} token used in the filename.Example paths:
Multiple values are separated by a pipe (|) and the whole field must be quoted, e.g. "value1|value2|value3". Only certain fields accept multiple values — where supported, the field’s description in the schema below says so.
The order of columns in your file does not matter. Our system reads columns by their header name, so feel free to arrange them in whatever order works best for you. Just make sure the header names match the field names listed in the schemas below.

Good to know

Send COGS with your inventory or order data whenever your platform can hold it. A separate COGS file is only for cases where the cost simply does not exist in your e-commerce platform or ERP, and it comes with real trade-offs: the file is not validated, mistakes are not reported back to you, and profitability will silently be wrong until a corrected file arrives. Talk to your Dema contact before choosing this route.
If we agree it is the only option, we set up a secondary inventory source for you and confirm the exact filename to use. The COGS file is an inventory file with an extra {source} part in its name, uploaded to the inventory/ folder:
{source} is a name for this secondary source. Ideally it names where the data comes from, such as the system the costs are taken from. For example: inventory/acme_erp_inventory_2026-10-01.csv. The file replaces nothing else in your setup — stock levels, product data and orders keep coming from your normal integration, and only the cost per product is taken from the file.Columns — the fields are defined as in Inventory, with these rules for this file:Other inventory columns, such as inventoryQuantity, can be left out.
How rows are matchedA row is applied only when productId, variantNo and warehouse all match your existing data exactly. Identifiers are compared as text, so leading zeros and spaces matter. SKU and GTIN cannot be used as identifiers in this file. Rows that don’t match are ignored without being reported back to you, and the file cannot add new products or warehouses.Products the file doesn’t cover or match keep the cost from your normal integration, if there is one. Otherwise we use the same product’s cost from another warehouse that day, or its last known cost, and finally the fallback margin set in Settings → Product Cost.DatesThe date in the filename is the date the cost takes effect. For each day, we use the most recent file dated on or before that day until a newer one arrives, so the yesterday’s-date rule for daily files does not decide which file is used, and the file does not have to be sent every day. We still recommend sending it regularly — daily, or whenever costs change — because new products get no cost from this file until they are included in it.What to keep in mind
  • Send the full catalogue every time. The file is a snapshot, not a list of changes — a variant left out of the latest file goes back to the cost from your normal integration, or keeps the last cost we had for it if your integration has none, so an outdated cost can linger.
  • Keep identifiers as text. Opening the file in a spreadsheet can strip leading zeros, and those rows will not match.
  • Costs already recorded on past orders do not change on their own. Tell your Dema contact when you upload a corrected file and we will reprocess the affected period.
Certain Dema features depend on specific fields being present in your data. The table below summarises what is needed to unlock Marketing Mix Modeling (MMM) and incrementality testing.

Marketing Mix Modeling (MMM)

MMM requires a minimum of one year of historical marketing costs data to capture seasonality patterns and produce reliable channel-level recommendations. For profitability-based optimization targets (NGP2 or NGP3), COGS, returns, and fulfillment cost data must also be present.

Incrementality testing

Dema’s incrementality testing is based on geo-experiments that assign postal code zones to treatment and control groups. For this to work, your orders data must include zipCode for the markets you want to test. Without postal codes, Dema cannot construct valid treatment and control regions.The same profitability data required for MMM (historical costs, COGS, returns, and fulfillment costs) is also recommended for incrementality testing, as it enables profit-based measurement (NGP2 / epROAS) in addition to gross sales.
Contact the customer success team on Slack or Teams if you are unsure whether your existing data covers these requirements before setting up MMM or incrementality tests.
If you operate multiple storefronts, you can assign data using one of two methods:
Storefront assignment currently applies to orders and returns data types only.
Option 1: Filename-based assignmentInclude the external storefront ID in the filename. This assigns the entire file to one storefront.
Option 2: Column-based assignmentInclude the externalStorefrontId column in your data for granular per-row assignment.

Merchant mappings

Merchant mappings connect your external storefront IDs to the platform's internal storefronts. They also optionally assign country-level marketing cost data based on country codes.Setup: Provide the following JSON structure to the commercial team:
[
    {
        "externalStorefrontId": "STORE-001",
        "countries": ["SE", "NO", "DK"]
    },
    {
        "externalStorefrontId": "STORE-002",
        "countries": ["GB"]
    },
    {
        "externalStorefrontId": "STORE-003",
        "countries": ["US"]
    },
    {
        "externalStorefrontId": "STORE-004",
        "countries": []
    }
]
string
required
Your external storefront identifier. Can be any string but preferably something that represents the storefront.
array
Array of ISO 3166 country codes (2 letters) for assigning marketing cost data. Use an empty array [] if no country filtering is needed.

Setup instructions

Choose your preferred method for uploading files to our platform:

sFTP

Direct upload via secure FTP

Azure Blob Storage

Cloud storage integration with event-driven processing
Contact our customer success team to receive your dedicated sFTP credentials and server details. Once configured, you can upload files directly to your designated folder, and our system will automatically process them.
Request your sFTP credentials through Slack or Teams.

Data schemas

When importing examples into Google Sheets or similar tools, verify that numbers are not malformatted. Pay special attention to decimal points and thousand separators.

Costs

Marketing costs data for campaign tracking and ROI analysis.
Upload folder: costs/
See available channel groups and channels for valid values. See Storefront assignment for country-based storefront mapping.

Indeliveries

Track incoming product deliveries to your warehouses.
Upload folder: indeliveries/

Inventory

Stock levels and cost — the dynamic part of a product record. To get complete product coverage, pair this with the static metadata sent via Product Attributes (name, brand, category, etc.); the two data types are joined on product/variant. See COGS priority for how cost values are resolved.
Upload folder: inventory/
The filename date must be yesterday’s date, not today’s.Both the product and product inventory extractors apply a built-in −1 day date shift: the file is generated today but must be named with yesterday’s date to be picked up by our daily import job.A file named with today’s date (e.g. acme_inventory_2026-04-15.csv) will not be processed and will result in “No rows to insert”.
Each row should have a unique productId-variantNo-warehouse combination. Aggregate inventory quantities per warehouse location.
The current inventory format — only the stock-level and cost fields.

Fields


Logistics

Shipping and fulfillment costs associated with orders.
Upload folder: logistics/
The system supports both outbound shipments to customers and return shipments from customers.

Orders

Customer transaction data including order details and line items. See COGS priority for how cost values are resolved.
Upload folder: orders/

How order data should be structured

Each row represents a unique order line, identified by the combination of orderId, productId, and variantNo.
Required:
Required:Tax fields (one required):
Include these fields to record returns directly in your orders file.Required (when including returns):
Order header level:Order line level:

Product Attributes

A complete product record requires both Product Attributes and Inventory. Even if stock levels aren't important to you, both tables must be sent — they are separate data types joined on product/variant. Product Attributes holds the static details (name, brand, category, description, etc.), while Inventory holds the dynamic values (stock levels, cost). Send product metadata here, not in the Inventory table.
Product metadata including names, categories, and descriptive attributes for your catalog.
Upload folder: productAttributes/
Like inventory files, product attribute files generated by the product extractor use a −1 day date shift. Always name the file with yesterday’s date, not today’s.
Each row should have a unique productId-variantNo combination.

Required fields


Returns

Returns can be sent in three ways (listed in preferred order):
Upload folder: returns/

1. Part of orders

Include return fields directly in your orders data

2. Referenced return

Separate file with order reference

3. Unreferenced return

Separate file without order reference
Returns that link back to an original order for complete tracking.
Each row should have a unique orderId-productId-variantNo combination. Aggregate returned quantities and include only returns since your last upload.
Each return file should contain the latest cumulative state of all returned items for each order. We use snapshot logic, meaning each file replaces the previous state rather than adding to it.Example:

Need help?

Contact support

Get in touch with our customer success team through Slack or Teams

Storefront assignment

Configure storefront and merchant mappings