Unify Your Fintech Stack

Access best-in-class data providers through one seamless integration.
Start Building
A Step-by-Step Guide to Launching a Multi-Aggregator Strategy with Quiltt

Reliable access to financial data is not just important—it's mission-critical. While many companies start with a single data aggregator, this approach can lead to significant challenges:

  • Service disruptions when an aggregator experiences downtime
  • Coverage gaps for certain financial institutions
  • Limited feature availability for specific use cases
  • Regional accessibility issues
  • Increased vulnerability to pricing changes

This is where a multi-aggregator strategy comes in. By leveraging Quiltt's unified API, you can implement a robust multi-aggregator approach that provides better coverage, enhanced reliability, and an improved user experience. Let's walk through how to build this strategy step by step.

Prerequisites

Before we dive in, you'll need:

  • A Quiltt account with API access
  • Basic understanding of GraphQL. See our guide here.
  • Familiarity with financial data aggregation concepts

Don't worry if you're not an expert in all these areas—we'll explain each concept as we go.

Technology Choices

This tutorial uses pnpm as the package manager and Next.js as the web framework. However, the core concepts and integration patterns remain framework-agnostic - you can use any package manager (npm, yarn, bun) or any web framework of your choice. The key Quiltt integration concepts will remain the same.

Step 1: Understanding Quiltt's Aggregator Support

Before implementing any code, it's crucial to understand the aggregators at your disposal. Quiltt currently supports:

  • MX: Offers strong coverage of smaller institutions and credit unions across the US and Canada
  • Finicity: Boasts the most direct OAuth connections and especially strong for payments and lending use-cases
  • Akoya: Provides direct OAuth connections to hundreds of top institutions in the US
  • Plaid: Known for their developer-friendly APIs

1.1 Coverage Differences

  • Some aggregators have better coverage of regional banks
  • Others excel at connecting to major national institutions
  • International coverage varies significantly

1.2 Feature Variations

  • Account verification capabilities
  • Transaction categorization accuracy
  • Real-time balance updates
  • Investment account support

Understanding these differences will inform your implementation strategy.

Step 2: Setting Up Your Quiltt Environment

Think of your Quiltt environment as the command center for your multi-aggregator strategy. Here's how to set it up:

  1. First, create a new Next.js project (version 15 as of the writing of this tutorial):
pnpm create next-app my-quiltt-app --typescript --tailwind --appcd my-quiltt-app
  1. Install the Quiltt React SDK:
pnpm add @quiltt/react
  1. Retrieve your API Key from the Quiltt Dashboard and add it to your environment
# .env.localNEXT_PUBLIC_QUILTT_CONNECTOR_ID=your_connector_id_hereQUILTT_API_KEY=your_api_key_here

Authentication

The Quiltt React SDK requires a valid JWT token to authenticate API requests. When using useQuery and useSubscription, obtain a Session token using a server-side API call and pass it using the QuilttProvider component or useQuilttSession hook.
For detailed instructions on handling Authentication, see our Authentication Tutorial.
  1. Initialize your environment in your root layout:
// src/app/layout.tsx
import { QuilttProvider } from '@quiltt/react'

import './globals.css'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <QuilttProvider>
          {children}
        </QuilttProvider>
      </body>
    </html>
  )
}


Step 3: Implementing Multi-Aggregator Connector

Link to this section#3.1 Setting Up Your Connector

Before writing any code, you'll need to configure your connector in the Quiltt Dashboard. This will determine which aggregators and features are available to your users.

  1. Visit the Quiltt Dashboard
  2. Select your environment (sandbox or production)
  3. Create a new connector or edit an existing one
  4. Configure the connector:
    1. Set up your Authentication configuration
    2. Set up your Enrollment configuration
    3. In the Connect section:
      • Enable at least two aggregators (e.g., MX and Plaid)
      • Select at least one required feature (e.g., TRANSACTIONS)
    4. For the purposes of this tutorial, set up the ExitRedirect section to:
      • Set the Redirect URL to http://localhost:3000/login
      • Enable the option for Send Token
Connect Settings
Exit Redirect Settings

3.2 Add the Connector to your Project

Let's implement the core connection components:

The ConnectAccounts component provides a general-purpose button that launches the Quiltt connector dialog, allowing users to connect any supported financial institution:

// src/components/ConnectAccounts.tsx
'use client'

import { QuilttButton } from '@quiltt/react'
import type { ConnectorSDKOnExitSuccessCallback, ConnectorSDKOnLoadCallback } from '@quiltt/react'

export default function ConnectAccounts() {
  const handleLoad: ConnectorSDKOnLoadCallback = (metadata) => {
    console.log(`Connector ${metadata.connectorId} loaded!`)
  }

  const handleSuccess: ConnectorSDKOnExitSuccessCallback = (metadata) => {
    console.log('Connection established:', metadata.connectionId)
  }

  return (
    <QuilttButton
      connectorId={process.env.NEXT_PUBLIC_QUILTT_CONNECTOR_ID!}
      onLoad={handleLoad}
      onExitSuccess={handleSuccess}
      className="rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
    >
      Connect Account
    </QuilttButton>
  )
}

The PrefilledConnector component demonstrates how to pre-select a specific institution (Chase in this example) for a more streamlined connection experience:

// src/components/PrefilledConnector.tsx
'use client'

import { QuilttButton } from '@quiltt/react'

export default function PrefilledConnector() {
  return (
    <QuilttButton
      connectorId={process.env.NEXT_PUBLIC_QUILTT_CONNECTOR_ID!}
      institution="Chase"
      onExitSuccess={(metadata) => {
        console.log('Connection established:', metadata.connectionId)
      }}
      className="rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
    >
      Connect Chase Account
    </QuilttButton>
  )
}

3.3 Handling Authentication

After a successful connection, the Quiltt Connector redirects users to your login page with an authentication token. Let's implement the login handler:

/ src/app/login/page.tsx
'use client'

import { useEffect } from 'react'

import { useRouter, useSearchParams } from 'next/navigation'

import { useQuilttSession } from '@quiltt/react'

export default function LoginPage() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const { importSession } = useQuilttSession()

  useEffect(() => {
    const token = searchParams.get('token')
    if (!token) {
      console.error('No authentication token found')
      return
    }

    const processToken = async () => {
      try {
        const success = await importSession(token)
        if (success) {
          router.push('/connections')
        } else {
          console.error('Failed to import session')
        }
      } catch (error) {
        console.error('Error processing authentication token:', error)
      }
    }

    processToken()
  }, [importSession, router, searchParams])

  return (
    <main className="flex min-h-screen items-center justify-center">
      <div className="rounded-lg bg-white p-8 shadow-lg">
        <h1 className="mb-4 font-bold text-2xl">Processing Authentication...</h1>
        <p className="text-gray-600">Please wait while we complete your login.</p>
      </div>
    </main>
  )
}

After implementing this login page:

  1. The connector redirects to http://localhost:3000/login?token={authToken}
  2. useQuilttSession processes and stores the token
  3. Users are redirected to /connections
  4. Subsequent API requests use this token for authentication

This completes the connection flow and prepares us for accessing financial data in the next section.

Step 4: Accessing Data

The journey from initiating a connection to accessing financial data involves several key steps. Let's break this down into a clear process.

Link to this section#4.1 Connection Events

The Quiltt Connector SDK provides a comprehensive callback system that lets you track every step of the connection process. These events are crucial for implementing a robust multi-aggregator strategy, as they allow you to:

  1. Monitor which aggregator was selected for the connection
  2. Track the success rate of different aggregators
  3. Handle connection failures gracefully
  4. Manage the user experience throughout the connection flow

Here's a robust implementation of a connection manager:

// src/components/ConnectionManager.tsx
'use client'

import { useState } from 'react'

import { QuilttButton, ConnectorSDKEventType } from '@quiltt/react'
import type { ConnectorSDKCallbackMetadata } from '@quiltt/react'

interface ConnectionManagerProps {
  onConnectionEstablished?: (connectionId: string) => void
}

export default function ConnectionManager({ onConnectionEstablished }: ConnectionManagerProps) {
  const [connectionState, setConnectionState] = useState<{
    status: 'idle' | 'connecting' | 'connected' | 'error'
    message?: string
  }>({ status: 'idle' })

  // Comprehensive event handler for all connector events
  const handleEvent = (type: ConnectorSDKEventType, metadata: ConnectorSDKCallbackMetadata) => {
    console.log(`Connector event: ${type}`, metadata)

    switch (type) {
      case ConnectorSDKEventType.Open:
        setConnectionState({
          status: 'connecting',
          message: 'Connector opened',
        })
        break

      case ConnectorSDKEventType.Load:
        setConnectionState({
          status: 'connecting',
          message: `Connector ${metadata.connectorId} loaded`,
        })
        break

      case ConnectorSDKEventType.ExitSuccess:
        if (metadata.connectionId) {
          setConnectionState({
            status: 'connected',
            message: `Connection ${metadata.connectionId} established`,
          })
          onConnectionEstablished?.(metadata.connectionId)
        }
        break

      case ConnectorSDKEventType.ExitAbort:
        setConnectionState({
          status: 'idle',
          message: 'Connection process aborted',
        })
        break

      case ConnectorSDKEventType.ExitError:
        setConnectionState({
          status: 'error',
          message: 'Error establishing connection',
        })
        break
    }
  }

  return (
    <div className="space-y-4">
      <div className="flex gap-4">
        {/* Standard Connection Flow */}
        <QuilttButton
          connectorId={process.env.NEXT_PUBLIC_QUILTT_CONNECTOR_ID!}
          onEvent={handleEvent}
          className="rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
          disabled={connectionState.status === 'connecting'}
        >
          Connect Account
        </QuilttButton>

        {/* Pre-selected Institution Flow */}
        <QuilttButton
          connectorId={process.env.NEXT_PUBLIC_QUILTT_CONNECTOR_ID!}
          institution="Chase"
          onEvent={handleEvent}
          className="rounded bg-green-600 px-4 py-2 text-white hover:bg-green-700"
          disabled={connectionState.status === 'connecting'}
        >
          Connect Chase Account
        </QuilttButton>
      </div>

      {/* Connection State Display */}
      {connectionState.message && (
        <div
          className={`rounded-lg p-4 ${
            connectionState.status === 'error'
              ? 'bg-red-100 text-red-800'
              : connectionState.status === 'connected'
                ? 'bg-green-100 text-green-800'
                : 'bg-blue-100 text-blue-800'
          }`}
        >
          {connectionState.message}
        </div>
      )}
    </div>
  )
}

The key events you'll want to handle are:

  • Open: Triggered when the connector modal opens
  • Load: Fired when an aggregator is selected and loaded
  • ExitSuccess: Indicates a successful connection, providing the connectionId
  • ExitAbort: Triggered if the user cancels the process
  • ExitError: Fired if there's an error during connection

4.2 Account Data

The @quiltt/react package provides hooks for handling data fetching and caching through GraphQL. The primary hooks you'll use are:

  • useQuery: For fetching data
  • useSubscription: For real-time updates
  • useQuilttClient: For direct cache access and modifications

These hooks provide several powerful features:

  • Automatic retry logic for failed requests
  • Request batching for better performance
  • Built-in error handling
  • Real-time updates via GraphQL subscriptions
  • Smart request caching

Server-Side Data Fetching

While this tutorial uses React hooks for client-side data fetching, you can also implement your own server-side GraphQL client using fetch. This might be preferred if you need to keep sensitive data server-side or want to implement your own caching strategy. Check out our API Reference for details on implementing a custom client.

4.3 Displaying Accounts

Now we can create our accounts list component that handles both initial data loading and real-time updates:

// src/components/AccountsList.tsx
'use client'

import { gql, useQuery, useSubscription, useQuilttClient } from '@quiltt/react'

const GET_ACCOUNTS = gql`
  query GetAccounts($connectionId: ID!) {
    connection(id: $connectionId) {
      accounts {
        id
        name
        balance
        type
      }
    }
  }
`

const ACCOUNT_UPDATES = gql`
  subscription OnAccountUpdate($connectionId: ID!) {
    accountUpdate(connectionId: $connectionId) {
      id
      balance
      updatedAt
    }
  }
`

interface AccountsListProps {
  connectionId: string
}

export default function AccountsList({ connectionId }: AccountsListProps) {
  const quilttClient = useQuilttClient()
  const { data, loading, error } = useQuery(GET_ACCOUNTS, {
    variables: { connectionId },
  })

  // Subscribe to real-time balance updates
  useSubscription(ACCOUNT_UPDATES, {
    variables: { connectionId },
    onData: ({ data }) => {
      // Update cache with new balance
      quilttClient.cache.modify({
        id: quilttClient.cache.identify(data.accountUpdate),
        fields: {
          balance: () => data.accountUpdate.balance,
        },
      })
    },
  })

  if (loading) {
    return <div>Loading accounts...</div>
  }

  if (error) {
    return <div className="text-red-600">Error loading accounts: {error.message}</div>
  }

  return (
    <div className="space-y-4">
      {data?.connection?.accounts.map((account) => (
        <div key={account.id} className="rounded-lg bg-white p-4 shadow">
          <h3 className="font-semibold">{account.name}</h3>
          <p className="text-gray-600">${account.balance.toFixed(2)}</p>
          <p className="text-gray-500 text-sm">{account.type}</p>
          <p className="text-gray-400 text-xs">Updates automatically</p>
        </div>
      ))}
    </div>
  )
}

4.4 Real-Time Updates

Quiltt provides real-time updates through GraphQL subscriptions. Here's how to implement comprehensive real-time functionality:

// src/components/ConnectionMonitor.tsx
'use client'

import { gql, useSubscription, useQuilttClient } from '@quiltt/react'

const CONNECTION_STATUS = gql`
  subscription OnConnectionStatus($connectionId: ID!) {
    connectionStatus(connectionId: $connectionId) {
      id
      status
      updatedAt
    }
  }
`

const SYNC_PROGRESS = gql`
  subscription OnSyncProgress($connectionId: ID!) {
    syncProgress(connectionId: $connectionId) {
      id
      progress
      stage
      estimatedTimeRemaining
    }
  }
`

interface ConnectionMonitorProps {
  connectionId: string
  onStatusChange?: (status: string) => void
}

export default function ConnectionMonitor({ connectionId, onStatusChange }: ConnectionMonitorProps) {
  const quilttClient = useQuilttClient()

  // Monitor connection status changes
  useSubscription(CONNECTION_STATUS, {
    variables: { connectionId },
    onData: ({ data }) => {
      // Update connection status in cache
      quilttClient.cache.modify({
        id: quilttClient.cache.identify({ __typename: 'Connection', id: connectionId }),
        fields: {
          status: () => data.connectionStatus.status,
        },
      })
      onStatusChange?.(data.connectionStatus.status)
    },
  })

  // Monitor sync progress
  useSubscription(SYNC_PROGRESS, {
    variables: { connectionId },
    onData: ({ data }) => {
      console.log('Sync progress:', data.syncProgress)
    },
  })

  return null // This is a monitoring component with no UI
}

This implementation provides several benefits for a multi-aggregator strategy:

  • Real-Time Updates: Get immediate notifications of data changes
  • Connection Monitoring: Track connection health across all aggregators
  • Sync Progress: Monitor data synchronization progress
  • Automatic Cache Updates: Keep UI in sync with backend data
  • Resource Optimization: No polling required

Alternative Real-Time Updates

While GraphQL subscriptions provide the most seamless real-time experience, you can also implement real-time updates using webhooks. This approach might be preferred for server-side architectures or when you need to integrate with existing event-processing systems. See our Webhooks Documentation for details on setting up webhook-based updates.

4.5 Best Practices

When working with multi-aggregator connections, follow these best practices:

  1. Cache Appropriately: Each aggregator has different rate limits and update frequencies
  2. Handle Throttling: Implement exponential backoff for retries
  3. Optimize Batch Operations: Group requests when possible
  4. Monitor Performance: Track response times and success rates per aggregator

By following this structured approach to data access, you'll be able to maintain reliable connections across multiple aggregators while providing a smooth user experience.

4.6 Integration Pages

The home page (./src/app/page.tsx) serves as the entry point for users to initiate new connections:

// src/app/page.tsx
import ConnectAccounts from '@/components/ConnectAccounts'
import PrefilledConnector from '@/components/PrefilledConnector'

export default function Home() {
  return (
    <main className="mx-auto max-w-4xl space-y-8 p-6">
      <section>
        <h1 className="mb-4 font-bold text-2xl">Connect Your Financial Accounts</h1>
        <div className="space-y-4">
          <div className="rounded-lg bg-white p-6 shadow">
            <h2 className="mb-3 font-semibold text-lg">Connect Any Account</h2>
            <ConnectAccounts />
          </div>

          <div className="rounded-lg bg-white p-6 shadow">
            <h2 className="mb-3 font-semibold text-lg">Quick Connect: Chase</h2>
            <PrefilledConnector />
          </div>
        </div>
      </section>
    </main>
  )
}

The connections page (./src/app/connections/page.tsx) provides a dashboard view of all connected accounts and their current status:

// src/app/connections/page.tsx
'use client'

import { gql, useQuery } from '@quiltt/react'

import AccountsList from '@/components/AccountsList'
import ConnectionStatusIndicator from '@/components/ConnectionStatusIndicator'
import type { Connection } from '@/types/generated/graphql'

const GET_CONNECTIONS = gql`
  query GetConnections {
    connections {
      id
      status
      institution {
        name
      }
      accounts {
        id
        name
        balance
        type
      }
    }
  }
`

export default function ConnectionsPage() {
  const { data, loading, error } = useQuery<{ connections: Array<Connection> }>(GET_CONNECTIONS)

  if (loading)
    return (
      <main className="mx-auto max-w-4xl p-6">
        <h1 className="mb-6 font-bold text-2xl">Your Connected Accounts</h1>
        <div>Loading connections...</div>
      </main>
    )

  if (error)
    return (
      <main className="mx-auto max-w-4xl p-6">
        <h1 className="mb-6 font-bold text-2xl">Your Connected Accounts</h1>
        <div className="text-red-600">Error loading connections: {error.message}</div>
      </main>
    )

  console.log(data)

  return (
    <main className="mx-auto max-w-4xl p-6">
      <h1 className="mb-6 font-bold text-2xl">Your Connected Accounts</h1>

      <div className="space-y-6">
        {data?.connections.map((connection) => (
          <div key={connection.id} className="rounded-lg bg-white p-6 shadow">
            <div className="mb-4 flex items-start justify-between">
              <h2 className="font-semibold text-lg">{connection.institution.name}</h2>

              <ConnectionStatusIndicator status={connection.status} connectionId={connection.id} />
            </div>

            <AccountsList connectionId={connection.id} />
          </div>
        ))}
      </div>
    </main>
  )
}

The connection details page (./src/app/connections/[id]/page.tsx) shows detailed information for a specific connection, including all linked accounts and repair options if needed:

// src/app/connections/[id]/page.tsx
'use client'

import { Suspense } from 'react'

import { notFound } from 'next/navigation'

import { gql, useQuery } from '@quiltt/react'

import AccountsList from '@/components/AccountsList'
import ConnectionStatusIndicator from '@/components/ConnectionStatusIndicator'

const GET_CONNECTION = gql`
  query GetConnection($id: ID!) {
    connection(id: $id) {
      id
      status
      institution {
        name
      }
    }
  }
`

interface ConnectionPageProps {
  params: {
    id: string
  }
}

export default function ConnectionPage({ params }: ConnectionPageProps) {
  const { data, loading, error } = useQuery(GET_CONNECTION, {
    variables: { id: params.id },
  })

  if (loading)
    return (
      <main className="mx-auto max-w-4xl p-6">
        <div>Loading connection details...</div>
      </main>
    )

  if (error)
    return (
      <main className="mx-auto max-w-4xl p-6">
        <div className="text-red-600">Error loading connection: {error.message}</div>
      </main>
    )

  if (!data?.connection) return notFound()

  const { connection } = data

  return (
    <main className="mx-auto max-w-4xl p-6">
      <div className="space-y-6">
        <div className="flex items-center justify-between">
          <h1 className="font-bold text-2xl">{connection.institution.name} Details</h1>

          <ConnectionStatusIndicator status={connection.status} connectionId={connection.id} />
        </div>

        <Suspense fallback={<div>Loading accounts...</div>}>
          <AccountsList connectionId={connection.id} />
        </Suspense>
      </div>
    </main>
  )
}

Step 5: Error Handling and Connection Maintenance

Financial data connections can become disrupted for various reasons:

  1. Authentication Changes
    • Password updates
    • Multi-factor authentication changes
    • Security question modifications
    • Token expiration
  2. Institution Changes
    • API updates
    • Security protocol changes
    • Service migrations
    • Backend system maintenance
  3. Aggregator Issues
    • Service disruptions
    • API deprecations
    • Rate limiting
    • Data format changes

Maintaining reliable connections requires robust error handling and repair capabilities. Let's implement comprehensive error handling:

Link to this section#5.1 Connection Status Types

First, we'll define our connection status handling using the types generated from our GraphQL schema:

ConnectionStatus

The ConnectionStatus type is generated using @graphql-codegen/typescript. For detailed instructions on setting up GraphQL Code Generator with Quiltt, see our GraphQL Tooling Tutorial.
// src/lib/connection-status.ts
import type { ConnectionStatus } from '@/types/generated/graphql'

interface StatusHandler {
  message: string
  severity: 'success' | 'info' | 'warning' | 'error'
  action: 'repair' | 'retry' | 'reconnect' | 'check_logs' | 'check_status' | 'contact_support' | null
}

export const handleConnectionStatus = (status: ConnectionStatus): StatusHandler => {
  switch (status) {
    case 'SYNCED':
      return {
        message: 'Connected and up to date',
        severity: 'success',
        action: null,
      }

    case 'SYNCING':
    case 'INITIALIZING':
    case 'UPGRADING':
      return {
        message: 'Updating connection...',
        severity: 'info',
        action: null,
      }

    case 'ERROR_REPAIRABLE':
      return {
        message: 'Connection needs repair',
        severity: 'warning',
        action: 'repair',
      }

    case 'ERROR_INSTITUTION':
      return {
        message: 'Institution temporarily unavailable',
        severity: 'error',
        action: 'retry',
      }

    case 'ERROR_PROVIDER':
      return {
        message: 'Provider error - check remote data',
        severity: 'error',
        action: 'check_logs',
      }

    case 'ERROR_SERVICE':
      return {
        message: 'Service disruption - check status page',
        severity: 'error',
        action: 'check_status',
      }

    case 'DISCONNECTED':
      return {
        message: 'Connection disconnected',
        severity: 'error',
        action: 'reconnect',
      }

    default:
      return {
        message: 'Unknown status',
        severity: 'error',
        action: 'contact_support',
      }
  }
}

5.2 Status Display Component

Let's create a reusable component to display connection status:

// src/components/ConnectionStatusIndicator.tsx
'use client'

import { QuilttButton } from '@quiltt/react'

import { handleConnectionStatus } from '@/lib/connection-status'
import type { ConnectionStatus } from '@/types/generated/graphql'

interface ConnectionStatusIndicatorProps {
  status: ConnectionStatus
  connectionId: string
}

export default function ConnectionStatusIndicator({ status, connectionId }: ConnectionStatusIndicatorProps) {
  const { message, severity, action } = handleConnectionStatus(status)

  const getSeverityStyle = () => {
    switch (severity) {
      case 'success':
        return 'bg-green-100 text-green-800'
      case 'info':
        return 'bg-blue-100 text-blue-800'
      case 'warning':
        return 'bg-yellow-100 text-yellow-800'
      case 'error':
        return 'bg-red-100 text-red-800'
    }
  }

  const renderAction = () => {
    switch (action) {
      case 'repair':
        return (
          <QuilttButton
            connectorId={process.env.NEXT_PUBLIC_QUILTT_CONNECTOR_ID!}
            connectionId={connectionId}
            onExitSuccess={(metadata) => {
              console.log('Connection repaired:', metadata.connectionId)
            }}
            className="rounded bg-yellow-600 px-4 py-2 text-white hover:bg-yellow-700"
          >
            Repair Connection
          </QuilttButton>
        )
      case 'reconnect':
        return (
          <QuilttButton
            connectorId={process.env.NEXT_PUBLIC_QUILTT_CONNECTOR_ID!}
            connectionId={connectionId}
            onExitSuccess={(metadata) => {
              console.log('Connection reconnected:', metadata.connectionId)
            }}
            className="rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
          >
            Reconnect
          </QuilttButton>
        )
      case 'check_status':
        return (
          <a
            href="https://status.quiltt.io"
            target="_blank"
            rel="noopener noreferrer"
            className="text-blue-600 hover:underline"
          >
            Check Status Page
          </a>
        )
      // Add other action handlers as needed
      default:
        return null
    }
  }

  return (
    <div className="flex items-center justify-between rounded-lg p-4">
      <div className={`rounded-full px-3 py-1 text-sm ${getSeverityStyle()}`}>{message}</div>
      {renderAction()}
    </div>
  )
}

5.3 Best Practices for Error Handling

  1. Proactive Monitoring: Monitor connection statuses and handle repairs before users encounter issues
  2. Clear Communication: Always show current connection status and provide clear next steps
  3. Automatic Recovery: Implement automatic retry logic for transient failures
  4. State Management: Track repair attempts and connection history
  5. Error Logging: Log errors with proper context for debugging and support
  6. User Guidance: Include clear instructions for user-actionable items

Link to this section#Conclusion

Implementing a multi-aggregator strategy with Quiltt is like building a resilient financial data infrastructure. By following this guide, you've created:

  • A smart routing system for optimal aggregator selection
  • Resilient connection management across providers
  • Adaptive feature support that maximizes capabilities

The implementation provides:

  • A clear entry point for connecting accounts
  • A dashboard view of all connections
  • Detailed views of individual connections
  • Automatic error detection and repair flows
  • Real-time connection status monitoring

Need help with implementation or have questions? The Quiltt team is here to support your journey.