Control Horario·Legal
Producto · 17/08/2026

Conectar el fichaje con Google Sheets o AppSheet: guía con la API

Código de Apps Script listo para copiar, qué endpoint pedir según lo que necesites (y por qué pedir el equivocado te cuesta una tarde), el patrón que funciona en AppSheet, y las tres cosas —zonas horarias, truncado y geolocalización— que te ahorrarán depurar de noche.

Respuesta corta: se conecta con una clave de API y peticiones HTTP. Desde Google Sheets, con una función de Apps Script que trae los fichajes a una pestaña. Desde AppSheet, apoyándote en esa misma hoja. No hacen falta webhooks ni integraciones especiales: una consulta programada cada quince minutos, o una pasada nocturna, cubre el 95% de los casos.

El caso típico

Tienes tu gestión de proyectos montada en una hoja de cálculo, con las horas presupuestadas de cada trabajo. Y tienes el fichaje, que sabe las horas reales. Lo que quieres es que la comparación se haga sola.

Es una integración pequeña y bien delimitada: leer datos, escribirlos en una pestaña, y dejar que las fórmulas que ya tienes hagan el resto. No necesitas un proyecto de integración.

Paso 1: la clave de API

En Control Horario Legal se genera desde Ajustes → Integraciones. Se muestra una sola vez, así que guárdala en el gestor de contraseñas antes de cerrar la pantalla.

Tres cosas que conviene saber antes de seguir:

  • La clave es de solo lectura por defecto. Para lo que vamos a hacer, es justo lo que quieres.
  • Identifica a la empresa entera, no a un usuario. Trátala como una contraseña: no la pegues en una celda de la hoja compartida.
  • Usa una clave por integración. Si mañana tienes que revocar la de la hoja, no tumbas nada más.

Paso 2: decidir qué endpoint necesitas

Aquí es donde se gana o se pierde el tiempo. Hay dos formas de responder «cuántas horas lleva esta persona este mes», y una es mucho más barata:

  • /api/v1/fichajes te da los apuntes sueltos (entrada, pausa, salida). Los necesitas si quieres el detalle: a qué hora entró cada día, desde qué método, con qué proyecto.
  • /api/v1/horas te da los totales ya sumados por empleado y periodo. Si solo quieres el total, no emparejes apuntes en Apps Script: pide esto.
  • /api/v1/proyectos/horas te da horas fichadas frente a previstas por proyecto, con la desviación calculada. Si tu caso es exactamente comparar presupuesto contra real, este endpoint puede ahorrarte toda la lógica de la hoja.

Paso 3: traer los datos a Google Sheets

En la hoja: Extensiones → Apps Script. El código mínimo que funciona:

const API_KEY = 'chl_tu_clave';   // mejor en Propiedades del script
const BASE = 'https://controlhorariolegal.com/api/v1';

function traerFichajes() {
  const hoy = new Date();
  const desde = Utilities.formatDate(new Date(hoy.getFullYear(), hoy.getMonth(), 1), 'Europe/Madrid', 'yyyy-MM-dd');
  const hasta = Utilities.formatDate(hoy, 'Europe/Madrid', 'yyyy-MM-dd');

  const res = UrlFetchApp.fetch(
    BASE + '/fichajes?desde=' + desde + '&hasta=' + hasta,
    { headers: { 'X-Api-Key': API_KEY }, muteHttpExceptions: true }
  );
  const data = JSON.parse(res.getContentText());
  if (!data.ok) throw new Error(data.error);

  const filas = data.fichajes.map(f => [
    f.id, f.fecha, f.hora, f.empleado, f.tipo,
    f.centro, f.referencia || '', f.proyecto ? f.proyecto.codigo : ''
  ]);

  const hoja = SpreadsheetApp.getActive().getSheetByName('Fichajes');
  hoja.clear();
  hoja.appendRow(['ID','Fecha','Hora','Empleado','Tipo','Centro','Referencia','Proyecto']);
  if (filas.length) hoja.getRange(2, 1, filas.length, filas[0].length).setValues(filas);
}

Guarda la clave en Configuración del proyecto → Propiedades del script en lugar de dejarla en el código, y léela con PropertiesService.getScriptProperties().getProperty('API_KEY'). Si compartes la hoja, el código va con ella.

Para programarlo: Activadores → Añadir activador, temporizador cada hora o diario. Una pasada nocturna del día anterior es suficiente para informes; cada 15 minutos si quieres algo cercano al tiempo real.

Paso 4: la comparación con lo presupuestado

Si tu maestro de proyectos vive en la hoja, cruza por el código con un SUMIF contra la columna Proyecto y ya tienes previsto contra real.

Pero hay un atajo que mucha gente se pierde: si das de alta esos mismos códigos en el maestro de proyectos de Control Horario Legal, la comparación te la devuelve hecha:

GET /api/v1/proyectos/horas?desde=2026-08-01&hasta=2026-08-31

Y devuelve, por proyecto, horas fichadas, previstas, desviación y porcentaje consumido. Menos fórmulas que mantener.

Cómo hacer que los fichajes lleguen ya imputados

Si el fichaje entra desde tu propio sistema por API, puedes mandar tu código interno de obra en el campo referencia. Si coincide con un proyecto del maestro, el fichaje queda imputado solo, sin que nadie elija nada.

Si tu gente ficha desde el móvil de la app, se elige en un desplegable al fichar la entrada, entre los proyectos que tenga asignados.

Y en AppSheet

AppSheet no llama a APIs REST arbitrarias con comodidad. El patrón que funciona es no intentarlo: que Apps Script escriba en la hoja y AppSheet lea la hoja. Ganas caché, historial y depuración trivial —si algo falla, lo ves en la pestaña—.

Si necesitas refrescar bajo demanda desde la app, una acción de AppSheet puede llamar a un webhook de Apps Script desplegado como aplicación web, que a su vez ejecuta la función de arriba.

Tres cosas que te ahorrarán depurar de noche

  • Zonas horarias. El campo ts viene en UTC; fecha y hora vienen ya convertidos a la hora local del centro. Usa estos últimos para presentar y el ts para ordenar. Mezclarlos es el origen clásico del error de una hora.
  • Volumen. Una consulta admite 366 días de rango y devuelve hasta 10.000 apuntes; si se alcanza el tope, la respuesta trae truncado: true. Comprueba ese campo en lugar de suponer.
  • Geolocalización. No viaja salvo que la pidas con ?geo=1. Si la traes a la hoja, recuerda que sigue siendo un dato personal: refléjalo en tu registro de actividades de tratamiento y limita quién ve esa pestaña.

No hay webhooks: por qué y qué hacer

No emitimos webhooks salientes. Es una limitación real y preferimos decirla antes de que diseñes contando con ellos. Para este caso de uso el polling acotado funciona igual de bien y es más fácil de depurar: si una pasada falla, la siguiente recupera, sin colas ni reintentos que mantener.

Si lo que quieres es un panel de presencia en vivo, /api/v1/presencia te resuelve toda la plantilla en una sola llamada.


Una API pensada para que la integres tú

Documentación pública en controlhorariolegal.com/api, claves de solo lectura por defecto, y endpoints que devuelven las horas ya sumadas y las desviaciones por proyecto ya calculadas. Incluida en el plan Pro, y disponible durante los 30 días de prueba.

Probar 30 días gratis →

Preguntas frecuentes

¿Necesito el plan Pro para usar la API?

Sí, la API está incluida en el plan Pro. Durante los 30 días de prueba la cuenta funciona con permisos de Pro, así que puedes montar y validar la integración completa antes de contratar nada.

¿Puedo crear una clave de API que solo pueda leer?

Sí, y es lo que obtienes por defecto: todas las claves nacen de solo lectura. Escribir en el registro requiere un permiso adicional que se concede caso por caso. Para llevar datos a una hoja de cálculo no necesitas escritura.

¿Hay webhooks para avisar de nuevos fichajes?

No. Para mantener sincronizado un sistema externo se consulta el endpoint de fichajes con un rango acotado: cada 15 minutos si se necesita algo cercano al tiempo real, o una pasada nocturna del día anterior para informes.

¿Cómo obtengo las horas totales de cada trabajador sin sumar los apuntes?

Con el endpoint /api/v1/horas, que devuelve días trabajados y horas totales por empleado y periodo, en decimal y en HH:MM. Usa el mismo cálculo que el export para nómina, así que la integración y el CSV de la gestoría no pueden dar cifras distintas.

¿Puedo mandar mi código interno de proyecto en cada fichaje?

Sí. Cada fichaje admite un campo referencia de texto libre de hasta 64 caracteres. Si ese código coincide con el de un proyecto dado de alta en el maestro, el fichaje queda imputado a ese proyecto automáticamente.

¿Qué límites de consulta tiene la API?

Cada clave dispone de 180 unidades por minuto y 6.000 por hora, donde cada llamada gasta según lo que cuesta: consultar /ping o /proyectos vale 1 unidad y /fichajes o /proyectos/horas valen 8. En la práctica son 22 consultas seguidas de las más caras por minuto, muy por encima de lo que necesita una integración que sincroniza cada quince minutos. Cada respuesta incluye la cabecera X-RateLimit-Remaining para que no tengas que estimarlo, y si agotas el margen recibes un 429 con los segundos de espera en Retry-After. Además hay topes por consulta: máximo 366 días de rango y 10.000 registros por respuesta en el endpoint de fichajes, y 62 días en el de horarios planificados.

Última actualización: 17 de agosto de 2026. Este artículo tiene fines informativos y no constituye asesoramiento legal.