Modern JS client for Airtable Web API
Install:
pnpm install airtable-ofetch
Import:
// CommonJS
const { Airtable } = require('airtable-ofetch');
// ESM / TypeScript
import { Airtable } from 'airtable-ofetch';
const airtable = new Airtable(); // Will read process.env.AIRTABLE_API_KEY
This client is implemented on top of unjs/ofetch to provide better cross-runtime compatibility.
You can provide custom configuration during client initialization:
const airtable = new Airtable({
/**
* As of February 1st 2024, Airtable Web API has ended deprecation period
* of Airtable API Key and has prompted all users to migrate to use personal
* access token (PAT) or OAuth access token
*
* @see https://airtable.com/developers/web/api/authentication
*/
apiKey: 'YOUR_PERSONAL_ACCESS_TOKEN', // Otherwise default to process.env.AIRTABLE_API_KEY
/**
* API Endpoint URL target, users may override this if they need
* to pass requests through an API proxy. Don't include trailing slash
* for consistency.
*
* @optional
*/
endpointURL: 'https://api.airtable.internal', // Also configurable via AIRTABLE_ENDPOINT_URL
/**
* Content Endpoint URL target, users may override this if they need
* to pass requests through an API proxy. Don't include trailing slash
* for consistency.
*
* @see https://airtable.com/developers/web/api/upload-attachment
* @optional
*/
contentEndpointURL: 'https://content.airtable.internal', // Also configurable via AIRTABLE_CONTENT_ENDPOINT_URL
/**
* How long in ms before aborting a request attempt.
* Default to 5 minutes.
*
* @optional
*/
requestTimeout: 180 * 1000,
/**
* Disable / configure exponential backoff with jitter retry
* whenever API request receive 429 status code response
*
* @see https://airtable.com/developers/web/api/rate-limits
* @optional
*/
noRetryIfRateLimited: true, // This disable retry
/**
* Custom headers to be included when requesting to API endpoint
*
* @optional
*/
customHeaders: {
'X-Custom-Header': 'Custom Value',
}
})
You can customize maximum retries and its backoff behavior:
const airtable = new Airtable({
noRetryIfRateLimited: {
maxRetries: 5, // Maximum retry attempts. Default to Infinity
initialDelayMs: 500, // Initial retry delay in ms. Default to 1000ms
maxDelayMs: 2000, // Maximum retry delay in ms. Default to 45_000ms
},
})
You can create a new client that inherit previous configuration and replace some of it:
const airtable = new Airtable({ apiKey: 'custom-api-key' });
// New client will inherit manually passed apiKey
const newAirtable = airtable.create({ customHeaders: { 'X-Custom-Header': 'Custom Value' } });
This client implement similar pagination control as airtable.js using eachPage()
that you can control whenever possible:
const table = new Airtable().base('appEpvhkjHcG8OvKu').table('tblc7ieWKVQM9eequ');
// List records endpoint exposes pagination
// https://airtable.com/developers/web/api/list-records
const query = table.list({ pageSize: 50 });
// Async callback is supported
await query.eachPage(async (records: AirtableRecord[]) => {
// Do something with records
console.log(records);
// Return false to stop pagination early, otherwise pagination will continue until all records are exhausted
return false;
});
For convenient usage, you also have firstPage()
or all()
method:
const table = new Airtable().base('appEpvhkjHcG8OvKu').table('tblc7ieWKVQM9eequ');
// List comments also exposes pagination
// https://airtable.com/developers/web/api/list-comments
const query = table.comments('recPaibwSLDbZr80V', { pageSize: 50 });
const firstPageComments: AirtableComment[] = await query.firstPage();
const allComments: AirtableComment[] = await query.all();
Some endpoint doesn't expose pagination control, in this case we always return all records:
const airtable = new Airtable();
// It uses pagination but doesn't provide much control
// https://airtable.com/developers/web/api/list-bases
const bases: BaseInfo[] = await airtable.bases();
Specify your own data:
import { Airtable, type FieldSet } from "airtable-ofetch";
interface TableData extends FieldSet {
Name: string;
Notes: string;
}
// Type-assisted table
const table = new Airtable().base('appEpvhkjHcG8OvKu').table<TableData>('tblc7ieWKVQM9eequ');
// Return typed records
const records: AirtableRecord<TableData>[] = await table.list().all();
console.log(records[0].get('Name')) // Field name will be type assisted
Consult here to see interface shape. Adjusted in accordance to Web API docs.
Since this client implemented on top of unjs/ofetch, please consult ofetch's Bundler Notes to ensure compatibility with your project.
- Clone this repository
- Enable Corepack using
corepack enable
- Install dependencies using
pnpm install
- Run interactive tests using
pnpm dev