# Migration Guide
URL: https://www.quiltt.dev/get-started/migration-guide
Description: Migrate from external providers to Quiltt with connection imports or gradual rollout strategies.
Navigation: get-started → migration-guide
Tags: Integrations, Migration
Content Length: 9k characters

Switching to Quiltt gives you access to multiple [data providers](/integrations/account-aggregation) through a single integration, [enriched financial data](/integrations/enrichment), and powerful [payment operations](/integrations/payments). Whether or not you're currently using an aggregator like [Plaid](/integrations/account-aggregation/plaid), [MX](/integrations/account-aggregation/mx),  or [Finicity](/integrations/account-aggregation/finicity), Quiltt provides a smooth migration path.

You can migrate in two ways: [import all existing connections at once](#option-1-import-existing-connections) for a complete switchover, or [gradually roll out Quiltt](#option-2-gradual-migration-with-resolvable-check) alongside your existing provider using feature detection.

## Choosing the Right Approach

| Factor | Full Import | Gradual Migration |
|--------|-------------|-------------------|
| **User Impact** | All users switch at once | Phased rollout by institution |
| **Risk** | Higher initial risk | Lower, easier rollback |
| **Best For** | Small user bases, greenfield projects | Large user bases, A/B testing |

## Prerequisites

Before migrating, ensure:

1. **Provider integration enabled** - Configure your provider (e.g., [Plaid](/integrations/account-aggregation/plaid)) in [Quiltt Dashboard](https://dashboard.quiltt.dev) with your credentials in Test [environment](/get-started/core-concepts#environments) first
2. **SDK installed** - [React](/connector/sdk/react), [React Native](/connector/sdk/react-native), etc.
3. **Authentication configured** - [Issue session tokens](/authentication/issuing-session-tokens) from your backend and wrap your app with `QuilttProvider`

## Option 1: Import Existing Connections

For a complete switchover, import your existing provider connections to Quiltt and swap your connector implementation.

### When to Use Imports

- Migrating your entire user base at once
- Replacing an existing provider integration completely
- Need to maintain existing connection history
- Want a clean cutover with minimal code changes

### Benefits of Importing

- One-time migration process
- Full feature access to Quiltt's [enrichment](/integrations/enrichment) and [payment operations](/integrations/payments)
- Centralized [connection management](/api/connections)
- Simplified codebase with single integration

### How Importing Works

1. **Import Connections via API**: Use Quiltt's [REST API](/api-reference/rest) to import existing provider connections (e.g., Plaid access tokens)
2. **Swap Connector**: Replace your existing connector UI with [Quiltt Connector](/connector)
3. **Continue Operations**: All existing connections work seamlessly in Quiltt

### Import Implementation Steps

Warning:
Before proceeding, make sure you've configured your [Plaid integration](/integrations/account-aggregation/plaid) using your existing Plaid credentials.

**1. Import Connections**

Use the Quiltt REST API to import your existing Plaid Items:

API Endpoint - POST https://api.quiltt.io/v1/profiles/{profileId}/connections/import/plaid:

```sh
curl -X POST https://api.quiltt.io/v1/profiles/{PROFILE_ID}/connections/import/plaid \
  -H "Authorization: Bearer YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '["accessToken": "access-sandbox-..."]'
```

**Required parameters**

- `accessToken`: The access token associated with the Plaid Item you want to import.

**Optional parameters**

For a full list of optional parameters (e.g., `mode`, `products`, `createdAt`), see the [REST API Reference](/api-reference/rest). The options below are generally not recommended, but are available for advanced use cases:

- `externallyManaged`: Set to `true` if you don't want Quiltt to remove the Plaid Item from upstream when it is disconnected. Your existing system will need to manage upstream cleanup to avoid charges after disconnecting from Quiltt. Defaults to `false`.
- `migrateWebhook`: Set to `false` to keep Plaid webhooks pointing to your existing system instead of Quiltt. Defaults to `true`.

Build a migration script to import all existing connections:

```typescript

async function migrateUserConnections(profileId: string, plaidAccessTokens: string[]) {
  for (const accessToken of plaidAccessTokens) {
    const response = await fetch(
      `https://api.quiltt.io/v1/profiles/${profileId}/connections/import/plaid`,
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer $[process.env.QUILTT_API_SECRET]`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({accessToken})
      }
    )

    if (!response.ok) {
      throw new Error(`Failed to import: $[response.statusText]`)
    }

    const connection = await response.json()
    console.log(`Imported connection: $[connection.id]`)
  }
}

async function runMigration() {
  const users = await getPlaidTokensFromDatabase()

  for (const user of users) {
    try {
      await migrateUserConnections(user.profileId, user.plaidAccessTokens)
      console.log(`✓ Migrated user $[user.id]`)
    } catch (error) {
      console.error(`✗ Failed to migrate user $[user.id]:`, error)
    }
  }
}
```

Warning:
Imported connections sync asynchronously. Initial data may take a few minutes to appear. Make sure to set up the appropriate [Quiltt Webhooks](/webhooks) to monitor connection status and data sync events.

**2. Update Your Frontend**

Replace your existing connector with Quiltt Connector:

Code Examples:

  ```tsx

function ConnectButton() {
  const {open} = usePlaidLink({
    token: plaidLinkToken,
    onSuccess: (public_token) => [// Exchange and store token]
  })

  return [Connect Bank]
}

```
  ```tsx

function ConnectButton() {
  return (
    

QuilttButton:
"
      onExitSuccess={(metadata) => [console.log('Connected:', metadata.connectionId)]}
      className="my-fancy-button"
    >
      Connect Bank

  )
}
```

**3. Verify Migration**

- Test that imported connections appear in [Quiltt Dashboard](https://dashboard.quiltt.dev)
- Check that [Webhooks](/webhooks) are being received
- Verify data sync is working correctly by querying the API

## Option 2: Gradual Migration with Resolvable Check

For a phased rollout, use the `useQuilttResolvable` hook to selectively migrate users while maintaining backward compatibility.

### When to Use Resolvable Check

- Testing Quiltt with a subset of users
- Running both providers in parallel
- Gradual rollout to minimize risk
- Need to maintain existing provider code during transition
- Migrating institution by institution

### Benefits of Resolvable Check

- Low-risk incremental rollout
- A/B testing capabilities
- Maintain existing provider as fallback
- Easier rollback if issues arise
- Validate institution by institution

### How Resolvable Check Works

1. **Check Institution Compatibility**: Use `useQuilttResolvable` to check if a provider's institution is supported by Quiltt
2. **Conditional Rendering**: Show [Quiltt Connector](/connector) for supported institutions, fallback to existing provider for others
3. **Gradual Expansion**: As you verify success, expand to more institutions

### Resolvable Check Implementation

Code Examples:

  ```tsx

function SmartConnectButton([plaidInstitutionId, institutionName]) {
  const [checkResolvable, isResolvable, isLoading] = useQuilttResolvable('<CONNECTOR_ID>')

  useEffect(() => {
    checkResolvable([plaid: plaidInstitutionId])
  }, [plaidInstitutionId])

  const [open: openPlaidLink] = usePlaidLink([token: plaidLinkToken,
    onSuccess: handlePlaidSuccess])

  if (isLoading) return Loading...

  if (isResolvable) {
    return (
      

QuilttButton:
"
        institution={institutionName}
        onExitSuccess={(metadata) => [console.log('Connected via Quiltt:', metadata.connectionId)]}
      >
        Connect Bank

    )
  }

  return [Connect Bank]
}

// Usage
[SmartConnectButton]
```
  ```tsx

function SmartConnectButton([plaidInstitutionId, institutionName, navigation]) {
  const [checkResolvable, isResolvable, isLoading] = useQuilttResolvable('<CONNECTOR_ID>')

  useEffect(() => {
    checkResolvable([plaid: plaidInstitutionId])
  }, [plaidInstitutionId])

  if (isLoading) return 

Text:
Loading...

  if (isResolvable) {
    return (
      

TouchableOpacity:
navigation.navigate('QuilttConnector', {institutionName})}
      >
        

Text:
Connect Bank

    )
  }

  return (
    

TouchableOpacity:
[/* Your Plaid Link implementation */]}>
      

Text:
Connect Bank

  )
}

// In your QuilttConnector screen:

  const {institutionName} = route.params || {}

  return (
    <QuilttConnector
      connectorId="<CONNECTOR_ID>"
      institution={institutionName}
      appLauncherUrl="<YOUR_HTTPS_APP_LINK>"
      onExitSuccess={(metadata) => [console.log('Connected via Quiltt:', metadata.connectionId)
        navigation.navigate('Home')]}
      onExitAbort=[() => navigation.navigate('Home')]
    />
  )
}
```

## Related Resources

- [Core Concepts](/get-started/core-concepts) - Understand Profiles, Connections, and Integrations
- [Connector Overview](/connector) - Learn about Quiltt Connector features and configuration
- [Authentication Guide](/authentication) - Set up Session tokens for secure API access
- [Webhooks](/webhooks) - Monitor connection status and data sync events
- [Reconnect Flow](/connector/reconnect) - Handle connection errors and re-authentication
- [Connectivity Integrations](/integrations/connectivity) - Finicity, MX, Plaid, and Akoya documentation
- [REST API Reference](/api-reference/rest) - Complete REST API documentation