Connection Portal
Overview
The Connection Portal is the front-end interface your users interact with to link their brokerage accounts to the SnapTrade API.
Introduction
The Connection Portal is a drop-in UI that lets your users link brokerage accounts to the SnapTrade API. It handles credential entry, MFA, reconnects, and redirects, so your app only needs to open a connection portal link and and process the connection result when users are returned to your app.
SnapTrade’s connection portal is built to run smoothly on all modern browsers and platforms, including:
- Web apps
- Native iOS
- Native Android
- React Native
Initializing
The SnapTrade connection flow begins when your user shows intent to connect their brokerage account to your app.
1
User taps Connect Account in your app.
Your app calls your backend to generate a SnapTrade connection portal login link and returns it to the client.
2
Your app opens the SnapTrade connection portal login link for the user (see Integration Methods for platform-specific best practices).
They select their brokerage and go through the login flow.
3
After successfully connecting, SnapTrade redirects the user back to your app.
4
Your backend can now fetch and store the connection details and use them to make necessary API requests for the user.
Login Link Parameters
-
connectionType (optional): Sets the level of access requested. Defaults to
read.read: Data access onlytrade: Data + trading accesstrade-if-available: Requests trading access if supported; otherwise falls back toread
-
broker (optional) - broker slug: If you display broker options in your own UI instead of using SnapTrade’s built-in selection screen, pass the broker slug here. This skips the integrations selection screen and goes directly into that brokerage’s login flow. See the integrations page
-
customRedirect (optional): Override the default redirect URL for this session.
-
immediateRedirect (optional, boolean): If true, skips the Connection Portal’s success or error screen and sends the user straight back to your app after the connection attempt, using either the default or custom redirect URL.
-
reconnect (required for reconnect flow): The UUID of a connection that needs to be re-established. Leave this empty unless you are explicitly reconnecting a disabled connections.
-
showCloseButton (optional, boolean): Set to
falseto hide the close (X) button. Useful for mobile implementations where the native WebView or browser already provides a close button. Defaults totrue.
Integration Methods
You can display the Connection Portal in your application using one of the following methods. Pick one method depending on platform and UX needs.
Embedded iframe (recommended for web apps)
Displays the portal within your application using an iframe.
Best for: Web apps - Keeping users within your app, better user experience, when you want full control over the flow.
- Example React snippet:
- Key Considerations:
- Find guidance on how to monitor window messages here.
- Your application is responsible for closing the iframe modal post connections.
- If not using
snaptrade-reactSDK, you must handle responsive sizing and closing the modal. The SDK simplifies this.
New Browser Tab
Opens the portal in a separate browser tab or popup window.
Best for: Web apps - Straightforward connection flows.
- Key Considerations:
- To determine the connection state, your application can use one of the following approaches:
- Option 1: Window messages
- Open the Connection Portal in a new window using
window.open. This is required to receive client-side window messages. - Refer to the documentation on how to listen for and handle these messages here.
- Open the Connection Portal in a new window using
- Option 2: Query parameters in redirect
- The portal will redirect back to your URL with query parameters:
- SUCCESS:
{your_redirect_url}?status=SUCCESS&connection_id={connection_id} - ERROR:
{your_redirect_url}?status=ERROR&status_code={status_code}&error_code={error_code} - ABANDONED:
{your_redirect_url}?status=ABANDONED
- SUCCESS:
- The portal will redirect back to your URL with query parameters:
- Option 1: Window messages
- You can provide a custom redirect to navigate the user back to a specific page in your app post-connection.
- Set
immediateRedirectto true in the login link to skip the connection portal’s internal finish screens and redirect immediately.
- To determine the connection state, your application can use one of the following approaches:
Mobile In-app Browser (Recommended for mobile apps)
Use SFSafariViewController on iOS, Chrome Custom Tabs on Android, or the recommended in-app browser library for React Native. This preserves browser features required by OAuth and Passkeys.
Best for: Mobile applications (React Native, native iOS/Android apps, etc.)
Implementation guides:
Window messages
We send these window messages to notify your app about user actions and the status of the connection attempt.
Your app should listen for these messages and respond accordingly, for example by showing toast notifications, performing redirects, or running any other app logic that makes sense for your use case.
-
Messages
- SUCCESS: Indicates successful institution connection. The message contains the authorization ID (same as connection id).
{status: 'SUCCESS', authorizationId: 'AUTHORIZATION_ID'}- ERROR: Sent when a connection error occurs, including an error code, status code and description.
{status: 'ERROR', errorCode: 'ERROR_CODE', statusCode: 'STATUS_CODE', detail: 'DETAIL_OF_THE_ERROR'}-
CLOSED: Sent when the user manually closes the OAuth connection window that opens in a new tab.
- Note: This message is only emitted when the connection portal is loaded inside an iframe. In other integration methods, the OAuth flow opens in the same tab as the connection portal, so closing the OAuth window also ends the entire connection portal session.
-
ABANDONED: Functions the same as
CLOSE_MODALbut only triggers for non-iframe implementations.- Example React snippet:
React Native
Authentication Flow: [Your App] → [In-App Browser] → [SnapTrade Auth] → [Redirect] → [Your App]
Redirect URL Parameters
SnapTrade redirects back to your app with these parameters:
-
Success:
status=SUCCESSconnection_id=<string>- The connection ID to use for API calls
-
Error:
status=ERRORerror_code=<string>- Error code describing what went wrongstatus_code=<number>- HTTP status code
Expo
- Configure URL scheme in
app.config.jsonorapp.json:
- Install Dependencies
- Rebuild the app after adding URL schemes
- Basic implementation
Vanilla React Native
- Configure URL scheme:
- iOS: Add to
Info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>yourapp</string>
</array>
</dict>
</array>
- Android: Add to
AndroidManifest.xml
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="yourapp" /> </intent-filter>
2. Install Dependencies
- Basic Implementation
Native iOS
Authentication Flow: [Your App] → [In-App Browser] → [SnapTrade Auth] → [Redirect] → [Your App]
Redirect URL Parameters
SnapTrade redirects back to your app with these parameters:
-
Success:
status=SUCCESSconnection_id=<string>- The connection ID to use for API calls
-
Error:
status=ERRORerror_code=<string>- Error code describing what went wrongstatus_code=<number>- HTTP status code
Implementation
- Configure URL scheme in
Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>yourapp</string>
</array>
</dict>
</array>
- Basic implementation
import SafariServices
class ViewController: UIViewController {
func openSnapTrade() {
guard let url = URL(string: "YOUR_SNAPTRADE_LOGIN_LINK") else { return }
let safariVC = SFSafariViewController(url: url)
present(safariVC, animated: true)
}
}
// In AppDelegate.swift or SceneDelegate.swift
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// Dismiss Safari View Controller
if let presented = UIApplication.shared.windows.first?.rootViewController?.presentedViewController as? SFSafariViewController {
presented.dismiss(animated: true)
}
// Parse URL
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else {
return false
}
let params = queryItems.reduce(into: [String: String]()) { result, item in
result[item.name] = item.value
}
// Handle callback
if params["status"] == "SUCCESS",
let connectionId = params["connection_id"] {
print("Connection successful: \\(connectionId)")
// Save connection_id and proceed
} else if params["status"] == "ERROR",
let errorCode = params["error_code"] {
print("Connection failed: \\(errorCode)")
// Show error to user
}
return true
}
// For iOS 13+ with SceneDelegate
func scene(_ scene: UIScene,
openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
// Handle URL same as above
}
Native Android
Authentication Flow: [Your App] → [In-App Browser] → [SnapTrade Auth] → [Redirect] → [Your App]
Redirect URL Parameters
SnapTrade redirects back to your app with these parameters:
-
Success:
status=SUCCESSconnection_id=<string>- The connection ID to use for API calls
-
Error:
status=ERRORerror_code=<string>- Error code describing what went wrongstatus_code=<number>- HTTP status code
Implementation
- Configure URL scheme in
AndroidManifest.xml, add to your main Activity:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="yourapp" />
</intent-filter>
</activity>
- Basic implementation
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Handle incoming deep link
handleIntent(intent)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
intent?.let { handleIntent(it) }
}
private fun handleIntent(intent: Intent) {
val data: Uri? = intent.data
data?.let { uri ->
val status = uri.getQueryParameter("status")
val connectionId = uri.getQueryParameter("connection_id")
val errorCode = uri.getQueryParameter("error_code")
when (status) {
"SUCCESS" -> {
println("Connection successful: $connectionId")
// Save connection_id and proceed
}
"ERROR" -> {
println("Connection failed: $errorCode")
// Show error to user
}
}
}
}
fun openSnapTrade() {
val url = "YOUR_SNAPTRADE_LOGIN_LINK"
CustomTabsIntent.Builder()
.build()
.launchUrl(this, Uri.parse(url))
}
}
Troubleshooting
Coinbase Mobile Authentication Issues
- Problem: Coinbase uses OAuth and supports Passkeys, Google, and Apple sign-in. When the portal runs inside a mobile WebView, Passkey and Google sign-in often fail. WebViews impose restrictions on third-party cookies, credential delegation, and embedded authentication flows. This breaks modern auth flows.
- Solution: We recommend using in-app browser for all integrations. It’s more secure and avoids problems like this.
Brokerage Connectivity Issue Screen
-
What it looks like: Users see a connectivity warning before reaching the login page for a specific brokerage.
-
Why it happens: SnapTrade detects degraded connectivity to that brokerage. Some users may still connect, but analytics show an unhealthy success rate.
-
How to handle:
- For users: Recommend trying again later if they cannot connect.
- For developers: No code changes are required. This is an automatic protection against poor user experience.
Brokerage Under Maintenance Screen
-
What it looks like: A warning that the selected brokerage is temporarily unavailable and the connection cannot proceed right now.
-
Why it happens:
- The brokerage is in scheduled or unscheduled maintenance.
- SnapTrade is experiencing degraded connectivity to the broker, preventing the creation of any new connections.
-
How to handle:
- For users: Recommend trying again later when the maintenance window is over.
- For developers: No code changes required. SnapTrade automatically re-enables connections when the brokerage or our service recovers.