JS Client for Airtable Web API built on top @unjs/ofetch
npm install airtable-ofetch



Modern JS client for Airtable Web API
* airtable-ofetch
* 🚀 Quick Start
* ✔️ Works on node, browser, and workers
* 🔧 Configuration
* 🔁 Pagination
* 📘 Type Friendly
* 📦 Bundler Notes
* 💻 Development
* License
Install:
``bash`
pnpm install airtable-ofetch
Import:
`js
// CommonJS
const { Airtable } = require('airtable-ofetch');
// ESM / TypeScript
import { Airtable } from 'airtable-ofetch';
const airtable = new Airtable(); // Will read process.env.AIRTABLE_API_KEY
`
`js
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
/**
* Disable automatic reset when server response with Iteration Timeout error
* when calling .all() on List Records query
*
* @see {@link https://airtable.com/developers/web/api/list-records#:~:text=LIST_RECORDS_ITERATOR_NOT_AVAILABLE}
* @optional
*/
noIterationReset: true, // Throws when iteration timeout
/**
* 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:
`js`
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:
`js
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' } });
`
that you can control whenever possible:`typescript
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;
});
`> [!NOTE]
>
eachPage() API need you to handle Iteration Timeout scenario yourselfFor convenient usage, you also have
firstPage() or all() method:`typescript
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:
`typescript
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();
`📘 Type Friendly
Specify your own data:`typescript
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('tblc7ieWKVQM9eequ');
// Return typed records
const records: AirtableRecord[] = 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.
📦 Bundler Notes
Since this client implemented on top of unjs/ofetch, please consult ofetch's Bundler Notes to ensure compatibility with your project.💻 Development
* Clone this repository
* Enable Corepack using corepack enable
* Install dependencies using pnpm install
* Run interactive tests using pnpm dev`