Skip to content

Commit cf52ebe

Browse files
authored
feat: airtable docs (#2619)
Introducing the documentation for Airtable data import Actor. Removed the Airtable extension docs (not released yet)
1 parent dfffc6c commit cf52ebe

20 files changed

Lines changed: 213 additions & 129 deletions
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
---
2+
title: Airtable integration
3+
description: Automatically import items from any Apify dataset into Airtable using the Airtable Data Import Actor. Use standalone or in automated workflows.
4+
sidebar_label: Airtable
5+
sidebar_position: 1
6+
slug: /integrations/airtable
7+
---
8+
9+
import ThirdPartyDisclaimer from '@site/sources/_partials/_third-party-integration.mdx';
10+
11+
The [Airtable Data Import Actor](https://console.apify.com/actors/f4DM1wGmMQdnTLbrE/info/readme?build=latest) transfers items from any Apify dataset into an [Airtable](https://www.airtable.com/) base. Use it standalone or chain it after other Actors in automated workflows via [integrations](/platform/integrations).
12+
13+
<ThirdPartyDisclaimer />
14+
15+
## Prerequisites
16+
17+
- An [Apify account](https://console.apify.com/)
18+
- An [Airtable account](https://www.airtable.com/)
19+
- The [Airtable Data Import Actor](https://console.apify.com/actors/f4DM1wGmMQdnTLbrE/info/readme?build=latest)
20+
21+
## Connect to Airtable
22+
23+
The Actor uses OAuth 2.0 to connect to your Airtable account:
24+
25+
1. Navigate to the Actor's **Integrations** tab in Apify Console.
26+
1. Click **Connect** next to Airtable and follow the OAuth consent flow.
27+
1. Once connected, the OAuth account field is populated automatically.
28+
29+
![Apify Console Integrations tab showing Airtable OAuth connection screen](../images/airtable/airtable_console_oauth.webp)
30+
31+
The Actor retrieves a fresh access token at the start of each run. Your Airtable credentials are never stored or logged.
32+
33+
## Configure the Actor
34+
35+
Configure the Actor from its **Input** tab in Apify Console. Each field is described below.
36+
37+
### Operation
38+
39+
Controls how the Actor handles the target table and its existing records.
40+
41+
- `Append`: Adds new records to the table. Existing records are never modified or deleted. Use for continuous pipelines.
42+
- `Override`: Deletes all existing records before importing. Use for full data refreshes.
43+
- `Create`: Creates a new table with fields from your mappings, then imports data. If the table already exists, the `clearOnCreate` setting determines what happens.
44+
45+
### Clear on create
46+
47+
A safety switch for `Create` mode only. Defaults to `false`.
48+
49+
- `Enabled` (`true`): Clears all existing records and imports. Use for automated fresh starts.
50+
- `Disabled` (`false`): Throws an error if the table exists, preventing accidental data loss.
51+
52+
### Base
53+
54+
Accepts a base ID (`appXXXXXXXXXXXXXX`, found in the Airtable URL) or a base name. Base IDs are recommended - they are immutable and globally unique.
55+
56+
![Airtable base URL highlighting the base ID portion](../images/airtable/airtable_console_app_id.webp)
57+
58+
### Table
59+
60+
Accepts a table name or table ID (`tblXXXXXXXXXXXXXX`). When using `Create` mode and the table does not exist, the Actor creates it automatically.
61+
62+
### Dataset ID
63+
64+
Specifies the dataset to import from:
65+
66+
- A static dataset ID (for example, `cqxkhXcn2SCjTpeCz`).
67+
- `{{resource.defaultDatasetId}}` when used as an integration - automatically passes the upstream Actor's dataset.
68+
69+
### Unique ID
70+
71+
Enables duplicate detection. When set, the Actor reads existing values from the mapped Airtable column and skips records with matching values. The value must match one of the `source` fields in your `dataMappings`.
72+
73+
### Field mappings
74+
75+
An array defining how dataset fields map to Airtable columns.
76+
77+
![Field mappings editor showing multiple mapping rows configured](../images/airtable/airtable_console_field_mapping.webp)
78+
79+
Each mapping has these properties:
80+
81+
| Property | Description |
82+
| --- | --- |
83+
| `source` | Dataset field path, supports dot notation for nested objects (`crawl.depth`, `metadata.uid`) |
84+
| `target` | Airtable column name |
85+
| `targetType` | `existing` if the field already exists, `new` to create it automatically |
86+
| `fieldType` | Airtable field type: `singleLineText`, `multilineText`, `number`, `checkbox` |
87+
88+
#### Dot notation
89+
90+
Use dot notation to access nested object properties. `items[0].name` style array indexing is not supported.
91+
92+
#### Field types
93+
94+
| Field type | Use for |
95+
| --- | --- |
96+
| `singleLineText` | Names, URLs, IDs (max 10,000 characters) |
97+
| `multilineText` | Descriptions, paragraphs, JSON blobs |
98+
| `number` | Prices, counts, ratings (integer precision) |
99+
| `checkbox` | Boolean values, yes/no flags |
100+
101+
:::caution Number precision
102+
103+
The Actor creates `number` fields with integer precision. For decimal values, create the field manually in Airtable and use `targetType: "existing"`.
104+
105+
:::
106+
107+
## Import results from another Actor automatically
108+
109+
Chain the Actor after a scraping or extraction Actor so its dataset flows into Airtable on every run. Use this for scheduled scrapers, recurring price checks, or any pipeline where fresh data should reach your base without a manual trigger.
110+
111+
1. Open the upstream Actor in Apify Console and go to the **Integrations** tab.
112+
1. Click **Add integration** and select **Airtable Data Import Actor**.
113+
1. Set `datasetId` to `{{resource.defaultDatasetId}}`.
114+
1. Configure the base, table, operation, and field mappings.
115+
1. Connect your Airtable account via OAuth.
116+
117+
![Apify integration setup screen showing Airtable Data Import Actor configuration](../images/airtable/airtable_console_dataset_id.webp)
118+
119+
## Example of the output
120+
121+
After each run, the Actor writes a JSON summary to its dataset. Each field reports a key result from the import operation:
122+
123+
```json
124+
{
125+
"success": true,
126+
"operation": "Append",
127+
"baseName": "My Product Catalog",
128+
"tableName": "Products",
129+
"totalItems": 1500,
130+
"importedCount": 1450,
131+
"skippedDuplicates": 50,
132+
"duration": 330
133+
}
134+
```
135+
136+
## Example configurations
137+
138+
<details>
139+
<summary>Append with duplicate detection</summary>
140+
141+
```json
142+
{
143+
"operation": "Append",
144+
"base": "appABC123456789",
145+
"table": "Products",
146+
"datasetId": "{{resource.defaultDatasetId}}",
147+
"uniqueId": "url",
148+
"dataMappings": [
149+
{ "source": "title", "target": "Product Name", "targetType": "existing", "fieldType": "singleLineText" },
150+
{ "source": "price", "target": "Price", "targetType": "existing", "fieldType": "number" },
151+
{ "source": "url", "target": "URL", "targetType": "existing", "fieldType": "singleLineText" },
152+
{ "source": "description", "target": "Description", "targetType": "existing", "fieldType": "multilineText" },
153+
{ "source": "inStock", "target": "In Stock", "targetType": "existing", "fieldType": "checkbox" }
154+
]
155+
}
156+
```
157+
158+
</details>
159+
160+
<details>
161+
<summary>Create new table</summary>
162+
163+
```json
164+
{
165+
"operation": "Create",
166+
"clearOnCreate": false,
167+
"base": "appXYZ987654321",
168+
"table": "Customer Feedback",
169+
"datasetId": "cqxkhXcn2SCjTpeCz",
170+
"dataMappings": [
171+
{ "source": "reviewer.name", "target": "Reviewer Name", "targetType": "new", "fieldType": "singleLineText" },
172+
{ "source": "rating", "target": "Rating", "targetType": "new", "fieldType": "number" },
173+
{ "source": "comment", "target": "Review Text", "targetType": "new", "fieldType": "multilineText" },
174+
{ "source": "verified", "target": "Verified Purchase", "targetType": "new", "fieldType": "checkbox" }
175+
]
176+
}
177+
```
178+
179+
</details>
180+
181+
<details>
182+
<summary>Override for full refresh</summary>
183+
184+
```json
185+
{
186+
"operation": "Override",
187+
"base": "Daily Competitor Prices",
188+
"table": "Pricing",
189+
"datasetId": "{{resource.defaultDatasetId}}",
190+
"dataMappings": [
191+
{ "source": "sku", "target": "SKU", "targetType": "existing", "fieldType": "singleLineText" },
192+
{ "source": "competitor", "target": "Competitor", "targetType": "existing", "fieldType": "singleLineText" },
193+
{ "source": "price", "target": "Price", "targetType": "existing", "fieldType": "number" }
194+
]
195+
}
196+
```
197+
198+
</details>
199+
200+
## Limits
201+
202+
- Text values are truncated at 10,000 characters per field.
203+
- `number` fields are created with integer precision; create decimal fields manually.
204+
- Imports process at approximately 50 records per second (10 per batch, 200ms delay).
205+
- Progress is automatically persisted - if a run is interrupted, it resumes from where it left off.
206+
207+
## Next steps
208+
209+
- [Learn about Apify integrations](/platform/integrations) to chain Actors in automated workflows.
210+
- [Explore Airtable's API documentation](https://airtable.com/developers/web/api/field-model) for field type details.
211+
- If you have questions about the Airtable integration, reach out via the support live chat in Console or the [developer community on Discord](https://discord.com/invite/jyEM2PRvMU).

sources/platform/integrations/data-storage/airtable/index.md

Lines changed: 0 additions & 129 deletions
This file was deleted.
Binary file not shown.
Binary file not shown.
Binary file not shown.
10.3 KB
Loading
5.83 KB
Loading
19.3 KB
Loading
10.4 KB
Loading
-74.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)