> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withsotto.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Purchase import CSV

> Import order and line-item data into Sotto.

The purchase import ingests order and transaction data. **Each row represents a
single line item.** Orders with multiple items have multiple rows that share the
same `order_id` and `total_price`.

<Note>
  **Delivery:** place the file in the SFTP inbound directory provisioned for
  your account. Sotto picks up new files automatically and routes them by their
  filename prefix — a file must start with `purchase` (or `order`) to be
  processed as a purchase import. Files whose name doesn't match a known type
  are not processed.
</Note>

## File requirements

| Property       | Value                                                |
| -------------- | ---------------------------------------------------- |
| Format         | CSV (comma-separated values)                         |
| Encoding       | UTF-8                                                |
| Filename       | Prefixed with `purchase_` (or `order_`)              |
| Delimiter      | Comma (`,`)                                          |
| Text qualifier | Optional; required only for values containing commas |
| Header row     | Required. Optional columns may be omitted entirely.  |
| Date format    | ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`)                    |
| Phone format   | E.164 (e.g. `+15551234567`)                          |

## Columns

| Column                    | Required     | Type     | Description                                                                        | Example                |
| ------------------------- | ------------ | -------- | ---------------------------------------------------------------------------------- | ---------------------- |
| `order_id`                | **Yes**      | String   | Unique identifier for the order in your system.                                    | `1001`                 |
| `created_at`              | **Yes**      | DateTime | Order creation timestamp (ISO 8601).                                               | `2023-11-27T14:30:00Z` |
| `total_price`             | **Yes**      | Decimal  | Total order value incl. tax and shipping. Repeat for every line item in the order. | `125.50`               |
| `product_title`           | **Yes**      | String   | Product name.                                                                      | `Super Widget`         |
| `quantity`                | **Yes**      | Decimal  | Quantity purchased.                                                                | `2`                    |
| `price`                   | **Yes**      | Decimal  | Price per unit (not the line total).                                               | `25.00`                |
| `order_name`              | No           | String   | Customer-facing order number.                                                      | `#1001`                |
| `source_name`             | No           | String   | Purchase origin.                                                                   | `Shopify`              |
| `location`                | No           | String   | Where the order was placed (e.g. a retail store).                                  | `Soho`                 |
| `customer_email`          | Conditional¹ | String   | Customer email address.                                                            | `jane.doe@example.com` |
| `customer_phone`          | Conditional¹ | String   | Customer phone number (E.164). Preferred identifier.                               | `+15551234567`         |
| `customer_third_party_id` | Conditional¹ | String   | Your unique customer identifier.                                                   | `CUST-12345`           |
| `customer_first_name`     | No           | String   | Customer first name.                                                               | `Jane`                 |
| `customer_last_name`      | No           | String   | Customer last name.                                                                | `Doe`                  |
| `customer_dob`            | No           | Date     | Customer date of birth (`YYYY-MM-DD`).                                             | `1990-01-15`           |
| `sms_opt_in`              | No           | Boolean  | Whether the customer opted in to SMS during this purchase (case-insensitive).      | `TRUE`                 |
| `billing_zip`             | No           | String   | Billing/shipping ZIP (used for timezone).                                          | `90210`                |
| `billing_city`            | No           | String   | City.                                                                              | `Beverly Hills`        |
| `billing_state`           | No           | String   | State/province code.                                                               | `CA`                   |
| `line_item_id`            | No           | String   | Unique identifier for this line item.                                              | `987654321`            |
| `product_id`              | No           | String   | Product identifier in your system.                                                 | `Prod-123`             |
| `variant_title`           | No           | String   | Product variant name.                                                              | `Red / Large`          |

<Info>
  ¹ **Customer identification:** at least one of `customer_phone`,
  `customer_third_party_id`, or `customer_email` must be present per row.
  Phone number is preferred for matching accuracy.
</Info>

## Processing rules

### Customer matching

Customers are matched in priority order:

1. `customer_phone` *(recommended)*
2. `customer_third_party_id`
3. `customer_email`

If a match is found, the existing customer is updated with any new information.
If no match is found:

* **With `customer_phone`** — a new customer record is created.
* **Without `customer_phone`** — the purchase is recorded but not attributed to a
  customer (no record is created).

### SMS consent

`sms_opt_in` reflects whether the customer opted in **during this specific
purchase**.

* `true` — the customer is marked as opted in.
* `false` or blank — existing consent is unchanged.

<Warning>
  Customers cannot opt out through the purchase workflow. A `false` value does
  **not** opt a customer out; it only means they did not opt in during this
  transaction.
</Warning>

### Location

`billing_zip` is used to determine the customer's timezone. City and state are
optional but improve segmentation.

## Example

```text theme={"dark"}
order_id,order_name,created_at,total_price,source_name,customer_email,customer_phone,customer_third_party_id,customer_first_name,customer_last_name,customer_dob,sms_opt_in,billing_zip,billing_city,billing_state,line_item_id,product_id,product_title,variant_title,quantity,price
1001,#1001,2023-11-27T14:30:00Z,125.50,Shopify,jane.doe@example.com,+15551234567,CUST-12345,Jane,Doe,1990-01-15,true,90210,Beverly Hills,CA,987654321,Prod-123,Super Widget,Red / Large,2,25.00
1001,#1001,2023-11-27T14:30:00Z,125.50,Shopify,jane.doe@example.com,+15551234567,CUST-12345,Jane,Doe,1990-01-15,true,90210,Beverly Hills,CA,987654322,Prod-456,Mega Gadget,Blue / Medium,1,75.50
1002,#1002,2023-11-27T15:45:00Z,50.00,POS,john@example.com,+15559876543,CUST-67890,John,Smith,,false,10001,New York,NY,987654323,Prod-789,Basic Item,,1,50.00
```

## Validation checklist

<Steps>
  <Step title="Required fields present">
    Every row has `order_id`, `created_at`, `total_price`, `product_title`,
    `quantity`, and `price`.
  </Step>

  <Step title="A customer identifier per row">
    At least one of `customer_phone`, `customer_third_party_id`, or
    `customer_email`.
  </Step>

  <Step title="Consistent order totals">
    Rows sharing an `order_id` have identical `total_price` values.
  </Step>

  <Step title="Correct formats">
    Timestamps use ISO 8601; phone numbers use E.164; booleans are `true`/`false`.
  </Step>
</Steps>
