Argyle Link

Learn how to integrate Argyle into your Web, iOS, Android, or React Native application.

Note: this guide relates to the Argyle Link 3 version. The documentation for the previous version of Link is here. Please read through the Migrating to Link 3 article before upgrading to the new version.

Overview

Argyle Link is a front-end UI element that allows users to grant your application access to their work accounts. It can be integrated natively on iOS, Android, ReactNative, and JavaScript and can be displayed on any part of your application.

The information entered into Argyle Link by users is encrypted and Argyle securely handles the complexity of multi-factor authentication and access control, which provides a smooth user experience for your users.

Within the Argyle API, the companies or payroll platforms which hold a user's work account, are referred to as Link items.

Configuration

Argyle Link provides multiple configuration options and callbacks that will customize how this UI element will function within your application. The only argument that is mandatory when invoking Argyle Link is the pluginKey, which can be found in the Argyle Console.

By default, anytime Argyle Link is initialized, it will be treated as a new session for a new user. To ensure your users retain their previous state in Argyle Link when it is re-initialized for them, your application must use the userToken parameter.

A configuration example is displayed below. Feel free to copy-paste it into an html file, replace your_plugin_key with your own plugin_key (found in the API keys section of the Argyle Console), and give it a try.

Web Link initialization example
1<!DOCTYPE html>
2<html>
3  <head>
4    <meta charset="utf-8" />
5  </head>
6  <body>
7    <script src="https://plugin.argyle.io/argyle.web.v3.js"></script>
8    <script type="text/javascript">
9      const argyle = Argyle.create({
10        pluginKey: 'your_plugin_key',
11        apiHost: 'https://api-sandbox.argyle.io/v1',
12        // userToken: 'user_token',
13        // linkItems: ['lyft', 'uber'],
14        onAccountCreated: ({ accountId, userId, linkItemId }) => {
15          console.log('Account created: ', accountId, ' User ID:', userId, ' Link Item ID:', linkItemId)
16        },
17        onAccountConnected: ({ accountId, userId, linkItemId }) => {
18          console.log('Account connected: ', accountId, ' User ID:', userId, ' Link Item ID:', linkItemId)
19        },
20        onAccountUpdated: ({ accountId, userId, linkItemId }) => {
21          console.log('Account updated: ', accountId, ' User ID:', userId, ' Link Item ID:', linkItemId)
22        },
23        onAccountRemoved: ({ accountId, userId, linkItemId }) => {
24          console.log('Account removed: ', accountId, ' User ID:', userId, ' Link Item ID:', linkItemId)
25        },
26        onUserCreated: ({ userId, userToken }) => {
27          console.log('User created: ', userId, 'User token:', userToken)
28        },
29        onClose: () => {
30          console.log('Link closed')
31        },
32        onTokenExpired: updateToken => {
33          console.log('Token expired')
34          // generate your new token here (more info: /developer-tools/api-reference#user-tokens)
35          // updateToken(newToken)
36        }
37      })
38      argyle.open()
39    </script>
40  </body>
41</html>

See the full list of all configuration attributes at the bottom of this page.

Closing Link programmatically

Normally, Link is closed by the user but it can also be closed by calling close method of the Link instance returned by Argyle.create

User tokens

User tokens are temporary access keys that let you start Argyle Link for an existing user.

They are JWT tokens that contain an expiry date you can use to determine if you need to create a new user token. Newly issued tokens expire in 30 days. You can always decode the token to find out the exact expiration date (check exp field).

You can create user tokens using the /user-tokens endpoint.

Make sure that you request user tokens on your server-side and your client_id and client_secret are never exposed on the front-end.

Callbacks

Whenever a new account is created, the onAccountCreated callback is invoked with the accountId and userId parameters. You should store those IDs on your database and use them to retrieve the user's employment data from the Argyle API.

The onAccountUpdated callback is invoked when a user updates their credentials for an existing account.

When Argyle Link is initialized for a new user (i.e. userToken was not specified), a new user is created just before the user tries to connect their first account. This is when the onUserCreated callback is invoked with an object containing a userId and a userToken.

You should save the user ID on your database to be able to reference the user's accounts and request their user tokens from the API.

You can find the full list of all available callbacks in the Configuration Attributes section under "Callbacks".

Android integration

Android Link SDK provides a way to integrate Argyle Link into your Android app.

The SDK supports API level 21 and above (distribution stats).

Note: We recommend you to lock your app to portrait orientation.

Important: When using tools like Proguard to obfuscate your code, make sure to exclude Android Link SDK package (com.argyle.*) from the process, it may cause unexpected runtime issues otherwise. You can do this by adding this line to your proguard-rules.pro:-keep class com.argyle. { *; }

Our configuration is currently set to the following:

  • minSdkVersion = 21
  • compileSdkVersion = 28
  • targetSdkVersion = 28
  • Android Support Library = 28.0.0
  • Kotlin = 1.3+

1. Adding the SDK dependency

Gradle configuration
1dependencies {
2    implementation 'com.argyle:argyle-plugin-android-source:3.x.x'
3}

2. Creating the SDK configuration

SDK configuration
1val config = ArgyleConfig.Builder()
2  .loginWith("your_plugin_key","apiHost", "token") //token required just in JAVA. 
3  //.linkItems(arrayOf("lyft", "uber"))
4    .setCallbackListener(object : Argyle.ArgyleResultListener {
5
6  override fun onUserCreated(userToken: String, userId: String) {
7    Log.d("Result", "onUserCreated:  userId: $userId, userToken: $userToken")
8  }
9
10  override fun onAccountCreated(accountId: String, userId: String, linkItemId: String) {
11    Log.d("Result", "onAccountCreated: accountId: $accountId, userId: $userId, linkItemId: $linkItemId")
12  }
13
14  override fun onAccountConnected(accountId: String, userId: String, linkItemId: String) {
15    Log.d("Result", "onAccountConnected: accountId: $accountId, userId: $userId, linkItemId: $linkItemId")
16  }
17
18  override fun onAccountUpdated(accountId: String, userId: String, linkItemId: String) {
19    Log.d("Result", "onAccountUpdated: accountId: $accountId, userId: $userId, linkItemId: $linkItemId")
20  }
21
22  override fun onAccountRemoved(accountId: String, userId: String, linkItemId: String) {
23    Log.d("Result", "onAccountRemoved: accountId: $accountId, userId: $userId, linkItemId: $linkItemId")
24  }
25
26  override fun onAccountError(accountId: String, userId: String, linkItemId: String) {
27    Log.d("Result", "onAccountError: accountId: $accountId, userId: $userId, linkItemId: $linkItemId")
28  }
29
30  override fun onPayDistributionSuccess(accountId: String, userId: String, linkItemId: String) {
31     Log.d("Result", "onPayDistributionSuccess: accountId: $accountId, userId: $userId, linkItemId: $linkItemId")
32  }
33
34  override fun onPayDistributionError(accountId: String, userId: String, linkItemId: String) {
35     Log.d("Result", "onPayDistributionError: accountId: $accountId, userId: $userId, linkItemId: $linkItemId")
36  }  
37
38  override fun onError(error: ArgyleErrorType) {
39    Log.d("Result", "onError: error: $error")
40  }
41
42  override fun onTokenExpired(handler: (String) -> Unit) {
43    handler("new_token")
44  }
45
46  override fun onClose() {
47    Log.d("Result", "onClose")
48  }
49})
50.build()

3. Starting the flow

Starting flow
1Argyle.instance.init(config);
2Argyle.instance.startSDK(this)

Closing Link programmatically

Normally, Link is closed by the user but it can also be closed by calling Argyle.instance.close()

iOS integration

Argyle iOS SDK provides a way to integrate Argyle Link into your iOS app. Requirements:

  • iOS 11.0+
  • Xcode 11.6+
  • Swift 5+

Note: We recommend you to lock your app to portrait orientation.

1. Adding the SDK dependency

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Argyle into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'Argyle', '3.x.x'

Use pod install and pod update commands to install/update pods afterward.

Note: the imported module name changed from Argyle to ArgyleLink starting with Pod version 3.0.1

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate Argyle into your Xcode project using Carthage, specify it in your Cartfile:

github "argyle-systems/argyle-plugin-ios" == 3.x.x

2. Configuring and starting the flow

SDK configuration
1class ViewController: UIViewController {
2
3 override func viewDidLoad() {
4    _ = Argyle.shared
5      .loginWith(pluginKey: "your_plugin_key", apiHost: "https://api-sandbox.argyle.io/v1")
6      .linkItems(["amazon_flex", "uber"]) // Can be skipped if all Link items are needed
7      .resultListener(self)
8    }
9
10  @IBAction func argyleNewUser(_ sender: Any) {
11    let argyle = Argyle.shared.controller
12    argyle.modalPresentationStyle = .fullScreen
13    self.present(argyle, animated: true, completion: nil)
14  }
15}
16
17extension ViewController: ArgyleResultListener {
18
19    func onUserCreated(token: String, userId: String) {
20        print("APP: onUserCreated((token: \(token), userId: \(userId))")
21        UserDefaults.standard.set(token, forKey: EXISTING_USER_TOKEN_KEY)
22    }
23
24    func onAccountCreated(accountId: String, userId: String, linkItemId: String) {
25        print("APP: onAccountCreated(accountId: \(accountId), userId: \(userId), linkItemId: \(linkItemId))")
26    }
27
28    func onAccountConnected(accountId: String, userId: String, linkItemId: String) {
29        print("APP: onAccountConnected(accountId: \(accountId), userId: \(userId), linkItemId: \(linkItemId))")
30    }
31
32    func onAccountUpdated(accountId: String, userId: String, linkItemId: String) {
33        print("APP: onAccountUpdated(accountId: \(accountId), userId: \(userId), linkItemId: \(linkItemId))")
34    }
35
36    func onAccountRemoved(accountId: String, userId: String, linkItemId: String) {
37        print("APP: onAccountRemoved(accountId: \(accountId), userId: \(userId), linkItemId: \(linkItemId))")
38    }
39
40    func onAccountError(accountId: String, userId: String, linkItemId: String) {
41        print("APP: onAccountError(accountId: \(accountId), userId: \(userId), linkItemId: \(linkItemId))")
42    }
43
44    func onPayDistributionSuccess(accountId: String, userId: String, linkItemId: String) {
45        print("APP: onPayDistributionSuccess(accountId: \(accountId), userId: \(userId), linkItemId: \(linkItemId))")
46    }
47
48    func onPayDistributionError(accountId: String, userId: String, linkItemId: String) {
49        print("APP: onPayDistributionError(accountId: \(accountId), userId: \(userId), linkItemId: \(linkItemId))")
50    }
51
52    func onError(error: ArgyleErrorType) {
53        print("APP: onError(error: \(error.rawValue))")
54    }
55
56    func onTokenExpired(handler: @escaping (String) -> ()) {
57        handler("new_token")
58    }
59
60    func onClose() {
61        print("APP: onClose")
62    }
63}

Closing Link programmatically

Normally, Link is closed by the user but it can also be closed by calling Argyle.shared.close()

React Native integration

React Native SDK provides a way to integrate Argyle Link into your React Native app.

Requirements for iOS:

  • The minimum deployment target needs to be at least 11.0
  • Required react-native version 0.60.x+

Requirements for Android:

Important: When using tools like Proguard to obfuscate your code, make sure to exclude Android Link SDK package (com.argyle.*) from the process, it may cause unexpected runtime issues otherwise. You can do this by adding this line to your proguard-rules.pro:-keep class com.argyle. { *; }

In case of runtime issues related to okhttp3 library, note that Link SDK currently has a dependency of okhttp3:4.5.x but in case some of your dependencies use an older version (okhttp3:3.x.x) they may need updating to a version that also uses okhttp3:4.x.x . Alternatively, you may try forcing the version of the dependency as follows:

build.gradle
1configurations.all {
2    resolutionStrategy.force 'com.squareup.okhttp3:okhttp:4.5.x'
3    resolutionStrategy.force 'com.squareup.okhttp3:okhttp-urlconnection:4.5.x'
4}

1. Adding the SDK dependency

$ npm install @argyleio/argyle-plugin-react-native --save or

$ yarn add @argyleio/argyle-plugin-react-native

Update the Argyle pod with:

$ cd ios

$ pod install

$ pod update

in case not the most recent version of Argyle pod was installed.

2. Configuring and starting the flow

SDK Configuration
1import ArgyleSdk from '@argyleio/argyle-plugin-react-native'
2
3// Configure the SDK before hand, once. only call ArgyleSdk.start() when the UI is needed
4ArgyleSdk.loginWith("your_plugin_key", "https://api-sandbox.argyle.io", "")
5
6ArgyleSdk.onUserCreated(res => console.log("onUserCreated", res))
7ArgyleSdk.onAccountCreated(res => console.log("onAccountCreated", res))
8ArgyleSdk.onAccountConnected(res => console.log("onAccountConnected", res))
9ArgyleSdk.onAccountUpdated(res => console.log("onAccountUpdated", res))
10ArgyleSdk.onAccountRemoved(res => console.log("onAccountRemoved", res))
11ArgyleSdk.onAccountError(res => console.log('onAccountError', res))
12ArgyleSdk.onPayDistributionSuccess(res => console.log('onPayDistributionSuccess', res))
13ArgyleSdk.onPayDistributionError(res => console.log('onPayDistributionError', res))
14ArgyleSdk.onError(error => console.log("onError", error))
15ArgyleSdk.onTokenExpired(res => console.log("onTokenExpired", res))
16ArgyleSdk.onClose(() => console.log('onClose'))
17
18ArgyleSdk.linkItems(["uber", "lyft"]) // Can be skipped if all Link items are needed
19
20// Launch the SDK
21ArgyleSdk.start()

Closing Link programmatically

Normally, Link is closed by the user but it can also be closed by calling ArgyleSdk.close()

Configuration attributes

For visual examples of all customizable UI elements, refer to the Link customization guide.

General

pluginKey
string uuid
required

Your plugin key, which can be found in the API keys section of the Argyle Console.

apiHost
string
optional

The API host that Argyle Link should use. Defaults to production API.

userToken
string uuid
optional

By default, anytime Argyle Link is initialized, Argyle will treat this as a new session for a new user. To ensure your users retain their previous state in Argyle Link when it is re-initialized for them, your application must use the userToken parameter.

UI Elements

companyName
string
optional

Your company or app name to display in the UI of Argyle Link (e.g. "your account is now successfully connected to companyName").

The default value is your company name as entered in the Company Settings section of the Argyle Console.

introSearchPlaceholder
string
optional

Placeholder text in the search box in the Intro screen of Link.

Defaults to "Find and link your employer".

showCategories
bool
optional

Show/hide category tabs (e.g. All, Employer, Gig, Payroll).

Defaults to true.

excludeCategories
array of strings
optional

Excludes one or more categories (and their respective Link items) from the Search screen.

Possible values: employer, gig, payroll.

linkItems
array of strings
optional

Use this parameter to limit the number of Link items that your users can connect to. Provide an array of Link item IDs you want Argyle Link to display on the Search screen. The order in which you list the IDs will define the order in which they are displayed in the UI.

If you provide a single Link item ID, the Search screen will be skipped and the user will be navigated directly to the Link item Login screen.

excludeLinkItems
array of strings
optional

Use this parameter to limit the number of Link items that your users can connect to. Provide an array of Link item IDs you want Argyle Link to exclude in the Search screen.

searchScreenTitle
string
optional

The main title in the Search screen.

Defaults to "Search for your income source".

searchScreenSubtitle
string
optional

The subtitle in the Search screen.

Defaults to "Find your employer, gig platform, or payroll provider."

cantFindLinkItemTitle
optional

The title for the Don’t see your company? button when no Link item is available. By default, this button is not shown if the onCantFindLinkItemClicked callback attribute is not defined.

showBackToSearchButton
bool
optional

If set to false, hides the Return to search button in the success screen.

The default value is true.

backToSearchButtonTitle
string
optional

The title for the Return to search button in the Success screen.

exitButtonTitle
string
optional

A value to override the default title of the Done button shown in the Success screen.

showCloseButton
bool
optional

Toggles the visibility of the Close button. This flag works only on the web implementation of Argyle Link (and not on the mobile SDKs).

The default value is true.

closeOnOutsideClick
bool
optional

Toggles the closing of Link when a user clicks outside the bounds of the UI element provided by Argyle. This flag works only on the web implementation of Argyle Link (and not on the mobile SDKs).

The default value is true.

Pay Distribution

payDistributionConfig
string
optional

Argyle Link will initiate a pay distribution change process if a pay distribution configuration is provided. Pay distribution configuration describes the desired outcome of that change. For more information on changing pay distributions, please refer to the Pay Distribution Guide.

payDistributionUpdateFlow
bool
optional

If payDistributionUpdateFlow is set to true and the payDistributionConfig parameter is provided, the pay distribution update flow will be initiated right after an account gets connected.

If this is set to true but the payDistributionConfig is not set, Link will not initialize properly.

Defaults to false.

payDistributionItemsOnly
bool
optional

When set to true, only Link items that support pay distribution will be shown. For more information on changing pay distributions, please refer to the Pay Distribution Guide.

If a payDistributionConfig is provided, then only the Link items that match the parameters in the config will be shown. For example, if the payDistributionConfig allows only amount allocations and a Link item supports percent allocations only, then that Link item will not be shown.

If no payDistributionConfig is provided then all Link items that have some pay distribution support (amount and/or percent) will be shown.

The default value is false.

Callbacks

onPayDistributionSuccess
func
optional

A callback function invoked after a successful pay distribution update flow.

The function will be passed an object containing accountId, userId, and linkItemId.

onPayDistributionError
func
optional

A callback function invoked after an error occurs during the pay distribution update flow.

The function will be passed an object containing accountId, userId, and linkItemId.

onCantFindLinkItemClicked
func
optional

An optional callback triggered after the Don't see your company? button is clicked. By default, this button is not shown if the onCantFindLinkItemClicked callback attribute is not defined.

Link will close by default if this callback is defined and triggered on iOS, Android, and ReactNative SDKs. You can use the close method of the Argyle instance to close the Link Javascript SDK.

The callback function will receive an object containing a search query that was entered by the user.

onAccountCreated
func
optional

A callback function invoked immediately after a user clicks connect and a new account is created. The callback will be invoked before authenticating the account with the Link item.

The function will be passed an object containing accountId, userId, and linkItemId.

onAccountConnected
func
optional

A callback function invoked every time a new account is successfully authenticated with a Link item, including any multi-factor authentication requests. If your linkItems list contains only one Link item, it is safe to close Argyle Link at this point.

The function will be passed an object containing accountId, userId, and linkItemId.

onAccountUpdated
func
optional

A callback function invoked when a user updates their account credentials.

The function will be passed an object containing accountId, userId, and linkItemId.

onAccountRemoved
func
optional

A callback function invoked when a user removes an account.

The function will be passed an object containing accountId, userId, and linkItemId.

onUserCreated
func
optional

A callback function invoked when a new user is created. The function will be passed an object containing userId and userToken. The user object is created on the first attempt of a new user to connect an account.

onAccountError
func
optional

A callback function invoked every time an account fails to authenticate with a Link item.

The function will be passed an object containing accountId, userId, and linkItemId.

onClose
func
optional

A callback function invoked immediately after the user closes Link.

onTokenExpired
func
optional

A callback function invoked when the userToken expires.

The function will be passed another function as a parameter, which you should call with your new userToken as an argument.

Instead of using this callback, we advise checking the validity of the current token before initializing Link and generating a new one if needed.

onUIEvent
func
optional

The onUIEvent is invoked when specific UI events are activated on Link. These events are passed with a data object containing linkItem, accountId, userID, and deepLink.

Also, some events have specific properties. Please, refer to Link Analytics to know all the event-specific properties and the screen where they are activated.