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

# Migrate customers

> Learn how to migrate customers from your old system using Masivo's REST API

<Note>
  Check the complete list of parameters and responses of the [`POST customers
      migrate`](/api-reference/customers/migrate/post) endpoint to do a migration.
</Note>

```typescript theme={null}
const data = {
  customers: [
    {
      id: "your-id", // unique per account
      name: "John Smith",
      email: "john@smith.com", // unique per account
      registration_date: "1995-02-15T00:00:00.000Z",
      metrics: {  // optional - customer metrics for different time periods (lifetime, yearly, monthly, quarterly)
        lifetime: {
          to: "2025-02-21T14:05:42.164Z",
          from: "2024-11-27T17:57:13.756Z",
          tier_id: "8f26a2be-f922-4693-a273-9d7ab317024c",
          last_visit: "2024-12-10T20:58:01.965Z",
          spend_total: 50.2,
          number_of_purchases: 10
          },
        last_year: {
          to: "2025-01-01T07:59:59.999Z",
          from: "2024-01-01T08:00:00.000Z",
          tier_id: "142b1336-ef6e-40aa-be3f-33332003bfa5",
          last_visit: "2024-12-10T20:58:01.965Z",
          spend_total: 5.2,
          number_of_purchases: 3
        },
        this_year: {
          to: "2026-01-01T07:59:59.999Z",
          from: "2025-01-01T08:00:00.000Z",
          tier_id: "8f26a2be-f922-4693-a273-9d7ab317024c",
          last_visit: "2024-12-10T20:58:01.965Z",
          spend_total: 0,
          number_of_purchases: 0
        },
        last_month: {
          to: "2025-02-01T07:59:59.999Z",
          from: "2025-01-01T08:00:00.000Z",
          tier_id: "142b1336-ef6e-40aa-be3f-33332003bfa5",
          last_visit: "2024-12-10T20:58:01.965Z",
          spend_total: 10,
          number_of_purchases: 1
        },
        this_month: {
          to: "2025-03-01T07:59:59.999Z",
          from: "2025-02-01T08:00:00.000Z",
          tier_id: "8f26a2be-f922-4693-a273-9d7ab317024c",
          last_visit: "2024-12-10T20:58:01.965Z",
          spend_total: 0,
          number_of_purchases: 0
        },
        updated_at: "2025-02-21T14:05:42.164Z",
        last_quarter: {
          to: "2025-01-01T07:59:59.999Z",
          from: "2024-10-01T07:00:00.000Z",
          tier_id: "142b1336-ef6e-40aa-be3f-33332003bfa5",
          last_visit: "2024-12-10T20:58:01.965Z",
          spend_total: 0,
          number_of_purchases: 0
        },
        this_quarter: {
          to: "2025-04-01T06:59:59.999Z",
          from: "2025-01-01T08:00:00.000Z",
          tier_id: "8f26a2be-f922-4693-a273-9d7ab317024c",
          last_visit: "2024-12-10T20:58:01.965Z",
          spend_total: 0,
          number_of_purchases: 0
        },
        last_semester: {
          to: "2025-01-01T07:59:59.999Z",
          from: "2024-07-01T07:00:00.000Z",
          tier_id: "142b1336-ef6e-40aa-be3f-33332003bfa5",
          last_visit: "2024-12-10T20:58:01.965Z",
          spend_total: 10,
          number_of_purchases: 1
        },
        this_semester: {
          to: "2025-07-01T06:59:59.999Z",
          from: "2025-01-01T08:00:00.000Z",
          tier_id: "8f26a2be-f922-4693-a273-9d7ab317024c",
          last_visit: "2024-12-10T20:58:01.965Z",
          spend_total: 0,
          number_of_purchases: 0
        },
      },
      balance: [
        {
        amount: 2, // the amount of the balance item
        brand_id: null, // the id of the brand that owns the reward of this balance item.
        expiration_date: null, // the expiration date of the balance item
        reward_id: "b2bc86ad-5ccd-4fea-95fd-322a4a8f3f43",
        channel_id "e-commerce2", // optional, it has to already exist in your account
        funded_by: "marketing", // optional, who funded the rewards used in this balance item
        issued_at: "2025-01-05T00:00:00.000Z" // optional, the date when the balance item was originally issued. Defaults to right now.
        store_id: "cfc" // optional, it has to already exist in your account
       }
      ],
      devices: [
        {
          device_token: "fcm-token-123456789", // the unique token that identifies the device (given by firebase)
          device_info: {
            platform: "ios", // the platform of the device (ios, android, web, windows, macos)
            model: "iPhone 13", // the model of the device
            osVersion: "15.4" // the operating system version of the device
          },
          expires_at: "2025-12-31T23:59:59.999Z", // the date when the device token expires
          created_at: "2024-01-01T10:00:00.000Z" // the date when the device was registered
        }
      ]
    }
  ]
};

const response = await fetch("https://api.masivo.ai/customers/migrate", {
  method: "POST",
  headers: { Authorization: `Bearer ${accessToken}` },
  body: JSON.stringify(data)
});
```

<Warning>You must not migrate deleted customers</Warning>

### Batch Processing

Customer migrations are handled in batches. You can include **up to 1000 records per batch**. Keep in mind that:

* **Batch Size:** Ensure your migration payload does not exceed 1000 users.
* **Queuing:** Migrations are not executed instantly; they are **enqueued** for processing. You may need to wait from a few seconds to a few minutes before the changes are visible in your dashboard, depending on how busy the queue is.

<Tip>
  If you need to migrate several thousands o records, make sure you are in a
  Production account.
</Tip>

<Frame caption="Prod account badged example">
  <img src="https://mintcdn.com/trd/7W_vRQTxJHIpxqe2/images/prod-account.webp?fit=max&auto=format&n=7W_vRQTxJHIpxqe2&q=85&s=b38406bbc7c896e801c5fd7686bf5eec" width="421" height="210" data-path="images/prod-account.webp" />
</Frame>

# Migrate events

Why migrate events? Migrating events is useful when you want to bring along your customers' behavior events such as purchases.

By default, all migrated events are marked as fulfilled and do not participate in active campaigns.

<Tip>
  Unlike transactions, events can be migrated multiple times if you don’t have
  all of them available at once.
</Tip>

<Warning>This section assumes you already had migrated your customers</Warning>

<Note>
  Check the complete list of parameters and responses of the [`POST events
      migrate`](/api-reference/customers/\[id]/events/migrate/post) endpoint to
  perform a migration.
</Note>

```typescript theme={null}
const data = {
  customers: [
    {
      id: "your-customer-id",
      events: [
        {
          brand_id: null, // the brand to which the reward belongs, null if the reward does not have a brand
          issued_at: "2025-01-30T17:50:19.423+00:00",
          resolved_at: "2025-01-30T17:50:19.423+00:00",
          type: "PURCHASE",
          fulfilled: true,
          // necessary for the metrics calculation
          order: {
            purchase_id: "1",
            value: 10,
            products: [
              {
                sku: "1",
                amount: 1,
                value: 1
              }
            ],
            payment_method: "CASH"
          }
        }
      ]
    }
  ]
};

const response = await fetch(
  "https://api.masivo.ai/api/storefront/v1/customers/migrate/events",
  {
    method: "POST",
    headers: { Authorization: `Bearer ${accessToken}` },
    body: JSON.stringify(data)
  }
);
```

<Warning>You must not migrate reversed events</Warning>

### Batch Limits

* The total number of events in the batch must not exceed 1000 and each customer must have at least one event.

### Automatic Processing and Metrics

When events are migrated, the system automatically recalculates the customer's metrics and updates their tier based solely
on events with the PURCHASE type.

# Migrate transactions

What is a transaction, and why is it important to migrate them? A transaction represents the history of accumulations and redemptions.
Migrating transactions allows you to have a clear record that justifies the user's previously migrated balance, providing a transparent
explanation of why their wallet holds a specific amount.

For transactions to be processed successfully, they must match the customer's
balance. This is crucial to prevent any discrepancies or errors during the
migration. Ensure that the transactions you are migrating align with the
existing balance information of each customer.

<Warning>
  This section assumes you already had migrated your customers and events
</Warning>

<Note>
  Check the complete list of parameters and responses of the [`POST transactions
      migrate`](/api-reference/customers/migrate/transactions/post) endpoint to
  perform a migration.
</Note>

```typescript theme={null}
const data = {
  customers: [
    {
      id: "your-customer-id",
      transactions: [
        {
          brand_id: null, // the brand to which the reward belongs
          reward_id: "ec9a5bfb-c2f1-4cf0-b509-247e47b96b65",
          details: "Migrated from old system", // details about this migrated transaction
          type: "ACCUMULATION",
          issued_at: "2025-01-30T17:50:19.423+00:00",
          resolved_at: "2025-01-30T17:50:19.423Z",
          cost: null,
          event: null,
          channel_id: null,
          store_id: null,
          amount: 4 // positive if it is ACCUMULATION type
        },
        {
          brand_id: null, // the brand to which the reward belongs
          reward_id: "ec9a5bfb-c2f1-4cf0-b509-247e47b96b65",
          details: "Migrated from old system", // details about this migrated transaction
          type: "REDEMPTION",
          issued_at: "2025-01-30T17:50:19.423+00:00",
          resolved_at: "2025-01-30T17:50:19.423Z",
          cost: null,
          event: null,
          channel_id: null,
          store_id: null,
          amount: -2 // negative if it REDEMPTION type
        }
      ]
    }
  ]
};

const response = await fetch(
  `https://api.masivo.ai/api/storefront/v1/customers/migrate/transactions`,
  {
    method: "POST",
    headers: { Authorization: `Bearer ${accessToken}` },
    body: JSON.stringify(data)
  }
);
```

<Warning>
  Once transactions are migrated, you cannot migrate them again unless you first
  revert the customers' migration. This ensures data integrity and prevents
  duplicate transactions.
</Warning>

### Batch Limits

* Ensure your migration payload does not exceed 1000 transactions.

# Revert migration

Mistakes can happen during the migration process at any stage. To address this, we provide a solution through the revert customer migration endpoint.

Transactions and events cannot be reverted independently; instead, you must revert the entire customer migration. This ensures that all related data is automatically rolled back.

**Important:** Only migrated customers that have not produce a transaction can be reverted. This will also include all their related events and transactions.

<Note>
  Check the complete list of parameters and responses of the [`DEL revert
      migration`](/api-reference/customers/migrate/revert/delete) endpoint to do a
  migration.
</Note>

```typescript theme={null}
const data = {
  start_date: "2024-08-15T00:00:00.000Z", // migrated after
  end_date: "2025-05-15T00:00:00.000Z" // migrated before
};

const response = await fetch("https://api.masivo.ai/customers/migrate", {
  method: "DEL",
  headers: { Authorization: `Bearer ${accessToken}` },
  body: JSON.stringify(data)
});
```
