Cómo importar filas de Airtable al CMS de Webflow por lotes con Zapier

Cómo importar entradas de Airtable al CMS de Webflow por lotes con Zapier y Webflow Cloud

Aprende a crear una ruta en Webflow Cloud que valide filas de Airtable desde Zapier o Postman y las cree como elementos de CMS en borrador.

Cómo importar entradas de Airtable al CMS de Webflow por lotes con Zapier y Webflow Cloud

Ismail Ajagbe
Redactor técnico
Ver perfil del autor
Ismail Ajagbe
Redactor técnico
Ver perfil del autor
Índice de contenidos

Airtable puede seguir siendo la fuente de verdad para las entradas del CMS; una ruta de Webflow Cloud alimentada por Zapier, y probada primero en Postman, valida cada fila lista y la escribe en la Colección como borrador.

El contenido que nace en Airtable, como un catálogo de productos o un registro de artículos, eventualmente debe convertirse en elementos del CMS, y copiar filas a mano no es sostenible. Además, genera inconsistencias: cambiar el nombre de una columna en Airtable o de un campo en Webflow puede romper el mapeo.

En esta guía, crearemos una configuración que le da a la importación una única dirección que controla el mapeo: un Route Handler de Next.js en Webflow Cloud. Zapier y Postman envían las filas a esta dirección, y esta escribe cada fila en la Colección como borrador a través de la API de datos, para que Airtable siga siendo la fuente de verdad.

¿Qué necesitas para importar entradas del CMS por lotes con Zapier y Airtable en Webflow?

Necesitas siete componentes para esta importación:

  • Colección del CMS de Webflow: Define primero los campos estructurados del CMS, ya que la ruta mapea las filas en campos existentes y no envía cambios de esquema.
  • Aplicación Next.js: Crea una aplicación Next.js basada en npm que cumpla con los requisitos de "bring-your-own-app", incluyendo las versiones mínimas compatibles y el gestor de paquetes.
  • Base de Airtable: Usa una tabla con nombres de columna controlados y una vista filtrada para los registros que estén listos para importar.
  • Cuenta de Zapier: Webhooks by Zapier está disponible en todos los planes, incluido el gratuito, pero el Zap aquí tiene tres pasos (disparador, webhook, actualización de Airtable), y el plan gratuito solo permite dos, así que considera el plan Professional o superior.
  • Postman: Usa Postman u otro cliente HTTP que pueda guardar solicitudes POST y encabezados secretos personalizados para pruebas repetidas.
  • Secreto compartido: Crea una cadena aleatoria larga que Zapier y Postman envíen a la ruta como valor de autenticación.
  • Node y Webflow CLI: Instala la versión de Node requerida y @webflow/webflow-cli después de crear la aplicación basada en npm, usa la CLI para desplegarla.

Con estos componentes listos, la construcción depende de un mapa de campos de Airtable estable, una ruta protegida y una URL de despliegue probada.

6 pasos para importar por lotes entradas de Airtable al CMS de Webflow en Webflow Cloud

Seis pasos para construir una ruta que acepte filas de Airtable desde Zapier o Postman y las cree como elementos de CMS en borrador, con un modo de prueba que muestra el mapeo antes de escribir nada.

Comienza controlando qué filas de Airtable entran en el flujo de trabajo, luego construye, despliega, prueba, automatiza y ejecuta la importación en lotes de tamaño adecuado.

1. Prepara la tabla de Airtable como fuente de importación

Configura los nombres de las columnas de Airtable para que coincidan con los slugs de los campos del CMS, de modo que el mapa de campos del entorno pueda usar pares idénticos. También puedes decidir qué columna se mapea a qué slug y anotar esa decisión. Para una colección de blog, eso podría significar columnas llamadas name, slug, summary y body.

Añade una columna de casilla de verificación llamada Ready y una segunda columna de casilla de verificación llamada Imported, luego crea una vista filtrada para las filas donde Ready esté marcada y Imported esté desmarcada. Esa vista es la puerta de enlace: Zapier la consulta cada 15 minutos en el plan gratuito y cada 2 minutos en el Profesional, por lo que una fila entra en el flujo de trabajo poco después de que alguien marque la casilla, no al instante.

Tras una importación exitosa, tú o un paso posterior de Zap configuráis Imported; la fila desaparece de la vista y una reimportación se convierte en un acto deliberado en lugar de un accidente.

Revisa las columnas de origen y sus campos de destino previstos antes de que lleguen a la ruta. Si un valor de origen necesita un cambio, hazlo explícito en Airtable o en la ruta en lugar de asumir que dos campos con estructuras diferentes son intercambiables.

Filtra la cuadrícula para que solo queden las filas marcadas y no importadas. Cada fila en la vista filtrada es ahora una que pretendes enviar a través del flujo de trabajo de importación, bajo nombres de columna que coinciden con el mapa de campos.

2. Crea el controlador de ruta de importación en la aplicación Next.js

Crea app/api/import/route.ts para aceptar una fila o una matriz de filas, verificar un secreto compartido en tiempo constante, validar el mapa de campos configurado y asignar cada fila a los nombres de campo del CMS configurados. Luego, escribe las filas asignadas con el punto de conexión Create Items de Webflow, POST /v2/collections/{collection_id}/items/insert, que Webflow recomienda para nuevas integraciones.

Ese punto de conexión admite hasta 100 elementos por solicitud y los crea como borradores de forma predeterminada, por lo que la ruta envía 100 a la vez, una solicitud tras otra, y espera un 429 durante el tiempo que indique Retry-After. Añade ?dryRun=1 a una solicitud para obtener las filas asignadas de vuelta sin escribir nada. Omite la exportación de tiempo de ejecución edge incompatible.

La comparación secreta aplica hash a ambos valores y realiza un XOR de los bytes en lugar de llamar a crypto.subtle.timingSafeEqual, porque esa extensión de Cloudflare existe en el tiempo de ejecución de Workers desplegado pero no en Web Crypto de Node bajo next dev, y quiero una ruta de código que se comporte igual en ambos lugares.

Garantizar la consistencia temporal entre los tiempos de ejecución locales y desplegados

Una ruta construida sobre timingSafeEqual funciona tras el despliegue pero falla en tu portátil, lo que hace que las pruebas locales sean inútiles para la única comprobación que protege el token. El mapa de campos proviene de una variable de entorno en lugar de una constante, por lo que cambiar la asignación no requiere editar el controlador.

Pega esto en app/api/import/route.ts:

// app/api/import/route.ts
import { NextResponse } from 'next/server';

type Row = Record<string, unknown>;

const BATCH = 100; // Create Items accepts up to 100 items per request

type WriteResult =
  | { ok: true; created: number }
  | { ok: false; created: number; failedAtRow: number; status: number; error: unknown };

async function sha256(text: string): Promise<Uint8Array> {
  const data = new TextEncoder().encode(text);
  return new Uint8Array(await crypto.subtle.digest('SHA-256', data));
}

// Constant-time compare that runs identically under next dev and on Workers.
async function secretsMatch(presented: string | null, expected: string): Promise<boolean> {
  if (!presented) return false;
  const a = await sha256(presented);
  const b = await sha256(expected);
  let diff = 0;
  for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
  return diff === 0;
}

function mapRow(row: Row, fieldMap: Record<string, string>): Row {
  const out: Row = {};
  for (const [airtableColumn, cmsField] of Object.entries(fieldMap)) {
    if (row[airtableColumn] !== undefined) out[cmsField] = row[airtableColumn];
  }
  return out;
}

// Writes mapped rows as draft items, 100 per request, one request at a time.
async function createItems(collectionId: string, token: string, rows: Row[]): Promise<WriteResult> {
  // skipInvalidFiles=false makes a bad image URL fail loudly instead of being dropped.
  const url = `https://api.webflow.com/v2/collections/${collectionId}/items/insert?skipInvalidFiles=false`;
  let created = 0;
  for (let i = 0; i < rows.length; ) {
    const chunk = rows.slice(i, i + BATCH);
    const res = await fetch(url, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json',
        Accept: 'application/json',
      },
      body: JSON.stringify({ items: chunk.map((fieldData) => ({ isDraft: true, fieldData })) }),
    });
    if (res.status === 429) {
      const wait = Number(res.headers.get('Retry-After') ?? '5');
      await new Promise((resolve) => setTimeout(resolve, wait * 1000));
      continue; // retry the same chunk
    }
    if (!res.ok) {
      const error = await res.json().catch(() => null);
      return { ok: false, created, failedAtRow: i, status: res.status, error };
    }
    created += chunk.length;
    i += BATCH;
  }
  return { ok: true, created };
}

export async function POST(request: Request) {
  const secret = process.env.IMPORT_SHARED_SECRET;
  const token = process.env.WEBFLOW_API_TOKEN;
  const collectionId = process.env.WEBFLOW_COLLECTION_ID;

  if (!secret || !token || !collectionId) {
    return NextResponse.json({ error: 'Import route is not configured' }, { status: 500 });
  }

  let parsedFieldMap: unknown;
  try {
    parsedFieldMap = JSON.parse(process.env.WEBFLOW_FIELD_MAP ?? '{}');
  } catch {
    return NextResponse.json({ error: 'WEBFLOW_FIELD_MAP is not valid JSON' }, { status: 500 });
  }

  if (
    parsedFieldMap === null ||
    typeof parsedFieldMap !== 'object' ||
    Array.isArray(parsedFieldMap) ||
    Object.entries(parsedFieldMap).length === 0 ||
    Object.entries(parsedFieldMap).some(
      ([airtableColumn, cmsField]) =>
        airtableColumn.length === 0 || typeof cmsField !== 'string' || cmsField.length === 0
    )
  ) {
    return NextResponse.json(
      { error: 'WEBFLOW_FIELD_MAP must be a non-empty JSON object with non-empty string mappings' },
      { status: 500 }
    );
  }

  const fieldMap = parsedFieldMap as Record<string, string>;

  if (!(await secretsMatch(request.headers.get('x-import-secret'), secret))) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  let body: unknown;
  try {
    body = await request.json();
  } catch {
    return NextResponse.json({ error: 'Body must be JSON' }, { status: 400 });
  }

  const rows: Row[] = Array.isArray(body) ? (body as Row[]) : [body as Row];
  if (rows.some((r) => r === null || typeof r !== 'object' || Array.isArray(r))) {
    return NextResponse.json(
      { error: 'Each row must be a JSON object' },
      { status: 400 }
    );
  }

  const items = rows.map((row) => mapRow(row, fieldMap));

  // ?dryRun=1 checks authentication and mapping without writing anything.
  if (new URL(request.url).searchParams.get('dryRun') === '1') {
    return NextResponse.json({ dryRun: true, count: items.length, items });
  }

  const result = await createItems(collectionId, token, items);
  if (!result.ok) {
    return NextResponse.json(
      {
        created: result.created,
        failedAtRow: result.failedAtRow,
        webflowStatus: result.status,
        webflowError: result.error,
      },
      { status: 502 }
    );
  }
  return NextResponse.json({ created: result.created }, { status: 201 });
}

Una escritura exitosa devuelve 201 con {"created": n}. Si Webflow rechaza un lote, la ruta se detiene y devuelve 502 con cuántos elementos se crearon, failedAtRow (la primera fila del lote rechazado) y el error propio de Webflow, cuyo details nombra el campo infractor.

Todo lo anterior a failedAtRow ya está en la Colección, así que reanuda desde esa fila en lugar de reenviar toda la matriz. skipInvalidFiles=false se establece deliberadamente: el valor predeterminado de Webflow descarta silenciosamente una imagen que no puede obtener y aun así informa de éxito.

Consideraciones de seguridad para la autenticación con secreto compartido

El encabezado de secreto compartido autentica a los llamadores y el secreto permanece en una variable del lado del servidor sin un prefijo NEXT_PUBLIC_, así que mantenlo fuera de cualquier código del navegador. Cualquiera que lo tenga puede escribir en la Colección, y la ruta no tiene límite de tasa ni protección contra repetición: reenviar las mismas filas crea borradores duplicados.

Dos cosas contienen el daño. Cada elemento llega como borrador, por lo que nada llega al sitio en vivo sin que un editor lo publique, y la casilla de verificación Imported evita que el Zap envíe una fila dos veces. Cambia el secreto cada vez que alguien que lo tenía deje el proyecto.

La ruta ahora puede autenticar las solicitudes entrantes, validar su estructura JSON, asignar filas de Airtable a nombres de campo del CMS y crearlas como elementos de borrador.

3. Configura las variables de entorno y despliega en Webflow Cloud

Configura el secreto compartido, el mapa de campos, el token de API y el ID de la Colección en el entorno de Webflow Cloud, luego despliega la aplicación en el proyecto y monta la ruta conectada a tu sitio. Mantén el secreto en el lado del servidor y formatea el mapa de campos como un objeto JSON de una sola línea.

Usa estos detalles de configuración para conectar la ruta desplegada con sus llamadores:

  • IMPORT_SHARED_SECRET: Almacena la cadena larga y aleatoria que autentica las solicitudes de Zapier y Postman como una variable de entorno secreta.
  • x-import-secret header: Envía el mismo valor secreto desde cada cliente bajo este nombre exacto de encabezado de solicitud.
  • WEBFLOW_FIELD_MAP: Asocia las columnas de Airtable con los campos del CMS usando JSON, como por ejemplo {"name":"name","slug":"slug","summary":"summary","body":"body"}.
  • WEBFLOW_API_TOKEN: Un token de API del sitio con el alcance CMS:write, almacenado como un secreto.
  • WEBFLOW_COLLECTION_ID: El ID de la colección donde se insertarán las filas.
  • Deployment route URL: Registra el dominio, la ruta de montaje y la /api/import ruta que Zapier y Postman deben llamar.

Together, these settings provide the route's authentication value, mapping rules, write access, target Collection and deployed address.En conjunto, estos ajustes proporcionan el valor de autenticación de la ruta, las reglas de mapeo, el acceso de escritura, la colección de destino y la dirección desplegada.

Malformed JSON in the field map returns a clear 500, as does a value that is not a non-empty object of non-empty string mappings. A mistyped column name can still pass those structural checks, so it drops that field without an error; you catch it in the validation response.Un JSON mal formado en el mapa de campos devuelve un error 500 claro, al igual que un valor que no sea un objeto no vacío de mapeos de cadenas no vacías. Un nombre de columna mal escrito puede superar esas comprobaciones estructurales, por lo que el campo se descarta sin error; podrás detectarlo en la respuesta de validación.

Install the Webflow CLI, then deploy to the Webflow Cloud project and mount path linked to the site. Write down the full route URL, including the mount path, so requests from Zapier and Postman reach the deployed handler.Instala la CLI de Webflow y luego despliega en el proyecto de Webflow Cloud y la ruta de montaje vinculada al sitio. Anota la URL completa de la ruta, incluyendo la ruta de montaje, para que las solicitudes de Zapier y Postman lleguen al manejador desplegado.

Once the deployment finishes, the environment lists all four variables and the route answers at a URL of the form https://your-domain/your-mount-path/api/import.Una vez finalizado el despliegue, el entorno enumera las cuatro variables y la ruta responde en una URL con el formato .

4. Prove the route with Postman before Zapier touches it4. Prueba la ruta con Postman antes de que Zapier intervenga

Create a POST request in Postman to the deployed route URL with ?dryRun=1 on the end, add a header named x-import-secret with your secret, and set the body to raw JSON. A readable response lets you catch mapping mistakes before they enter the automated workflow.Crea una solicitud POST en Postman a la URL de la ruta desplegada con al final, añade un encabezado llamado con tu secreto y configura el cuerpo como JSON sin formato. Una respuesta legible te permite detectar errores de mapeo antes de que entren en el flujo de trabajo automatizado.

Use a body that mirrors one Airtable row by column name:Usa un cuerpo que refleje una fila de Airtable por nombre de columna:

{
  "name": "Postman test entry",
  "slug": "postman-test-entry",
  "summary": "A row sent by hand to check the field map.",
  "body": "<p>Body content from Airtable.</p>"
}

The response includes "dryRun": true, "count": 1, and the mapped row inside items. Read the keys in the mapped item: every one should be the intended CMS field name, and any Airtable column missing from the field map should be absent. If a key is wrong, correct WEBFLOW_FIELD_MAP in the environment and resend.La respuesta incluye , y la fila mapeada dentro de . Lee las claves en el elemento mapeado: cada una debería ser el nombre del campo del CMS previsto, y cualquier columna de Airtable que falte en el mapa de campos debería estar ausente. Si una clave es incorrecta, corrige en el entorno y vuelve a enviar.

Send a request with a wrong secret too and confirm you get a 401 from this route. Save the Postman request so you can reuse it whenever the field map changes. Then remove ?dryRun=1, send one disposable row, and confirm it appears in the Collection as a draft.Envía también una solicitud con un secreto incorrecto y confirma que recibes un 401 de esta ruta. Guarda la solicitud de Postman para poder reutilizarla siempre que cambie el mapa de campos. Luego elimina , envía una fila desechable y confirma que aparece en la colección como borrador.

Once you've confirmed the mapping and the write, delete the disposable item. You now have a saved request that verifies the deployed route's authentication and field mapping before Zapier begins sending Airtable records.Una vez que hayas confirmado el mapeo y la escritura, elimina el elemento desechable. Ahora tienes una solicitud guardada que verifica la autenticación y el mapeo de campos de la ruta desplegada antes de que Zapier comience a enviar registros de Airtable.

5. Connect Zapier from the Airtable view to the route5. Conecta Zapier desde la vista de Airtable a la ruta

Configure an Airtable "New Record" trigger, which fires for records "when first added to a selected view", and point it at the Ready view. For the action, add "Webhooks by Zapier" with the event "POST".Configura un disparador de "Nuevo registro" en Airtable, que se activa para los registros "cuando se añaden por primera vez a una vista seleccionada", y asígnalo a la vista Ready. Para la acción, añade "Webhooks by Zapier" con el evento "POST".

Set the URL to the route, set Payload Type to JSON, and add one Data row per Airtable column, keyed by the column name, with the matching trigger field as its value. Finish with a Headers row named x-import-secret that holds the shared secret.Establece la URL a la ruta, configura el tipo de carga útil (Payload Type) como JSON y añade una fila de datos por cada columna de Airtable, usando el nombre de la columna como clave y el campo del disparador correspondiente como valor. Termina con una fila de encabezados llamada que contenga el secreto compartido.

Payload Type must be json. The route calls request.json() and answers 400 to a form-encoded body. Keep the Data keys identical to the column names in WEBFLOW_FIELD_MAP; a typo in a body key drops that field from the mapped output.El tipo de carga útil debe ser json. La ruta llama a y responde con un 400 ante un cuerpo codificado como formulario. Mantén las claves de datos idénticas a los nombres de las columnas en ; un error tipográfico en una clave del cuerpo hará que ese campo se elimine de la salida mapeada.

Prueba el Zap con un registro real de la vista. Luego, añade un tercer paso, la acción Actualizar registro de Airtable, que marque Imported en el mismo registro, y configúralo para que solo se ejecute cuando el paso del webhook devuelva created, así una fila rechazada permanece en la vista para su corrección.

El editor debería mostrar ahora el disparador, el cuerpo JSON y el encabezado secreto completado. El historial del Zap registra ahora cada casilla marcada en Airtable como una ejecución, con la respuesta de la ruta adjunta y la fila marcada Imported una vez que su elemento existe.

6. Ejecuta el lote y elige el carril adecuado según su tamaño

Selecciona las filas de Airtable que quieres procesar marcando Ready, luego observa cómo se llena el historial del Zap. Cada registro seleccionado dispara una ejecución, y cada ejecución envía una fila a la ruta.

Para una carga grande única, el carril de Postman puede ser más barato y rápido; yo lo uso para la primera pasada de validación y dejo Zapier para el goteo posterior.

Uso del carril de matriz de Postman para importaciones iniciales de gran volumen

Exporta la tabla de Airtable a CSV, conviértela a una matriz JSON en tu propia máquina (una herramienta de hoja de cálculo o unas pocas líneas de script bastarán), y pega toda la matriz en el cuerpo de Postman. Mantén el CSV fuera de la ruta y envía su JSON convertido a través de la misma ruta de solicitud utilizada para la validación.

La ruta ya acepta una matriz, por lo que una solicitud de Postman puede validar toda la tabla, y la respuesta devuelve un count para que puedas confirmar el total de filas. Divide las matrices muy grandes en unas pocas solicitudes en lugar de una; un lote más pequeño termina antes, y su lista mapeada es más fácil de inspeccionar.

Debido a que los límites de solicitud, los controles de tasa y la protección contra repetición aún no están implementados, utiliza este carril de matriz solo para validación controlada.

Independientemente del carril que uses, los elementos llegan como borradores. Revísalos en la Colección y publícalos cuando estén listos. Una sola solicitud de Postman puede llevar unos cientos de filas, ya que la ruta escribe 100 por llamada y una solicitud tiene 20 segundos; para miles, divide la matriz.

Aplica la imported actualización fila por fila. Las filas rechazadas o no procesadas permanecen disponibles para su corrección y una nueva ejecución.

¿Qué causa que una importación de Zapier a Webflow CMS falle?

Estas importaciones suelen fallar debido a una exportación de tiempo de ejecución incompatible, una discrepancia en el secreto desplegado, un lote demasiado grande o una fila que la validación de Webflow rechaza.

Usa el síntoma visible para separar los problemas de configuración de Webflow Cloud del comportamiento de mapeo y los fallos en la operación del CMS en vivo.

La compilación de Webflow Cloud falla en una ruta de API copiada desde la página de "bring-your-own-app"

Causa: La ruta copiada conserva la exportación de tiempo de ejecución incompatible. La página de "bring-your-own-app" usa una palabra para dos conceptos: Cloudflare Workers es una plataforma de borde (edge), y la documentación describe el alojamiento como "el tiempo de ejecución Edge", pero la exportación de tiempo de ejecución edge de Next.js es un objetivo de compilación separado.

Solución: Elimina la exportación de cada ruta y diseño en la aplicación y vuelve a compilar. El manejador de rutas se ejecuta en Workers sin ella. Si tienes un middleware.ts también, mantén el nombre: el middleware de tiempo de ejecución de Node.js no es compatible con Workers, y renombrarlo a proxy.ts, como sugieren las guías más recientes de Next.js, produce un archivo que se ejecuta en el tiempo de ejecución de Node y no puede optar por Edge, por lo que no se ejecutará en absoluto.

Revisa cada ruta y diseño, no solo el archivo de importación, porque una sola exportación incompatible restante aún puede detener la compilación de la aplicación antes de que el manejador reciba una solicitud.

Zapier y Postman obtienen un 401 de la URL desplegada, pero la misma solicitud tiene éxito contra localhost

Causa: La ruta compara el encabezado contra IMPORT_SHARED_SECRET del entorno desplegado, y ese valor no coincide con el que está en tu archivo local .env . Este manejador devuelve 401 cuando su comparación falla y 500 cuando la variable falta por completo. Por lo tanto, un 401 con el encabezado esperado suele significar que el valor desplegado difiere del local, por ejemplo, porque se pegó un salto de línea al final en el campo del panel de control.

Solución: Abre el entorno de Webflow Cloud, vuelve a introducir el secreto sin espacios alrededor y vuelve a desplegar: el valor modificado solo llega a la aplicación tras un despliegue. Luego, envía la solicitud de Postman guardada a la ruta desplegada para verificarlo. Las variables se configuran por entorno; confirma que las cuatro existen en aquel al que apunta tu URL.

Si el error 401 persiste, haz que la ruta devuelva temporalmente si la x-import-secret cabecera llegó o no, nunca su valor. Si falta la cabecera, el problema está en la fila de cabeceras del Zap; si está presente, el problema es una discrepancia en el valor.

Los lotes grandes agotan el tiempo de espera o fallan a mitad del proceso

Causa: La ruta escribe 100 elementos por llamada, una tras otra, y cada llamada cuenta para el límite de velocidad de la API de datos de 60 solicitudes por minuto en los planes Starter y Basic, y 120 en los planes CMS, Ecommerce y Business. Un array muy largo puede superar el tiempo de espera de 20 segundos de la plataforma, especialmente cuando Retry-After comienzan las esperas.

Solución: Divide el array en solicitudes de unos pocos cientos de filas y envía cada una solo después de que la anterior haya respondido. Si una solicitud falla a mitad, su respuesta proporciona created y failedAtRow: cada fila anterior a failedAtRow ya está en la colección, así que reenvía desde esa fila en lugar de enviar todo el array.

Mantén el carril del Zap para importaciones graduales, ya que envía una fila por ejecución y nunca se acerca a ninguno de los límites.

La ruta devuelve un error 502 con un error de validación de Webflow

Causa: Webflow rechazó un lote, generalmente porque falta un campo obligatorio o un slug ya está en uso. El mapeo puede ser correcto y los valores seguir siendo inválidos. La ruta se detiene en el primer lote rechazado y devuelve el error de Webflow, cuyo details array nombra el campo que falló.

Solución: Lee webflowError.details en la respuesta 502. Cada entrada nombra un campo, como items[20].fieldData.slug, donde el índice cuenta desde el inicio del lote fallido, así que suma failedAtRow para encontrar la fila de Airtable. Corrige esa fila en Airtable y reenvía desde failedAtRow.

Si el slug ya está en uso, cámbialo en Airtable o elimina primero el elemento existente, luego ejecuta la ?dryRun=1 solicitud para confirmar el mapeo antes de volver a escribir.

Qué puedes construir a continuación con Zapier, Airtable y el CMS de Webflow

Explora la integración de Webflow con Zapier para crear flujos de trabajo más automatizados, o mantén Airtable como fuente en tiempo real en lugar de una importación con Airtable como base de datos.

Para una personalización más profunda más allá de esta ruta de importación, la documentación para desarrolladores de Webflow cubre la API de datos.

Preguntas frecuentes

¿Puede Zapier llamar a la API del CMS de Webflow directamente en lugar de pasar por una ruta de Webflow Cloud?

Sí, de forma nativa: la integración de Zapier con Webflow tiene acciones para crear elementos y crear elementos en vivo que no requieren código. Úsalas a menos que necesites campos de referencia o multirreferencia, que el centro de ayuda de Webflow indica que Zapier no puede mapear, o si deseas la validación y el procesamiento por lotes que añade esta ruta.

¿Cómo puedo rotar el secreto compartido sin romper el Zap?

Rótalo mientras no haya filas de Airtable marcadas como "Ready". Debes actualizar IMPORT_SHARED_SECRET en Webflow Cloud y la cabecera x-import-secret del Zap al mismo tiempo, volver a desplegar y luego enviar la solicitud de Postman guardada con el nuevo valor. Cualquier ejecución que ocurra entre esos cambios recibirá un 401, así que pausa el trabajo entrante hasta que la prueba sea exitosa.

¿Puedo construir la ruta en Astro o Vite en lugar de Next.js?

Astro, sí; Vite, no según la documentación, porque Webflow no describe endpoints de servidor para aplicaciones Vite. En una aplicación Astro 6 o 7, la lógica de mapeo y escritura se transfiere sin cambios, pero lee el entorno desde locals.runtime.env en lugar de process.env. El resto del controlador se mantiene: sigue comparando el secreto con la rutina SHA-256 XOR, mapea cada fila y escribe los lotes en /items/insert. Solo necesitas cambiar los envoltorios de solicitud y respuesta de tu framework.

¿Puede la ruta actualizar elementos existentes en lugar de crear otros nuevos?

Sí, con una segunda llamada. La API de datos actualiza los elementos con PATCH /v2/collections/{collection_id}/items/{item_id}, así que la fila necesita el ID del elemento de Webflow, que la respuesta de creación devuelve, y puedes escribir de vuelta en Airtable en el mismo paso de Actualizar registro.

¿Puedo volver a ejecutar una fila sin crear un duplicado?

No solo con la creación: cada ejecución exitosa genera un nuevo borrador, así que la Imported casilla de verificación es tu escudo contra duplicados. Márcala solo después de que la ruta devuelva created, y reenvía solo las filas que quedaron sin marcar. Reenviar una fila que ya se procesó crea un segundo borrador, que un editor puede eliminar antes de publicar.


Última actualización
October 2, 2026
Categoría

Artículos relacionados


verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo
verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo

Empieza gratis

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.

Empieza, es gratis
Ver demostración

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.