Overview

There are three ways to interact with the Airtable API through our platform:

Airtable API Quirks

Every Airtable REST API request requires a baseId and a tableId. You can find these values in the URL of your Airtable base and table. We provide a hook to help you get the baseId and tableId values for your users.

Airtable doesn’t support events like you noramally would use. Instead you subscribe to specifec events by passing a JSON config object. We provide a helper function to generate this for you. See a couple steps below on how it works.

Creating a Webhook for a User

  1. Base ID Retrieval: You can use our hook to get the baseId for your users. The

    import { useGetAirtableBaseIds } from 'syncd-hooks';
    ...
    const { data: airtableBaseIds, isLoading: airtableBaseIdsIsLoading } = useGetAirtableBaseIds();
    ...
    {airtableBaseIds?.bases?.map((base) => (
     <option key={base.id} value={base.id}>
       {base.name}
     </option>
    ))}
    ...
    
  2. Table ID Retrieval: You can use our hook to get the tableId for your users. The

    import { useGetAirtableTables } from 'syncd-hooks';
    ...
    const { data: airtableTables, isLoading: airtableTablesIsLoading } = useGetAirtableTables();
    ...
    {airtableTables?.tables?.map((table) => (
     <option key={table.id} value={table.id}>
       {table.name}
     </option>
    ))}
    ...
    
  3. Create a webhook for the user using the previously collected data:

create-airtable.ts
    /**
     * We use JSDocs in the SDK to give you the best experience possible.
     * If you need to know what a function does, you can hover over it in your IDE.
     * If you need to know why you need a projectId for example, you can hover over it.
     */
    const res = await syncdClient.providers.airtable.webhooks.create({
      // This is a dummy URL. You will need to replace it with your own or your external user's URL.
      callbackUrl: "https://api.my-api.com/api/webhooks/airtable",
      // You can use this in the dashboard to easily identify the webhook.
      endpointName: `${user.id} - Airtable Webhook`,
      endpoindDescription: "DEV - Airtable Webhook",
      webhookSpec: generateAirtableWebhookSpec({
        tableId // Get this from the above hook useGetTables
      })
      // Syncd uses projects to group webhooks and users. You will need to create a project first and copy the ID.
      projectId: process.end.NEXT_PUBLIC_SYNCD_PROJECT_ID, // If you are using NEXT.js you can preface this with NEXT_PUBLIC to expose this to the client
      accessToken: <your-users-access-token>, // make sure the provider you use refreshes these tokens before passing it to us

      // This is an optional object that you can use to create an external user
      externalUser: {
        // If you do choose this option, you will need to provide a uniqueId
        uniqueId: user.id,
        firstName: user.firstName, // Optional
        lastName: user.lastName, // Optional

        // Any key value pairs you want to store with the user
        metadata: {
          email: "john@doe.com",
        },
      },
    });

Note: there was a helper function used generateAirtableWebhookSpec. You can import this from our SDK and it will allow you to generate the correct JSON.

Updating a Webhook

One thing Airtable doesn’t allow is updating a webhook. We support that by keeping a record of the old data and then deleting the old webhook and creating a new one. This is done in the background and you don’t have to worry about it. It would look something like this:

await syncdClient.providers.airtable.webhooks.update({
  ...
})

Airtable doesn’t directly support this. BUT, we do. This is useful if you want to change the callbackUrl or webhookSpec. The resulting webhook will be under the same project and endpointID so you don’t need to worry about updating things in your database/storage.

Note if you use Syncd for Oauth access tokens then we keep an internal cursor of the step that you are at. This might seem weird, but Airtable doesn’t acutally send you events, they send you an ID everytime an event happens and then you have to fetch the data of the events. The issue is, they return every event you have ever had. So we keep an internal cursor that maintains the current position. If you update the webhook without us, we can’t keep track of the internal curor, and instead you will have to on your end.

Example:

update-airtable.ts
/**
 * We use JSDocs in the SDK to give you the best experience possible.
 * If you need to know what a function does, you can hover over it in your IDE.
 * If you need to know why you need a projectId for example, you can hover over it.
 */
const res = syncdClient.providers.airtable.webhooks.update({
  accessToken: "<your-access-token>",
  baseId: "<your-base-id>",
  tableId: "<your-table-id>",
  webhookSpec: generateAirtableWebhookSpec({
    tableId: "<your-table-id>",
  }),
  endpointId: "<your-endpoint-id>",
  endpointDescription: "<your-endpoint-description>",
  endpointName: "<your-endpoint-name>",
  // This is option
  metadata: {
    email: "test@test.com",
  },
});

Special case (only if you use a third party for handeling access tokens)

If you use the SDK to create a webhook, and you don’t use Syncd for managing the OAuth access tokens, then your webhook body that get’s sent to you is actually just a webhookId. You can use this webhookId to get the webhook body. We do provide a helper function that you can pass your access token to, and it will return the webhook body. This has to be done on your webhook endpoint. It would look something like this.

import { getAirtableWebhookBodyFromId } from '@syncd-sdk';
...
const body: TAirtableWebhookIdBody = await req.json();
// This function handles the cursor pagination and retrieves the body that is associated with the webhookId
const actuallWebhookBody = await getAirtableWebhookBodyFromId({
  webhookId: body.webhookId,
  accessToken: <your-users-access-token>,
});
...

Example Payloads

Airtable doesn’t support traditional events. They instead support a

Types

TDefaultPayloadEvent