# Migrate from BigCommerce

Source: https://developers.swell.is/guides/migrate-from-bigcommerce

This guide covers a code-based approach for migrating data from BigCommerce to Swell, and how to handle some of the quirks specific to BigCommerce's APIs. It's intended to accompany our [Migrate to Swell](https://developers.swell.is/guides/migrate-to-swell) guide, which covers the general order of operations, Swell IDs, custom fields, and the `$migrate` flag.

### Authentication

We'll use the BigCommerce REST API to read your store data. Create a store-level API account in your BigCommerce control panel under Settings → Store-level API accounts, with read scopes for Products, Customers, and Orders. You'll receive an access token, which authenticates via the `X-Auth-Token` header. You'll also need your store hash — the short identifier in your API path and control panel URL.

### Setup

BigCommerce's catalog and customers live on the V3 API, while orders remain on the V2 API — so we'll set up clients for both, plus a Swell client to write with:

```javascript
const axios = require('axios');
const swell = require('swell-node').createClient(
  'your-store-id',
  'your-secret-key'
);

const STORE_HASH = 'your-store-hash';
const headers = { 'X-Auth-Token': 'your-access-token' };

const bcV3 = axios.create({
  baseURL: `https://api.bigcommerce.com/stores/${STORE_HASH}/v3`,
  headers,
});

const bcV2 = axios.create({
  baseURL: `https://api.bigcommerce.com/stores/${STORE_HASH}/v2`,
  headers,
});
```

Both API versions paginate with `limit` and `page` parameters (up to 250 records per request). Following the recommended migration order, we'll cover products, then customers, then orders.

### Products

The V3 catalog API can return images and variants inline with `include`, which saves per-product requests:

```javascript
let page = 1;
while (true) {
  const { data: response } = await bcV3.get('/catalog/products', {
    params: { limit: 100, page, include: 'images' },
  });
  const products = response.data;
  if (!products.length) break;

  for (const product of products) {
    await swell.post('/products', {
      name: product.name,
      sku: product.sku || undefined,
      price: product.price,
      sale: !!product.sale_price,
      sale_price: product.sale_price || undefined,
      description: product.description,
      active: false,
      stock_tracking: product.inventory_tracking !== 'none',
      stock_level: product.inventory_level || 0,
      images: (product.images || []).map((image) => ({
        file: { url: image.url_zoom || image.url_standard },
      })),
      bigcommerce_id: product.id,
    });
  }

  page++;
}
```

A few things to note:

- V3 responses wrap results in a `data` property, unlike V2.
- The BigCommerce product id is retained as a `bigcommerce_id` custom field — the orders script below uses it to reconnect line items to the migrated products.
- Products are created with `active: false` so you can review them before they become visible to customers.
- Images are referenced by their BigCommerce-hosted URLs. Verify your images have been fully imported into Swell before closing the BigCommerce store.
- For products with options, fetch variants with `include: 'variants'` (or from `/catalog/products/{id}/variants`) and map their option values into Swell product `options` and `variants`. Only enable variant generation for options where stock is tracked per variation.
- BigCommerce categories are comparable to Swell categories, including nesting. They aren't assigned automatically — create your category tree in the Swell dashboard and assign products in bulk after migrating.

### Customers

```javascript
let page = 1;
while (true) {
  const { data: response } = await bcV3.get('/customers', {
    params: { limit: 100, page },
  });
  const customers = response.data;
  if (!customers.length) break;

  for (const customer of customers) {
    await swell.post('/accounts', {
      email: customer.email,
      first_name: customer.first_name,
      last_name: customer.last_name,
      phone: customer.phone || undefined,
      bigcommerce_id: customer.id,
    });
  }

  page++;
}
```

Customer addresses live in a separate collection — fetch them from `/customers/addresses` filtered by `customer_id:in` and set each account's default shipping address accordingly. As with other platforms, password hashes cannot be transferred, so customers will be prompted to reset their password the first time they log in after migration.

### Orders

Orders use the V2 API, which has two quirks: line items are a separate request per order, and dates are formatted as RFC 2822 strings rather than ISO 8601, so convert them before posting to Swell.

```javascript
let page = 1;
while (true) {
  const { data: orders } = await bcV2.get('/orders', {
    params: { limit: 100, page },
  });
  if (!orders || !orders.length) break;

  for (const order of orders) {
    const account = await swell.get('/accounts/:first', {
      bigcommerce_id: order.customer_id,
    });

    const { data: lineItems } = await bcV2.get(`/orders/${order.id}/products`);

    const items = [];
    for (const lineItem of lineItems) {
      const product = await swell.get('/products/:first', {
        bigcommerce_id: lineItem.product_id,
      });
      if (!product) continue;

      items.push({
        product_id: product.id,
        quantity: lineItem.quantity,
        price: parseFloat(lineItem.base_price),
      });
    }

    await swell.post('/orders', {
      $migrate: true,
      account_id: account?.id,
      items,
      date_created: new Date(order.date_created).toISOString(),
      bigcommerce_id: order.id,
    });
  }

  page++;
}
```

The `$migrate` flag allows setting the original `date_created` and skips validation, events, and webhooks for historical records — see the Migrate to Swell guide for its tradeoffs. Depending on your needs, you can map additional order fields such as totals, taxes, and payment status from the BigCommerce order data. To maintain order number continuity, set your starting order number under Settings → General in the Swell dashboard.

### Next steps

That covers the core BigCommerce data. For shipments, subscriptions, gift cards, and coupons, see the [Migrate to Swell](https://developers.swell.is/guides/migrate-to-swell) guide, which covers each data type in detail along with the recommended migration order.
