|
| 1 | +import { Tabs, Callout, Steps } from "nextra/components"; |
| 2 | + |
| 3 | +# Airtable |
| 4 | + |
| 5 | +The Airtable auth provider enables tools and agents to call [Airtable APIs](https://airtable.com/developers/web/api/introduction) on behalf of a user using OAuth 2.0 authentication. |
| 6 | + |
| 7 | +<Callout> |
| 8 | + Want to quickly get started with Airtable in your agent or AI app? The pre-built |
| 9 | + [Arcade Airtable MCP Server](/mcp-servers/productivity/airtable-api) is what you |
| 10 | + want! |
| 11 | +</Callout> |
| 12 | + |
| 13 | +### What's documented here |
| 14 | + |
| 15 | +This page describes how to use and configure Airtable auth with Arcade. |
| 16 | + |
| 17 | +This auth provider is used by: |
| 18 | + |
| 19 | +- The [Arcade Airtable MCP Server](/mcp-servers/productivity/airtable-api), which provides pre-built tools for interacting with Airtable |
| 20 | +- Your [app code](#using-airtable-auth-in-app-code) that needs to call the Airtable API |
| 21 | +- Or, your [custom tools](#using-airtable-auth-in-custom-tools) that need to call the Airtable API |
| 22 | + |
| 23 | +## Configuring Airtable auth |
| 24 | + |
| 25 | +<Callout type="info"> |
| 26 | + When using your own app credentials, make sure you configure your project to |
| 27 | + use a [custom user |
| 28 | + verifier](/home/auth/secure-auth-production#build-a-custom-user-verifier). |
| 29 | + Without this, your end-users will not be able to use your app or agent in |
| 30 | + production. |
| 31 | +</Callout> |
| 32 | + |
| 33 | +In a production environment, you will most likely want to use your own Airtable app credentials. This way, your users will see your application's name requesting permission. |
| 34 | + |
| 35 | +Before showing how to configure your Airtable app credentials, let's go through the steps to create an Airtable app. |
| 36 | + |
| 37 | +### Create an Airtable app |
| 38 | + |
| 39 | +To integrate with Airtable's API, you'll need to create an OAuth integration: |
| 40 | + |
| 41 | +<Steps> |
| 42 | + |
| 43 | +#### Access the Airtable Developer Hub |
| 44 | + |
| 45 | +Navigate to the [Airtable Developer Hub](https://airtable.com/developers/web) and sign in with your Airtable account. |
| 46 | + |
| 47 | +#### Create a new OAuth integration |
| 48 | + |
| 49 | +1. Go to the [Create OAuth Integration](https://airtable.com/create/oauth) page |
| 50 | +2. Fill in the required details: |
| 51 | + - **Integration Name**: Choose a descriptive name for your application |
| 52 | + - **Description**: Provide a brief description of your app's purpose |
| 53 | + |
| 54 | +#### Configure OAuth settings |
| 55 | + |
| 56 | +1. Set the **Redirect URL** to the redirect URL generated by Arcade (see configuration section below) |
| 57 | +2. Configure the required **Scopes** for your application: |
| 58 | + - `data.records:read` - Read records from tables |
| 59 | + - `data.records:write` - Create, update, and delete records |
| 60 | + - `schema.bases:read` - Read base schema |
| 61 | + - Add other scopes as needed for your use case |
| 62 | + |
| 63 | +#### Obtain your credentials |
| 64 | + |
| 65 | +1. After creating your integration, you'll receive a **Client ID** |
| 66 | +2. Generate a **Client Secret** from your integration settings |
| 67 | +3. Copy both values for use in Arcade configuration |
| 68 | + |
| 69 | +</Steps> |
| 70 | + |
| 71 | +For detailed instructions, refer to Airtable's [OAuth documentation](https://airtable.com/developers/web/guides/oauth-integrations). |
| 72 | + |
| 73 | +Next, add the Airtable app to Arcade. |
| 74 | + |
| 75 | +## Configuring your own Airtable Auth Provider in Arcade |
| 76 | + |
| 77 | +<Tabs items={["Dashboard GUI", "Configuration File"]}> |
| 78 | +<Tabs.Tab> |
| 79 | + |
| 80 | +### Configure Airtable Auth Using the Arcade Dashboard GUI |
| 81 | + |
| 82 | +<Steps> |
| 83 | + |
| 84 | +#### Access the Arcade Dashboard |
| 85 | + |
| 86 | +To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at http://localhost:9099/dashboard. Adjust the host and port number to match your environment. |
| 87 | + |
| 88 | +#### Navigate to the OAuth Providers page |
| 89 | + |
| 90 | +- Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**. |
| 91 | +- Click **Add OAuth Provider** in the top right corner. |
| 92 | +- Select the **OAuth 2.0** tab at the top. |
| 93 | + |
| 94 | +#### Enter the provider details |
| 95 | + |
| 96 | +- Choose a unique **ID** for your provider (e.g. "arcade-airtable"). |
| 97 | +- Optionally enter a **Description**. |
| 98 | +- Enter the **Client ID** and **Client Secret** from your Airtable integration. |
| 99 | +- Configure the OAuth 2.0 endpoints: |
| 100 | + - **Authorization URL**: `https://airtable.com/oauth2/v1/authorize` |
| 101 | + - **Token URL**: `https://airtable.com/oauth2/v1/token` |
| 102 | +- Note the **Redirect URL** generated by Arcade. This must be set as your Airtable integration's Redirect URL. |
| 103 | + |
| 104 | +#### Create the provider |
| 105 | + |
| 106 | +Hit the **Create** button and the provider will be ready to be used. |
| 107 | + |
| 108 | +</Steps> |
| 109 | + |
| 110 | +</Tabs.Tab> |
| 111 | + |
| 112 | +<Tabs.Tab> |
| 113 | + |
| 114 | +### Configure Airtable Auth Using Configuration File |
| 115 | + |
| 116 | +<Callout type="info"> |
| 117 | + This method is only available when you are [self-hosting the |
| 118 | + engine](/home/deployment/on-prem-mcp) |
| 119 | +</Callout> |
| 120 | + |
| 121 | +<Steps> |
| 122 | + |
| 123 | +#### Set environment variables |
| 124 | + |
| 125 | +Set the following environment variables: |
| 126 | + |
| 127 | +```bash |
| 128 | +export AIRTABLE_CLIENT_ID="<your client ID>" |
| 129 | +export AIRTABLE_CLIENT_SECRET="<your client secret>" |
| 130 | +``` |
| 131 | + |
| 132 | +Or, you can set these values in a `.env` file: |
| 133 | + |
| 134 | +```bash |
| 135 | +AIRTABLE_CLIENT_ID="<your client ID>" |
| 136 | +AIRTABLE_CLIENT_SECRET="<your client secret>" |
| 137 | +``` |
| 138 | + |
| 139 | +#### Edit the Engine configuration |
| 140 | + |
| 141 | +Edit the `engine.yaml` file and add a new item to the `auth.providers` section: |
| 142 | + |
| 143 | +```yaml |
| 144 | +auth: |
| 145 | + providers: |
| 146 | + - id: arcade-airtable |
| 147 | + description: Airtable OAuth 2.0 provider |
| 148 | + enabled: true |
| 149 | + type: oauth2 |
| 150 | + client_id: ${env:AIRTABLE_CLIENT_ID} |
| 151 | + client_secret: ${env:AIRTABLE_CLIENT_SECRET} |
| 152 | + oauth2: |
| 153 | + scope_delimiter: " " |
| 154 | + pkce: |
| 155 | + enabled: true |
| 156 | + code_challenge_method: S256 |
| 157 | + authorize_request: |
| 158 | + endpoint: "https://airtable.com/oauth2/v1/authorize" |
| 159 | + params: |
| 160 | + response_type: code |
| 161 | + client_id: "{{client_id}}" |
| 162 | + redirect_uri: "{{redirect_uri}}" |
| 163 | + scope: "{{scopes}}" |
| 164 | + state: "{{state}}" |
| 165 | + token_request: |
| 166 | + endpoint: "https://airtable.com/oauth2/v1/token" |
| 167 | + params: |
| 168 | + grant_type: authorization_code |
| 169 | + client_id: "{{client_id}}" |
| 170 | + redirect_uri: "{{redirect_uri}}" |
| 171 | + response_content_type: application/json |
| 172 | +``` |
| 173 | +
|
| 174 | +</Steps> |
| 175 | +
|
| 176 | +</Tabs.Tab> |
| 177 | +</Tabs> |
| 178 | +
|
| 179 | +When you use tools that require Airtable auth using your Arcade account credentials, Arcade will automatically use this Airtable OAuth provider. If you have multiple Airtable providers, see [using multiple auth providers of the same type](/home/auth-providers#using-multiple-providers-of-the-same-type) for more information. |
| 180 | +
|
| 181 | +## Using Airtable auth in app code |
| 182 | +
|
| 183 | +Use the Airtable auth provider in your own agents and AI apps to get a user token for the Airtable API. See [authorizing agents with Arcade](/home/auth/how-arcade-helps) to understand how this works. |
| 184 | +
|
| 185 | +Use `client.auth.start()` to get a user token for the Airtable API: |
| 186 | + |
| 187 | +<Tabs items={["Python", "JavaScript"]} storageKey="preferredLanguage"> |
| 188 | +<Tabs.Tab> |
| 189 | + |
| 190 | +```python {8-12} |
| 191 | +from arcadepy import Arcade |
| 192 | +
|
| 193 | +client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable |
| 194 | + |
| 195 | +user_id = "{arcade_user_id}" |
| 196 | + |
| 197 | +# Start the authorization process |
| 198 | +auth_response = client.auth.start( |
| 199 | + user_id=user_id, |
| 200 | + provider="arcade-airtable", |
| 201 | + scopes=["data.records:read", "data.records:write", "schema.bases:read"] |
| 202 | +) |
| 203 | + |
| 204 | +if auth_response.status != "completed": |
| 205 | + print("Please complete the authorization challenge in your browser:") |
| 206 | + print(auth_response.url) |
| 207 | + |
| 208 | +# Wait for the authorization to complete |
| 209 | +auth_response = client.auth.wait_for_completion(auth_response) |
| 210 | + |
| 211 | +token = auth_response.context.token |
| 212 | +# Do something interesting with the token... |
| 213 | +``` |
| 214 | + |
| 215 | +</Tabs.Tab> |
| 216 | + |
| 217 | +<Tabs.Tab> |
| 218 | + |
| 219 | +```javascript {8-11} |
| 220 | +import { Arcade } from "@arcadeai/arcadejs"; |
| 221 | + |
| 222 | +const client = new Arcade(); |
| 223 | + |
| 224 | +const userId = "{arcade_user_id}"; |
| 225 | + |
| 226 | +// Start the authorization process |
| 227 | +const authResponse = await client.auth.start( |
| 228 | + userId, |
| 229 | + "arcade-airtable", |
| 230 | + ["data.records:read", "data.records:write", "schema.bases:read"] |
| 231 | +); |
| 232 | + |
| 233 | +if (authResponse.status !== "completed") { |
| 234 | + console.log("Please complete the authorization challenge in your browser:"); |
| 235 | + console.log(authResponse.url); |
| 236 | +} |
| 237 | + |
| 238 | +// Wait for the authorization to complete |
| 239 | +authResponse = await client.auth.waitForCompletion(authResponse); |
| 240 | + |
| 241 | +const token = authResponse.context.token; |
| 242 | +// Do something interesting with the token... |
| 243 | +``` |
| 244 | + |
| 245 | +</Tabs.Tab> |
| 246 | + |
| 247 | +</Tabs> |
| 248 | + |
| 249 | +## Using Airtable auth in custom tools |
| 250 | + |
| 251 | +You can use the pre-built [Arcade Airtable MCP Server](/mcp-servers/productivity/airtable-api) to quickly build agents and AI apps that interact with Airtable. |
| 252 | + |
| 253 | +If the pre-built tools in the Airtable MCP Server don't meet your needs, you can author your own [custom tools](/home/build-tools/create-a-mcp-server) that interact with the Airtable API. |
| 254 | + |
| 255 | +Use the `OAuth2()` auth class to specify that a tool requires authorization with Airtable. The `context.authorization.token` field will be automatically populated with the user's Airtable token: |
| 256 | + |
| 257 | +```python {8-12,22} |
| 258 | +from typing import Annotated |
| 259 | + |
| 260 | +import httpx |
| 261 | +from arcade_tdk import ToolContext, tool |
| 262 | +from arcade_tdk.auth import OAuth2 |
| 263 | + |
| 264 | + |
| 265 | +@tool( |
| 266 | + requires_auth=OAuth2( |
| 267 | + provider_id="arcade-airtable", |
| 268 | + scopes=["data.records:read", "schema.bases:read"] |
| 269 | + ) |
| 270 | +) |
| 271 | +async def list_bases( |
| 272 | + context: ToolContext, |
| 273 | +) -> Annotated[dict, "The user's bases."]: |
| 274 | + """ |
| 275 | + Retrieve the list of bases accessible to the authenticated user. |
| 276 | + """ |
| 277 | + url = "https://api.airtable.com/v0/meta/bases" |
| 278 | + headers = { |
| 279 | + "Authorization": context.authorization.token, |
| 280 | + } |
| 281 | + |
| 282 | + async with httpx.AsyncClient() as client: |
| 283 | + response = await client.get(url, headers=headers) |
| 284 | + response.raise_for_status() |
| 285 | + return dict(response.json()) |
| 286 | +``` |
| 287 | + |
| 288 | +## Available Scopes |
| 289 | + |
| 290 | +Airtable supports various OAuth scopes that determine the level of access your application has: |
| 291 | + |
| 292 | +- `data.records:read` - Read records from tables |
| 293 | +- `data.records:write` - Create, update, and delete records |
| 294 | +- `data.recordComments:read` - Read comments on records |
| 295 | +- `data.recordComments:write` - Create and update comments on records |
| 296 | +- `schema.bases:read` - Read base schema information |
| 297 | +- `schema.bases:write` - Modify base schema |
| 298 | +- `webhook:manage` - Create and manage webhooks |
| 299 | +- `user.email:read` - Read user email address |
| 300 | + |
| 301 | +For a complete list of available scopes, refer to the [Airtable Scopes documentation](https://airtable.com/developers/web/api/scopes). |
| 302 | + |
0 commit comments