ZapyFlow/Documentación de la APIopenapi.json

Integraciones nativas

Google Sheets, Google Calendar, Notion y HubSpot, conectados por OAuth desde el panel y movidos por el mismo catálogo de eventos que los webhooks.

El modelo

Una conexión es una concesión OAuth a una cuenta externa. Un vínculo dice “cuando ocurra order.created, ejecuta sheets.append_rowcon esta configuración”. Cada evento que casa con un vínculo produce una sincronización, y su historial es consultable.

bash
curl https://api.zapyflow.com.br/api/integrations \
  -H "Authorization: Bearer $ZAPYFLOW_API_KEY"
Conectar no forma parte de la API pública. Requiere una ida y vuelta por el navegador con consentimiento humano, y publicar un endpoint que te devuelve una URL para pulsar sería invitar a automatizar un flujo cuyo propósito entero es que una persona lo haya aprobado. Conecta en el panel; lee, configura y supervisa por la API.

Google — una conexión, dos capacidades

Sheets y Calendar aparecen como dos capacidades de una únicaconexión de Google, no dos conexiones. Revocar cualquier token de una concesión de Google revoca la concesión entera, así que dos conexiones separadas harían que “desconectar Sheets” matara en silencio la sincronización de tu Calendar. Añadir la segunda capacidad dispara consentimiento incremental.

Para Sheets pedimos drive.file, no acceso completo a hojas de cálculo: alcanza solo los archivos que eliges explícitamente, que es suficiente para añadir una fila.

Un reintento no duplica tus datos

Esta es la propiedad que decide si una integración es usable, y cada proveedor recibe el mecanismo más fuerte que de verdad ofrece — no uno genérico.

AcciónCómo se hace seguro el reintento
calendar.upsert_eventGoogle acepta un id de evento provisto por el cliente, así que lo derivamos de la cita. Una inserción duplicada devuelve 409 y cambiamos a patch. Creación idempotente de verdad, sin lectura extra.
hubspot.upsert_contact / upsert_dealCreamos las propiedades personalizadas zapyflow_lead_id y zapyflow_order_id con hasUniqueValue y usamos el upsert nativo por lotes de HubSpot. También casa el lead de WhatsApp que tiene teléfono y no correo — la mayoría aquí.
sheets.append_rowSheets no tiene upsert, así que la hoja necesita una columna zapyflow_event_id. El camino feliz es un solo append; solo recorremos esa columna en un reintento ambiguo (un fallo después de que la petición salió).
notion.create_pageMisma forma: una propiedad ZapyFlow ID en la base, consultada solo en un reintento ambiguo.

La actualización encuentra el registro que creó su creación: la referencia se indexa por la entidad (pedido, lead, cita), no por el evento. Sin eso, order.updated abriría un negocio nuevo en tu embudo cada vez.

Tratamiento de fallos

Las sincronizaciones reintentan con el mismo calendario que los webhooks — seis intentos a lo largo de ~31 horas — pero solo para fallos que el tiempo arregla. Una concesión revocada o un destino borrado son terminales.

EstadoSignificado
SUCCEEDEDEscrito en el proveedor. externalRef guarda el id de su lado.
SKIPPEDDeliberadamente no escrito — por ejemplo, la hoja no tiene la columna de id. El motivo queda en la sincronización.
FAILEDFallo terminal. Arregla la causa y reintenta.
EXHAUSTEDLos seis intentos se agotaron.

Tras 20 fallos consecutivos se apaga el vínculo — no la conexión. Una hoja rota no puede tumbar una sincronización de Calendar que funciona en la misma cuenta.

Conexiones revocadas

Cuando alguien revoca el acceso en el proveedor, nada nos avisa. Una sonda diaria lo detecta en menos de 24 horas y mueve la conexión a REVOKED, lo que muestra la petición de reconexión en el panel y pausa sus vínculos en vez de quemar reintentos.

Desconectar

DELETE /api/integrations/{installationId} borra la credencial que guardamos y desactiva los vínculos. La respuesta dice si además pudimos revocar en el proveedor — Notion no tiene endpoint de revocación, y devolvemos revokedAtProvider: false en vez de dar a entender un corte de acceso que no hicimos.