Use this guide if you need to bring sales data into Kintsugi manually, for example, migrating historical transactions from another system, or reporting data from a platform Kintsugi doesn't natively integrate with.
When to use this instead of a native integration?
If your sales platform (Shopify, Stripe, NetSuite, and others) is on Kintsugi's supported integrations list, connect it directly. It'll stay in sync automatically. Save CSV uploads for platforms without a native connection, or for one-time historical imports. Note that manually uploaded transactions stay in Kintsugi only; they don't sync back to your source platform, so keep customer IDs consistent to avoid duplicate records later.
Your Kintsugi account.
Your sales data exported as a CSV file, UTF-8 encoded.
A few minutes to map your columns to Kintsugi's template. This is the step that prevents almost all upload errors
Login to Kintsugi.
Navigate to Data Sources.
Click File Upload Template.
Click the download icon to get the template.
Always start from this template. It guarantees your file has the column headers Kintsugi expects.
There are required fields that should be filled out accordingly. Check out the table below; required fields are marked in red. Missing any of them is the #1 cause of upload errors, so check these first if something doesn't go through.
Date Formatting Tip
Dates need the format YYYY-MM-DDTHH:MM:SS. If you're working in Excel or Google Sheets, use a formula like this, just replace A2 with whichever cell holds your date:
=TEXT(A2,"YYYY-MM-DD") & "T" & TEXT(A2,"HH:MM:SS")You can optionally include a UTC offset (e.g., 2025-02-28T23:00:00-05:00). If you don't include one, Kintsugi assumes UTC. Either way, Kintsugi files the transaction under the local date it occurred. For example, a timestamp of 2025-02-28T23:00:00-05:00 is stored as:
Field | Value | Meaning |
|---|---|---|
| 2025-02-28 | Local transaction date |
| 2025-03-01 04:00:00 | UTC conversion |
| -05:00 | Local offset |
For a deeper walkthrough of every column, see this field-mapping reference sheet.
Use the table below to match your data to the Kintsugi template columns:
| Required |
|
related_external_id | Conditional | Required when transaction_type is FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE; optional otherwise. Must contain only alphanumeric characters, underscores, and hyphens. |
transaction_external_id | Yes | Unique ID for the transaction. Must only contain alphanumeric characters, underscores, and hyphens. |
status | Yes | Options: COMMITTED (default), PENDING, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID, ARCHIVED. Associated credit notes for refunds are required. Must not be left blank, as an empty string causes a validation error. |
date | Yes | Date the transaction occurred. Use standard date format YYYY-MM-DDT00:00:00. |
currency | Yes | Supports all ISO 4217 currency codes (USD, CAD, EUR, GBP, etc.). If not provided, defaults to USD. An empty string causes a validation error. |
description | No | Description of the transaction. Max 1000 characters. |
customer_id | Yes | Unique ID for the customer. Must only contain alphanumeric characters, underscores, and hyphens. Max 100 characters. |
customer_name | No | Name of the customer. Max 200 characters. |
customer_email | No | Email of the customer. Must be a valid email format. Max 200 characters. |
marketplace | Yes | If a transaction is from a marketplace facilitator (True/False). Default to false if missing; empty string causes validation error. |
ship_to_phone | No | Shipping address phone. Allows numerical values, space, "-", "+", "x." Max 50 characters. |
ship_to_street_line_1 | No | Shipping address line 1. Max 1000 characters. |
ship_to_street_line_2 | No | Shipping address line 2. Max 1000 characters. |
ship_to_city | No | Shipping city. Numerical values not allowed. Max 1000 characters. |
ship_to_state | Conditional | Shipping state. 2-letter state abbreviation. Required if ship_to_country is US or CA, but not when you only provide the bill_to address. |
ship_to_postal_code | Conditional | Shipping postal code. Must use an accurate postal code based on the state. Required if bill_to_postal_code and bill_to_country are empty. |
ship_to_country | Conditional | Shipping country. “US” and “CA” are allowed. Required if bill_to_postal_code and bill_to_country are not provided. |
bill_to_phone | No | Billing phone. Numerical values, space, "-", "+", "x" allowed. Max 50 characters. |
bill_to_street_line_1 | No | Billing address line 1. Max 1000 characters. |
bill_to_street_line_2 | No | Billing address line 2. Max 1000 characters. |
bill_to_city | No | Billing city. Numerical values not allowed. Max 100 characters. |
bill_to_state | Conditional | Billing state. 2-letter state abbreviation. Required if bill_to_country is US or CA, but not when you only provide the ship_to address. |
bill_to_postal_code | Conditional | Billing postal code. Only 4 or 5-digit numeral value. Include “0” in the beginning if it’s part of the postal code, like in MA, CT, and RI. Required if ship_to_postal_code and ship_to_country are not provided. |
bill_to_country | Conditional | Billing country. If not provided, defaults to US. Required if ship_to_postal_code and ship_to_country are not provided. |
line_item_id | No | Unique ID of the transaction item. Defaults to ‘None’ when empty. Max 200 characters. |
product_external_id | Yes | Unique ID of a product stored in your order management or billing system. Must only contain alphanumeric characters, underscores, hyphens, and spaces. Max 200 characters. |
product_name | No | Name of the product. This field helps categorize the product accurately. Defaults to ‘None’ when left empty. Max 200 characters. |
product_description | No | Description of the product. Defaults to ‘None’ when left empty. Max 1000 characters. |
amount | Yes | Final transaction amount after all discounts have been applied, but excluding tax. Format: General/Number. Must be a valid decimal number. Cannot be a negative amount or left blank. An empty string causes a validation error. |
tax_amount | Yes | Tax amount of the item. Format: General/Number. Must be a valid decimal number. Cannot be a negative amount or left blank. An empty string causes a validation error. |
quantity | Yes | Number of items sold. Should be > 0 and defaults to 1 if missing. An empty string causes a validation error. |
exempt | Yes | If the item is exempt from tax. Accepts valid boolean values (True/False, 1/0, T/F). An empty string causes a validation error. |
customer_exempt | Yes | If the customer is exempt from tax. Accepts valid boolean values (True/False, 1/0, T/F). An empty string causes a validation error. |
transaction_type | Yes | Type of the transaction. Valid values: SALE (default), FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, ARCHIVE. If not provided, defaults to ‘SALE.’ |
operation | Yes | Operation to perform on the transaction. Valid values: IMPORT (default), UPDATE, ARCHIVE. If not provided, defaults to ‘IMPORT.’ An empty string causes a validation error. |
discount_amount | No | Total discount amount applied to the transaction. If provided, must be > 0 and less than the ‘amount.’ If not provided, defaults to ‘0.00’ or ‘None. Only applicable to transactions with a discount.’ |
Save your completed file as a .CSV file
Log in to the Kintsugi App.
Navigate to Data Sources tab from the left-side menu.
Go to the File Upload section and select the original source of the data from the dropdown.
If your source is not listed, select Other.
Upload your CSV by either clicking Choose File or by dragging and dropping the file to the dropbox.
Kintsugi validates your entire file and opens Preview Mode, showing any errors (missing fields, bad formatting, wrong data types) before anything is committed. To review the full preview, scroll horizontally with Shift + scroll wheel and vertically with scrolling up and down.
If you spot any errors, go back to your CSV to fix them, then re-upload. If everything looks clean, click Upload to proceed.
Once the upload completes, you'll get a confirmation email at the address you're logged in with.
Stuck on a validation error? You don't need to wait on email. From the same screen, you can send the problematic file directly to Kintsugi support for a faster look.
For refunded or partially refunded transactions, include related_external_id and set transaction_type to PARTIAL_CREDIT_NOTE (or FULL_CREDIT_NOTE for a full refund).
Manual uploads can't be deleted outright. Instead, re-upload a row with the same transaction_external_id, set operation to ARCHIVE, and Kintsugi will archive that record. See the field-mapping reference sheet for details.
Symptom | Likely cause | Fix |
|---|---|---|
Upload rejected outright | File isn't UTF-8 encoded, or column headers were edited/reordered from the template | Re-export as UTF-8 CSV; keep the original template headers |
Row flagged in Preview Mode | A required field is blank or in the wrong format | Check the row against the Field reference table above; |
"Validation error" on a boolean field ( | Field left as an empty string instead of a valid boolean | Use |
Address fields rejected | Missing state/postal code for a US or CA address, or a postal code missing its leading zero (MA, CT, RI) | Make sure at least one complete address (ship-to or bill-to) is filled in |
Transactions look duplicated after later connecting the platform natively | The same transactions were already added via CSV upload before the native integration existed | Manual uploads don't sync back to the source platform; check for overlapping |
Can I re-upload the same file if I made a mistake? Yes. Fix the flagged rows and upload again. Preview Mode will catch anything still incorrect before it commits.
What if my platform isn't in the source dropdown list? Select Other. It won't affect how your data is processed.
Does Kintsugi support currencies other than USD? Yes. Any ISO 4217 currency code (USD, CAD, EUR, GBP, and others) is supported in the currency field.
Is there a limit to how many transactions I can upload at once? You can upload a CSV with up to 100mb file size. Very large files may take longer to validate. If you're migrating a large historical dataset, consider splitting it into smaller batches to make any errors easier to isolate.
For further concerns, we're always here to help. If you can't find the answer you're looking for, just reach out to us using the chat in the bottom right corner of your screen.