---
id: build-basic-connector
title: Build a Basic SaaS Connector
pagination_label: Build a Basic SaaS Connector
sidebar_label: Build a Basic SaaS Connector
sidebar_position: 5.5
sidebar_class_name: buildBasicConnector
keywords: ['connectivity', 'connectors', 'commands', 'cli']
description: This guide will show you how to start building SaaS connectors.
slug: /connectivity/saas-connectivity/build-basic-connector
tags: ['Connectivity']
---
## Objectives
This guide will walk you through the process of building a SaaS connector. You will learn how to build a SaaS connector that connects Identity Security Cloud (ISC) to a cloud-based source called [Airtable](https://airtable.com).
In addition to learning how to build the SaaS connector, you will learn how to deploy, debug, and test it as well.
You will learn how to implement SaaS Connectivity [commands](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/connector-commands) that allow you to manage accounts on the source. You will implement these commands:
- [Test Connection](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/test-connection)
- [Account List](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/account-list)
- [Account Read](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/account-read)
- [Account Create](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/account-create)
- [Account Update](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/account-update)
- [Account Delete](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/account-delete)
- [Entitlement List](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/entitlement-list/)
- [Entitlement Read](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/entitlement-read)
Once you have learned how to build an Airtable connector, you will know how to build basic SaaS connectors. You can then customize those connectors to best suit your organization's needs.
## SaaS connectivity
[Connectors](https://documentation.sailpoint.com/saas/help/sources/index.html) are the bridges between ISC and the various source systems ISC needs to communicate with and aggregate data from. These connectors require the use of virtual appliances (VAs).
**SaaS connectors** use [SaaS Connectivity](https://developer.sailpoint.com/docs/connectivity/saas-connectivity), a framework you can use to connect ISC, a SaaS platform, to other cloud-based sources without the use of a VA as a go-between.
SaaS Connectivity provides these benefits:
- The ability to develop, debug, and test custom connectors locally, without any dependencies on ISC.
- Features you can use to customize the user interface (UI) in ways specific to the source.
- Support for modern languages and frameworks.
## Requirements
To build an Airtable connector, you will need these resources:
- [Node](https://nodejs.org/en): Node >= 18.0.0 is required to develop SaaS connectors. You can get the latest release [here](https://nodejs.org/en/download/package-manager).
- [TypeScript](https://www.typescriptlang.org/): You will need TypeScript to develop the SaaS connector and follow this guide. You can learn how to get TypeScript [here](https://www.typescriptlang.org/download/).
- [SailPoint CLI](https://developer.sailpoint.com/docs/tools/cli): The SailPoint command line interface (CLI) is a command line tool you can use to leverage the SaaS Connectivity functionality and start building SaaS connectors much more quickly and easily. Get the latest release [here](https://github.com/sailpoint-oss/sailpoint-cli/releases).
- [IDE](https://code.visualstudio.com/): Use an integrated development environment (IDE), like [VSCode](https://code.visualstudio.com/), to develop, deploy, and debug the SaaS connector. You can get the latest release [here](https://code.visualstudio.com/Download).
- [Postman](https://www.postman.com/): Postman is an API platform you can use to send test API requests. SailPoint maintains a collection of SaaS Connectivity commands in Postman that you can access [here](https://www.postman.com/sailpoint/identitynow/folder/kv75eb5/connector-commands). This collection of commands makes it quick and easy for you to test SaaS connector commands.
- [ISC](https://documentation.sailpoint.com/saas/help/setup/get_started.html): You need an ISC tenant you can connect to Airtable.
- [Airtable](https://airtable.com/): You need to create an account on Airtable, the source you are connecting to. Airtable is a cloud-based relational database platform - it is a bit like Excel, but it is useful for this example because you can send API requests to modify the data in the tables.
## Create project
To create your SaaS connector project, use a command line to navigate to your project directory and run this command:
```sh
sail conn init navigate-conference
```
This command leverages the SailPoint CLI's SaaS Connectivity functionality to create a SaaS connector project, 'navigate-conference', that has all the resources you will need to develop the connector. You can read more about the SaaS connector's project structure [here](./prerequisites/#source-files).
To open the project with VSCode, open the 'navigate-conference' folder, and run this command:
```sh
code .
```
This command will launch VSCode in the folder you have open.
## Install dependencies
The SaaS connnector project has dependencies - packages or libraries required for it to function. To install these dependencies, run this command in your terminal:
```bash
npm install
```
This command installs the required dependencies and creates the 'package-lock.json' file, which lists the installed dependencies and their versions.
The 'package-lock.json' file looks something like this:
package-lock.json
```json
{
"name": "navigate-conference",
"version": "0.1.0",
"main": "dist/index.js",
"scripts": {
"clean": "shx rm -rf ./dist",
"prebuild": "npm run clean",
"build": "npx ncc build ./src/index.ts -o ./dist -m -C",
"dev": "cross-env NODE_OPTIONS=--enable-source-maps spcx run dist/index.js",
"debug": "spcx run dist/index.js",
"prettier": "npx prettier --write .",
"test": "jest --coverage",
"prepack-zip": "npm ci && npm run build",
"pack-zip": "spcx package"
},
"private": true,
"dependencies": {
"@sailpoint/connector-sdk": "^1.0.0"
},
"devDependencies": {
"@types/jest": "^27.0.1",
"@vercel/ncc": "^0.34.0",
"jest": "^27.0.6",
"prettier": "^2.3.2",
"shx": "^0.3.3",
"ts-jest": "^27.0.5",
"typescript": "4.3.5",
"cross-env": "7.0.3"
},
"jest": {
"preset": "ts-jest",
"testEnvironment": "node",
"clearMocks": true,
"collectCoverage": true,
"coverageThreshold": {
"global": {
"statements": 60,
"branches": 50,
"functions": 40,
"lines": 60
}
}
},
"prettier": {
"printWidth": 120,
"trailingComma": "es5",
"tabWidth": 4,
"semi": false,
"singleQuote": true
}
}
```
## Test deployment
You can now deploy your SaaS connector project. To deploy it, run this command:
```bash
npm run dev
```
This command deploys your project so that it watches for file changes. This means that the project will recompile as you make changes to it.
The script locally starts an Express server on `port 3000`, which you can use to invoke a command against the connector. You do not need to restart this process after making changes to connector code. Once the Express server is started, you can send `POST` requests to `localhost:3000` and test your command handlers.
You can also change the port by specifying it after `dev`, like this:
```bash
npm run dev 4200
```
This command changes the port to `localhost:4200`.
## Create Airtable table
Open [Airtable](https://airtable.com/). Follow these steps to create the table you will use to set up the test data for your SaaS connector:
1. Create a workspace and open it.
2. Within that workspace, select the 'Create' button to create a base. You will have two options, "Build an app", or "Start from scratch". Select "Start from scratch" to create a base, along with a basic table. Each row will represent an account, and each column will represent an account attribute.
3. Rename your table from 'Untitled Base' and your table from 'Table 1'. In the example, the base is 'Navigate-Conference', and the table is 'Users'.
4. Modify the columns:
- Name the first column, 'id', and make it 'Single line text'.
- Name the second column, 'email', and make it 'Single line text'.
- Name the third column, 'entitlements' and make it 'Multiple select'. Create these entitlement options: 'user', 'admin', and 'readonly'.
- Name the fourth column, 'fullname'.
5. Populate the table with some dummy data. Create at least two accounts, along with their attributes.
You will use your SaaS connector to aggregate this table's accounts into ISC and make changes to those accounts.
The table will look something like this example:
Example Airtable table
| id | email | entitlements | fullname |
| ------------- | ------------------------------- | ------------ | ------------- |
| alan.bradley | alan.bradley@sailpointdemo.com | user | Alan Bradley |
| brenda.cooper | brenda.cooper@sailpointdemo.com | admin | Brenda Cooper |
| fred.mcbread | fred.mcbread@test.com | readonly | Fred McBread |
## Install Airtable SDK
To connect your SaaS connector to Airtable, you must leverage the Airtable software development kit (SDK).
To install the Airtable SDK, run this command:
```bash
npm install airtable
```
This command installs the Airtable SDK and allows you to leverage its functionality.
Once you have installed the Airtable SDK, you will see it added to the list of dependencies in the 'package.json' file:
```json
"dependencies": {
"@sailpoint/connector-sdk": "^1.0.0",
"airtable": "^0.12.2"
}
```
## Get Airtable configuration
To connect to Airtable, you must be able to authenticate your API requests. To both learn how to configure your authentication as well as get the information you will need to do so, return to Airtable, go to the 'Help' menu, and access its API documentation. The API documentation is specific to the Airtable base and table you access it from.
Go to the 'Authentication' section of the API documentation. Switch to the 'JavaScript' option on the right to see the sample JavaScript code you must incorporate into your SaaS connector project to get started.
The code looks something like this:
```javascript
var Airtable = require('airtable');
Airtable.configure({
endpointUrl: 'https://api.airtable.com',
apiKey: 'YOUR_SECRET_API_TOKEN'
});
var base = Airtable.base('YOUR_BASE'); /// Your base ID is actually provided in the sample code in the documentation.
```
You must provide an `apiKey` and `Airtable.base` to authenticate to the Airtable API (the `endpointUrl` is optional). The Airtable API documentation provides your base, but for your `apiKey`, you need to an Airtable personal access token ([PAT](https://airtable.com/developers/web/guides/personal-access-tokens)).
## Create Airtable PAT
To create the PAT you will need to pass as an `apiKey`, go to [Airtable Builder Hub](https://airtable.com/create/tokens). The Airtable Builder Hub lists all your available PATs. Follow these steps to create a PAT:
1. Select the 'Create new token' button in the upper right corner of the Builder Hub.
2. Name your token.
3. Add scopes to your token to grant permissions. For example, adding `data.records:read` will allow you to see the data in table records. For more information about scopes in Airtable, refer to the [Scopes Guide](https://airtable.com/developers/web/api/scopes).
4. Add the base you created to the list of bases the PAT can access.
5. Select the 'Create token' button.
## Configure Airtable authentication
Once you have a PAT to pass as an `apiKey` and the base ID to pass as an `Airtable.base`, you can return to your code and configure your Airtable connector's authentication.
Open your 'my-client.ts' file. The SaaS connector's authentication is configured here.
The 'my-client.ts' file looks like this:
my-client.ts (Default)
```typescript showLineNumbers
import { ConnectorError } from "@sailpoint/connector-sdk"
const MOCK_DATA = new Map([
[
'john.doe',
{
id: '1',
username: 'john.doe',
firstName: 'john',
lastName: 'doe',
email: 'john.doe@example.com',
},
],
[
'jane.doe',
{
id: '2',
username: 'jane.doe',
firstName: 'jane',
lastName: 'doe',
email: 'jane.doe@example.com',
},
],
])
export class MyClient {
private readonly token?: string
constructor(config: any) {
// Fetch necessary properties from config.
// Following properties actually do not exist in the config -- it just serves as an example.
this.token = config?.token
if (this.token == null) {
throw new ConnectorError('token must be provided from config')
}
}
async getAllAccounts(): Promise {
return Array.from(MOCK_DATA.values())
}
async getAccount(identity: string): Promise {
// In a real use case, this requires a HTTP call out to SaaS app to fetch an account,
// which is why it's good practice for this to be async and return a promise.
return MOCK_DATA.get(identity)
}
async testConnection(): Promise {
return {}
}
}
```
The current authentication is configured in the `constructor`. A token is expected, and if a token is not sent with the request, the connector handles it with an error: "token must be provided from config".
This is where you need to implement the code from the Airtable API documentation.
1. Import the `Fieldset` and `Record` types from the Airtable SDK. To do so, copy this line at the top of the page, after the first import.
```typescript
import Airtable, { FieldSet, Record } from "airtable"
```
2. Copy and paste these lines, inspired by the Airtable API documentation, within the constructor, after the error handling. The SaaS connector will expect an Airtable `apiKey` and an `airtableBase`, instead of a `token`:
```typescript
Airtable.configure({apiKey: config.apiKey})
this.airtableBase = Airtable.base(config.airtableBase);
```
2. You no longer need the `token?` property, so you can replace that line before the constructor with this one, with the `airtableBase`:
```typescript
private readonly airtableBase: Airtable.Base
```
3. Update the error handling to reflect the new necessary authentication information. To do so, copy these lines to replace the current error handling:
```typescript
if (config?.apiKey == null) {
throw new ConnectorError('apiKey must be provided from config')
}
if (config?.airtableBase == null) {
throw new ConnectorError('airtableBase must be provided from config')
}
```
Once you have made these changes, your 'my-client.ts' file looks like this:
my-client.ts updated for authentication
```typescript showLineNumbers
import { ConnectorError } from "@sailpoint/connector-sdk"
import Airtable, { FieldSet, Record } from "airtable"
const MOCK_DATA = new Map([
[
'john.doe',
{
id: '1',
username: 'john.doe',
firstName: 'john',
lastName: 'doe',
email: 'john.doe@example.com',
},
],
[
'jane.doe',
{
id: '2',
username: 'jane.doe',
firstName: 'jane',
lastName: 'doe',
email: 'jane.doe@example.com',
},
],
])
export class MyClient {
private readonly airtableBase: Airtable.Base
constructor(config: any) {
// Fetch necessary properties from config.
// Following properties actually do not exist in the config -- it just serves as an example.
if (config?.apiKey == null) {
throw new ConnectorError('apiKey must be provided from config')
}
if (config?.airtableBase == null) {
throw new ConnectorError('airtableBase must be provided from config')
}
Airtable.configure({apiKey: config.apiKey})
this.airtableBase = Airtable.base(config.airtableBase);
}
async getAllAccounts(): Promise {
return Array.from(MOCK_DATA.values())
}
async getAccount(identity: string): Promise {
// In a real use case, this requires a HTTP call out to SaaS app to fetch an account,
// which is why it's good practice for this to be async and return a promise.
return MOCK_DATA.get(identity)
}
async testConnection(): Promise {
return {}
}
}
```
Your SaaS connector is now configured to authenticate its API requests to Airtable.
## Configure Postman environment
Once your SaaS connector's authentication is configured, you can configure Postman to test the connection between the SaaS connector and Airtable.
1. Open Postman. In the upper right corner, you can select the environment variables you will store so you can use them whenever you send API requests to Airtable or ISC.
2. Use the '+' button to create a new environment.
The first three environment variables you need, `tenant`, `clientId`, and `clientSecret`, will authenticate your API requests to ISC. If you have configured your SailPoint CLI, you can the same variables from your CLI's PAT. Otherwise, you can refer to [Authentication](/docs/api/authentication/#generate-a-personal-access-token) to learn how to create a PAT and get these variables.
The fourth environment variable, `airtableAPIKey` will authenticate your API requests. You will use the PAT you generated in Airtable for this variable.
3. To authenticate your API requests to ISC, specify values for these variables in their 'Initial value' and 'Current value' fields:
| Environment Variable | Required | Description |
| --- | --- | --- |
| `tenant` | Yes | Your ISC tenant, typically your company's name. |
| `clientId` | Yes | The client ID for the API client or personal access token. Keep this private and secure. |
| `clientSecret` | Yes | The client secret for the API client or personal access token. Keep this private and secure. |
| `airtableAPIKey` | Yes | The Airtable PAT. Keep this private and secure. |
4. Save your environment to finalize your changes.
5. Select the environment from the environment dropdown menu. All your API requests will automatically include these variables, authenticating them for both Airtable and ISC.
## Implement test connection command
Once you have configured Postman for testing your API requests, you can almost test your SaaS connector's connection to Airtable. To do so, you must implement your first command: [Test Connection](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/test-connection)
To implement Test Connection, open 'my-client.ts' and follow these steps:
Go to this `testConnection` asynchronous function at the end of the file.
```typescript
async testConnection(): Promise {
return {}
}
```
You will rewrite this function so that it actually does something.
Rewrite the function like this:
```typescript
async testConnection(): Promise {
return this.airtableBase('Users').select().firstPage().then(records => {
return {}
}).catch(err => {
throw new ConnectorError('Unable to connect!')
})
}
```
The first part of the function before the `catch` implements the command. The SaaS connector now sends a request to the `Users` table and checks whether it can connect and authenticate. If it is successful, the API returns an empty object, which is okay because you don't need to do anything with the data yet.
The second part of the function after the `catch` implements the error handling. If there is an error, the API returns this response: 'Unable to connect!'
Your code should currently look like this:
Code with test connection implemented
```typescript showLineNumbers
import { ConnectorError } from "@sailpoint/connector-sdk"
import Airtable, { FieldSet, Record } from "airtable"
const MOCK_DATA = new Map([
[
'john.doe',
{
id: '1',
username: 'john.doe',
firstName: 'john',
lastName: 'doe',
email: 'john.doe@example.com',
},
],
[
'jane.doe',
{
id: '2',
username: 'jane.doe',
firstName: 'jane',
lastName: 'doe',
email: 'jane.doe@example.com',
},
],
])
export class MyClient {
private readonly airtableBase: Airtable.Base
constructor(config: any) {
// Fetch necessary properties from config.
// Following properties actually do not exist in the config -- it just serves as an example.
if (config?.apiKey == null) {
throw new ConnectorError('apiKey must be provided from config')
}
if (config?.airtableBase == null) {
throw new ConnectorError('airtableBase must be provided from config')
}
Airtable.configure({apiKey: config.apiKey})
this.airtableBase = Airtable.base(config.airtableBase);
}
async getAllAccounts(): Promise {
return Array.from(MOCK_DATA.values())
}
async getAccount(identity: string): Promise {
// In a real use case, this requires a HTTP call out to SaaS app to fetch an account,
// which is why it's good practice for this to be async and return a promise.
return MOCK_DATA.get(identity)
}
async testConnection(): Promise {
return this.airtableBase('Users').select().firstPage().then(records => {
return {}
}).catch(err => {
throw new ConnectorError('Unable to connect!')
})
}
}
```
## Fork SaaS connectivity Postman collection
To start testing the SaaS connector's commands in Postman, you will need to get the SaaS Connectivity collection.
To get the SaaS Connectivity commands, follow these steps:
1. Go to the SailPoint maintained workspace in Postman [here](https://www.postman.com/sailpoint/identitynow/overview).
2. You will see the 'SaaS Connectivity collection listed on the left. Right click the collection and select 'Create a fork'. Forking the collection will create a collection you can use to test locally and make changes.
3. Name the fork and select the 'Fork Collection' button. This will create a copy of the collection in your own workspace.
4. Open the 'Workspaces' menu in the upper left corner and select 'My Workspace'. Doing so will open your workspace and list your API collections on the left.
5. Expand the 'SaaS Connectivity' collection.
6. There are two folders within this collection, 'Connector Commands' and 'Customizer Commands'. Expand 'Connector Commands'. You will see all the available connector commands listed.
## Test connection
Before you test the connection, make sure that your SaaS connector is running. Use this command in your terminal to run the connector:
```bash
npm run dev
```
Once the connector is running, you will see in the terminal that it is "watching for file changes". Whenever you save your changes, the project will recompile automatically to include them.
Each SaaS connector command in the collection includes a basic sample in its body. Select the 'Test Connection' command, listed as 'Test local stdTestConnection', to see a sample. You can use this sample as a template for your 'Test Connection' command, but this sample won't quite work for the Airtable connector because the necessary configuration for authentication no longer involves a `token`. Authentication to Airtable requires an `apiKey` and an `airtableBase`.
Rewrite the sample 'Test Connection' command like this:
```json
{
"type": "std:test-connection",
"input": {},
"config": {
"apiKey": "{{airtableAPIKey}}", /// The {{airtableAPIKey}} syntax uses the airtableAPIKey environment variable.
"airtableBase": "INSERT-AIRTABLE-BASE-HERE" /// Insert your Airtable base's ID here.
}
}
```
This command now provides the correct authentication, an `airtableAPIKey` and an `airtableBase`.
To test the request, click 'Send'.
This is a successful response:
```json
{
"data": {},
"type": "output"
}
```
To see what an unsuccessful response looks like, try making a small error in the Postman body, like this:
```json
{
"type": "std:test-connection",
"input": {},
"config": {
"apiKey": "{{airtableAPIKey}}",
"airtableBas": "YOUR-AIRTABLE-BASE-HERE"
}
}
```
The `airtableBase` value is now missing an "e" at the end, so the request won't work.
Try sending it again. This is what the response may look like:
Connector error
```json
generic error:
+ ConnectorError: airtableBase must be provided from config
at new MyClient (C:\git\Navigate-Conference\src\my-client.ts: 37: 19)
at connector (C:\git\Navigate-Conference\src\index.ts: 23: 22)
at process.processTicksAndRejections (node:internal/process/task_queues: 95: 5)
at async loadConnector (C:\git\Navigate-Conference\node_modules\@sailpoint\connector-sdk\bin\spcx.ts: 106: 49)
at async (C:\git\Navigate-Conference\node_modules\@sailpoint\connector-sdk\bin\spcx.ts: 118: 16)
at async _withConfig (C:\git\Navigate-Conference\node_modules\@sailpoint\connector-sdk\lib\config.ts: 37: 2)
at async (C:\git\Navigate-Conference\node_modules\@sailpoint\connector-sdk\bin\spcx.ts: 117: 5) {
type: 'generic'
}
```
The response now returns this error: "airtableBase must be provided from config".
## Debugging
When you're configuring your SaaS connector and implementing commands, it's inevitable that you will encounter bugs and errors while you work. SaaS Connectivity provides you the ability to run your SaaS connector in 'debug' mode, which allows you to test the connector locally and use breakpoints to help you troubleshoot.
First, stop running your SaaS connector. To do so, type "Ctrl+C" in the terminal. You will be prompted to confirm that you want to "terminate batch job". Type "Y" and click "Enter" to do so.
To run your SaaS connector in debug mode, open a JavaScript Debug Terminal in your terminal and use this command:
```bash
npm run debug
```
Similarly to the `npm run dev` command, this command starts running the connector and watching for file changes. However, running the `npm run debug` command in a JavaScript Debug Terminal runs your project in debugging mode. You can now take advantage of useful debugging features like breakpoints and the ability to add expressions to a watchlist.
## Breakpoints
One way to debug your SaaS connector is to use breakpoints. When you run your SaaS connector in debug mode, you can click a line number and add a break point.
A breakpoint stops running the project when it gets to that line. The idea is that if the project fails before it reaches the breakpoint in the code, the error occurred before that breakpoint, which gives you an idea of where to look. You can put another breakpoint earlier in the project to help you narrow down the area of code where the error occurred.
To show this, here is an example of the 'Test Connection' command in the 'my-client.ts' file, with an incorrect table name:
```typescript
async testConnection(): Promise {
return this.airtableBase('TableName').select().firstPage().then(records => {
return {}
}).catch(err => {
throw new ConnectorError('Unable to connect!')
})
}
```
This example does not have the 'Users' Airtable table name, so the SaaS connector is not going to be able to return the correct table.
Save your changes. The project will recompile to include them.
Try to test the connection in Postman with this request:
```json
{
"type": "std:test-connection",
"input": {},
"config": {
"apiKey": "{{airtableAPIKey}}",
"airtableBase": "YOUR-AIRTABLE-BASE-ID"
}
}
```
This time, there is an error: "Connector Error: Unable to connect!"
To pinpoint where the error occurred, follow these steps:
1. Return to the 'Test Connection' command implementation. Click the red dot that displays to the left of line 58, where the error gets thrown. Doing so inserts a break point at that line. Line 58 is a good one to start with, because that's where the "Unable to connect" error gets thrown.
2. Test the connection in Postman again. Postman will stall until it times out after 3 minutes (SaaS connectors time out after 3 minutes), because the project stopped before the response was returned.
3. Return to the 'my-client.ts' file, and you will see that line 58 is highlighted and the connector is now paused. The breakpoint indicates that the connector is working as intended, returning the error because it can't connect. This means that there is an error in the asynchronous `testConnection` function.
4. Click F5 to continue running the project. You will receive the same error as before: "Unable to connect!"
To resolve the issue, change `'TableName'` to `'Users'` and save your changes.
Now, test the connection in Postman again. Postman will stall again, so return to the 'my-client.ts' file and click 'F5' there to continue running the connector.
This time, you will receive a successful response: an empty JSON object.
Click the breakpoint again to remove it so that you can run your connector without pauses.
## Implement Account List Command
The next command you're going to run is [Account List](https://developer.sailpoint.com/docs/connectivity/saas-connectivity/commands/account-list). This command allows you to get all the accounts from your table, along with their account attributes. This command also allows you to manually aggregate Airtable account data within ISC.
To implement Account List, follow these steps:
1. [Create AirtableAccount Typescript File](#create-airtableaccount-typescript-file)
2. [Write Account List Logic](#write-account-list-logic)
3. [Update Account List Command Handler](#update-account-list-command-handler)
### Create AirtableAccount Typescript file
To implement Account List and successfully aggregate account data into ISC, the first thing you must do is create a new Typescript file, titled 'AirtableAccount.ts'. You will use this file to create a class that will act as a wrapper around the Airtable account record data, which you can then convert to standard output formats and back to Airtable-compatible objects.
Follow these steps to configure your 'AirtableAccount.ts' file:
1. Create a folder within the 'src' folder, called 'models'.
2. Create a Typescript file in the 'models' folder, called 'AirtableAccount.ts'.
3. Define the `AirtableAccount` class:
```typescript
export class AirtableAccount2 {
identity!: string
email!: string
id!: string
fullname!: string
entitlements!: Array
}
```
The `AirtableAccount` class represents an Airtable account object. The class defines the account attributes and their data types. The non-null assertion operator (!) ensures that the properties always have values and cannot be null or undefined.
4. Import the types you will need from the SaaS Connector and Airtable SDKs at the beginning of the file, before the `AirtableAccount` class:
```typescript
import { SimpleKey, StdAccountCreateOutput, StdAccountListOutput, StdAccountReadOutput } from '@sailpoint/connector-sdk'
import { FieldSet, Record } from 'airtable'
```
You will leverage the SaaS Connector and Airtable SDKs to implement Account List.
5. Write the `createwithRecords` static method within the `AirtableAccount` class, following the attribute definitions:
```typescript
public static createWithRecords(record: Record