Loading...
Loading...
Switching to Quiltt gives you access to multiple data providers through a single integration, enriched financial data, and powerful payment operations. Whether or not you're currently using an aggregator like Plaid, MX, or Finicity, Quiltt provides a smooth migration path.
You can migrate in two ways: import all existing connections at once for a complete switchover, or gradually roll out Quiltt alongside your existing provider using feature detection.
| 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 |
Before migrating, ensure:
QuilttProviderFor a complete switchover, import your existing provider connections to Quiltt and swap your connector implementation.
1. Import Connections
Use the REST API to import existing Plaid Items:
POSThttps://api.quiltt.io/v1/profiles/{profileId}/connections/import/plaidCopy endpoint URL to clipboardcurl -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-...",
"externallyManaged": true
}'
Parameters:
accessToken (required): The Plaid access token or processor tokenexternallyManaged (optional): Set to true if you don't want Quiltt to delete the connection from the provider on disconnectionmigrateWebhook (optional): Set to false to keep the current webhook configurationBuild a migration script to import all existing connections:
import { getPlaidTokensFromDatabase } from './database'
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,
externallyManaged: true
})
}
)
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)
}
}
}
Imported connections sync asynchronously. Initial data may take a few minutes to appear.
2. Update Your Frontend
Replace your existing connector with Quiltt Connector:
import { usePlaidLink } from 'react-plaid-link'
function ConnectButton() {
const { open } = usePlaidLink({
token: plaidLinkToken,
onSuccess: (public_token) => {
// Exchange and store token
}
})
return <button onClick={open}>Connect Bank</button>
}
import { QuilttButton } from '@quiltt/react'
function ConnectButton() {
return (
<QuilttButton
connectorId="<CONNECTOR_ID>"
onExitSuccess={(metadata) => {
console.log('Connected:', metadata.connectionId)
}}
>
Connect Bank
</QuilttButton>
)
}
3. Verify Migration
For a phased rollout, use the useQuilttResolvable hook to selectively migrate users while maintaining backward compatibility.
useQuilttResolvable to check if a provider's institution is supported by Quilttimport { useQuilttResolvable, QuilttButton } from '@quiltt/react'
import { useEffect, useState } from 'react'
import { usePlaidLink } from 'react-plaid-link'
function SmartConnectButton({ plaidInstitutionId, institutionName }) {
const { checkResolvable, isResolvable, isLoading } = useQuilttResolvable('my-connector-id')
const [showQuiltt, setShowQuiltt] = useState(false)
useEffect(() => {
checkResolvable({ plaid: plaidInstitutionId })
}, [plaidInstitutionId])
useEffect(() => {
if (!isLoading && isResolvable) {
setShowQuiltt(true)
}
}, [isLoading, isResolvable])
const { open: openPlaidLink } = usePlaidLink({
token: plaidLinkToken,
onSuccess: handlePlaidSuccess
})
if (isLoading) return <div>Loading...</div>
if (showQuiltt) {
return (
<QuilttButton
connectorId="my-connector-id"
institution={institutionName}
onExitSuccess={(metadata) => {
console.log('Connected via Quiltt:', metadata.connectionId)
}}
>
Connect Bank
</QuilttButton>
)
}
return <button onClick={openPlaidLink}>Connect Bank</button>
}
// Usage
<SmartConnectButton plaidInstitutionId="ins_3" institutionName="Chase" />
import { useQuilttResolvable } from '@quiltt/react-native'
import { useEffect, useState } from 'react'
import { Text, TouchableOpacity } from 'react-native'
function SmartConnectButton({ plaidInstitutionId, institutionName, navigation }) {
const { checkResolvable, isResolvable, isLoading } = useQuilttResolvable('my-connector-id')
const [showQuiltt, setShowQuiltt] = useState(false)
useEffect(() => {
checkResolvable({ plaid: plaidInstitutionId })
}, [plaidInstitutionId])
useEffect(() => {
if (!isLoading && isResolvable) {
setShowQuiltt(true)
}
}, [isLoading, isResolvable])
if (isLoading) return <Text>Loading...</Text>
if (showQuiltt) {
return (
<TouchableOpacity
onPress={() => navigation.navigate('QuilttConnector', { institutionName })}
>
<Text>Connect Bank</Text>
</TouchableOpacity>
)
}
return (
<TouchableOpacity onPress={() => {/* Your Plaid Link implementation */}}>
<Text>Connect Bank</Text>
</TouchableOpacity>
)
}
// In your QuilttConnector screen:
export const QuilttConnectorScreen = ({ route, navigation }) => {
const { institutionName } = route.params || {}
return (
<QuilttConnector
connectorId="my-connector-id"
institution={institutionName}
oauthRedirectUrl="<YOUR_HTTPS_APP_LINK>"
onExitSuccess={(metadata) => {
console.log('Connected via Quiltt:', metadata.connectionId)
navigation.navigate('Home')
}}
onExitAbort={() => navigation.navigate('Home')}
/>
)
}