El constructor de APIs
Crear APIs de la app como pipelines de pasos — SQL, llamadas HTTP y scripts — con argumentos, prueba integrada y documentación generada.
Cada API de Keplin es una operación GraphQL de la app: una query que lee datos o una mutation que los escribe. Las pantallas de la propia app, los informes, los workflows y los sistemas externos llaman todos a las mismas APIs — lo que defines aquí es el único camino de entrada y salida de datos de la aplicación.
Una API puede tener una de dos naturalezas:
| Naturaleza | Qué es | Dónde se profundiza |
|---|---|---|
| Pipeline | Una secuencia de pasos (Query SQL, Llamada HTTP, Script) que corre en orden; el resultado del último paso es la respuesta. | Esta página |
| Tabla | Un bloque único conectado a una tabla del modelo de datos, que genera las operaciones de lectura y escritura (get/add/update/delete) por ti. | La API GraphQL del modelo |
Esta página cubre el constructor en sí: crear la API, definir argumentos, montar el pipeline, probar sin guardar y publicar.
Dónde viven las APIs
Dentro de una app, abre el panel Código en la barra lateral. La sección APIs lista las APIs existentes — puedes organizarlas en carpetas con Nueva carpeta — y cada una se abre como pestaña del espacio de trabajo. La app tiene también una página de resumen con la lista completa, el tipo y el estado de cada API, y la dirección donde se sirven.

Nota
En la parte superior de la lista ves la dirección de la app: todas las
operaciones se sirven en un único endpoint GraphQL, del estilo
/api/graphql/gestao-clientes. No hay una URL por API — hay un campo
GraphQL por API.
Crear una API
- En el panel Código, en la fila APIs, pulsa el botón + (Nueva API). El botón Nueva API de la página de resumen te lleva al mismo sitio: el espacio de trabajo de la app.
- Dale un Nombre. El nombre es el campo GraphQL que los clientes van
a llamar, así que sigue la regla: letras, números y guion bajo, sin
empezar por número — por ejemplo
getOportunidadesPorConta. - Pulsa Crear API. La API nace en borrador y el constructor se abre a continuación — ahí decides la naturaleza (bloques SQL, HTTP, script o tabla).

Consejo
Si la API va a ser de Tabla, no uses prefijos como get o add en
el nombre: el nombre es la BASE de las operaciones. En una API de tabla
llamada contas se generan getContas, addContas, updateContas y
deleteContas — según las acciones que actives.
El constructor de un vistazo
La cabecera del constructor muestra el nombre, un sello con el tipo
(query, mutation o tabla) y el estado (publicada o
borrador). A la derecha quedan los comandos que valen para la API
entera:
| Comando | Qué hace |
|---|---|
| Publicada | Activa/desactiva la publicación. Una API en borrador solo es visible para quien construye; los clientes externos no la ven. |
| Pública (sin sesión) | Hace la API accesible sin sesión ni clave API — para pantallas públicas de la app. Ver APIs públicas. |
| Guardar | Guarda la API tal como está. Guardar es siempre posible con nombre y argumentos válidos — el trabajo a medias se guarda igualmente. |
Debajo, el trabajo se divide en tres pestañas:
| Pestaña | Para qué |
|---|---|
| Construir | Identificación, argumentos y el pipeline de pasos. |
| Probar | Ejecutar el pipeline en borrador y experimentar la API como un cliente. |
| Docs | Ejemplos listos para copiar para llamar a la API desde fuera. |

Identificación
En la sección Identificación defines:
- Operación — Query — lee datos o Mutation — escribe datos. La elección es semántica y práctica: las mutations piden confirmación antes de cada ejecución de prueba, porque escriben de verdad.
- Nombre — el campo GraphQL. Si el nombre es inválido, el constructor avisa: «camelCase simple: letras, números y guion bajo, sin empezar por número.»
En una API de Tabla no hay elección de operación — las operaciones derivan de las acciones CRUD que actives en el bloque Tabla.
Argumentos
La sección Argumentos declara los parámetros que los clientes pasan a la API. Cada argumento tiene:
| Columna | Qué es |
|---|---|
| Nombre | Identificador del argumento (letras, números, guion bajo; no empieza por número). |
| Tipo | Uno de: String, Int, Float, Boolean, ID, JSON, Upload. |
| Oblig. | Si el cliente está obligado a enviar el argumento. |
| Default | Valor usado cuando el cliente no envía nada. |
| Valor de prueba | Solo para el botón Ejecutar de la pestaña Probar — no afecta a los clientes. |
Dentro del pipeline, los argumentos quedan disponibles como :nombre en
los pasos SQL y HTTP, y como input["args"]["nombre"] en el paso Script.

Consejo
Escribe primero el pipeline si lo prefieres: cuando usas :unNombre en
un paso sin haberlo declarado, aparece la franja «Usados en el pipeline
pero aún por declarar:» con un botón por nombre — un clic y el argumento
queda creado.
Archivos como argumento (tipo Upload)
Un argumento de tipo Upload recibe un archivo. En ese caso la columna
Default da lugar a la elección del almacenamiento: De la app usa el
almacenamiento por defecto; como alternativa elige uno de los
almacenamientos configurados en los ajustes de la app (sección
Almacenamiento). Así, una API que recibe facturas y otra que recibe
fotografías no tienen que guardar los archivos en el mismo sitio.
Qué pasa cuando la API se llama con un archivo:
- El archivo se guarda en el almacenamiento elegido.
- En el pipeline, el argumento deja de ser el archivo en bruto y pasa a
ser una referencia con
filename,mimeType,sizey untoken— es esto lo que un paso Script recibe eninput["args"]["nombreDelArg"]. - La app se queda con el registro del archivo, como cualquier otro archivo subido por los usuarios.
Para probar, la columna de valor de prueba se transforma en un selector de archivo — elige uno de tu ordenador y pulsa Ejecutar.
Atención
Si la app tiene varios almacenamientos y ninguno marcado como por
defecto, una llamada con Upload sin almacenamiento elegido se rechaza —
la plataforma no elige uno por ti.
Desde fuera, el archivo se envía como variable multipart de la petición GraphQL (el formato estándar de subida GraphQL); dentro de la plataforma, las pantallas se encargan por ti.
El pipeline
La sección Pipeline es donde la API gana cuerpo. Las reglas son simples:
- Los pasos corren en orden; el resultado del último es la respuesta de la API.
- Cada paso (a partir del segundo) puede recibir el resultado del anterior — el sello «recibe el resultado del paso N» lo recuerda.
- En los pasos SQL y HTTP, el resultado anterior está en
:prev, y acepta rutas::prev.id,:prev.0.id. - Añades pasos con los botones Query SQL, Llamada HTTP y Script; el botón Tabla convierte la API a la naturaleza de tabla (y no se combina con los demás bloques).
Mientras no haya bloques, la sección sugiere el camino: el default es una Tabla del modelo; como alternativa, se construye un pipeline con los pasos descritos a continuación.
Paso Query SQL
- Elige el Datasource — una de las bases de datos registradas en la app. Sin datasources, el paso muestra el atajo para crear el primero.
- Escribe la query en el editor. Escribe
:para autocompletar argumentos; el editor conoce las tablas y columnas del datasource elegido y las sugiere mientras escribes. - Si la query devuelve una única fila por naturaleza (un total, un registro por clave), activa Devolver solo la primera fila — la respuesta pasa de lista a objeto.
Los valores de :argumento y :prev van siempre parametrizados a la
base de datos — nunca concatenados en el texto de la query. Eso te protege
de inyección de SQL sin ningún esfuerzo.

Consejo
A partir del segundo paso, :prev también aparece en el autocompletado —
después de una ejecución de prueba, las sugerencias incluyen las rutas
reales del resultado anterior (ej.: :prev.0.id). Para transformar
listas grandes entre pasos, mete un paso de código en medio.
Un : solo es un argumento donde la base de datos lo lee como tal. Dentro
de un texto (':x'), de un nombre entre comillas, de un comentario o en un
cast de PostgreSQL (valor::int), se queda como está.
El SQL del paso se guarda formateado en el dialecto del datasource elegido.
Solo cambian espacios y saltos de línea: las palabras mantienen las mayúsculas
que tenían, y los textos, los comentarios, los casts y los marcadores
:nombre quedan intactos.
Paso Llamada HTTP
Para hablar con servicios externos:
- Elige el Método (GET, POST, PUT, PATCH o DELETE) y rellena la
URL — ej.:
https://api.ejemplo.es/clientes/:clienteId. - Añade Headers con Añadir header — por ejemplo
Authorizationcon el valorBearer :token. - En los métodos con cuerpo, rellena el Body; activa Enviar como JSON para que el cuerpo vaya con el tipo de contenido correcto.
:nombreDelArg y :prev se sustituyen en la URL, headers y body.
Cada valor se escribe para el sitio donde queda. En la URL va codificado
(Silva & Filhos llega como un solo valor). En un body JSON lleva comillas y
escapes: {"nome": ":nome"} sigue siendo válido aunque el nombre tenga
comillas o saltos de línea, y fuera de comillas ({"id": :id}) un texto
recibe las comillas que le faltan. Un valor al inicio de la URL (la base,
:base/clientes) va tal cual.
La petición espera hasta 60 segundos la respuesta; pasado ese tiempo el
paso falla con «El servicio … no respondió en 60 s». El campo timeoutMs de
la configuración del paso cambia este tiempo, hasta 120 segundos.
Paso Script
El paso Script ejecuta un script de la app — la misma lógica que puedes correr a mano o por programación, ahora como parte de una API:
- Elige el Script en la lista (la lista muestra el nombre y el lenguaje de cada uno; solo aparecen scripts activos). Sin scripts, el paso muestra el atajo para crear el primero.
- Decide si el paso Recibe el resultado del paso anterior — en el primer paso del pipeline este interruptor no se aplica.
El contrato con el script es claro: los argumentos de la API llegan en
input["args"], el resultado del paso anterior en input["prev"], y el
valor devuelto por la función main(input) sigue al paso siguiente (o es
la respuesta, si es el último paso).
Atención
Si el script elegido tiene un tiempo límite alto, el constructor avisa — los clientes de la API esperan ese tiempo en el peor caso. Los pipelines de respuesta interactiva merecen scripts rápidos.
Reordenar y quitar pasos
Cada tarjeta de paso tiene flechas para Mover arriba / Mover abajo y una papelera para Quitar paso. Cambiar el pipeline invalida el resultado de la última prueba — vuelve a Ejecutar para ver resultados frescos.
Probar sin guardar
La pestaña Probar tiene dos herramientas. La primera, Probar el pipeline (borrador), corre el pipeline TAL COMO ESTÁ en el constructor, sin guardar:
- Rellena los valores de prueba de los argumentos (en la sección Argumentos).
- Pulsa Ejecutar. En una mutation, el constructor pide confirmación — «¿Ejecutar la mutation ahora?» — porque la prueba corre de verdad contra los datasources y una mutation hace escrituras reales.
- Lee el resultado: el sello Éxito/Error con la duración, la
Respuesta completa (las respuestas muy grandes aparecen truncadas),
y con más de un paso, el Resultado por paso — cada paso con sello
ok/error, para ver exactamente dónde se rompió el pipeline. - Si los pasos escribieron logs (un script que imprime, por ejemplo), aparecen en el bloque Logs.

El return type
El return type es la forma de la respuesta en el schema GraphQL — es él el que dice a los clientes qué campos pueden seleccionar. El constructor lo infiere del resultado real: después de cada ejecución mira el bloque Return type (inferido). Si difiere del guardado, aparece el aviso «Este return type aún no está guardado» con el botón Guardar return type — y un punto ámbar en el botón Guardar te recuerda lo mismo.
Nota
Sin ninguna ejecución, la pestaña muestra el Return type actual (el guardado). Ejecuta el pipeline para inferir el return type del resultado real — especialmente después de cambiar el SQL o el script.
Experimentar como un cliente
La segunda herramienta de la pestaña Probar es un entorno GraphQL interactivo apuntado al endpoint de la app — escribes operaciones, tienes autocompletado del schema y ves las respuestas. Como estás autenticado, los borradores también aparecen. El botón Abrir en ventana abre el mismo entorno en una pestaña del navegador. Los detalles quedan en el capítulo siguiente, en La API GraphQL del modelo.
Publicar
El interruptor Publicada controla quién ve la API:
- Borrador — solo quien construye la ve (en las sesiones autenticadas, las operaciones aparecen marcadas como borrador). Los clientes externos y los usuarios de la app no la ven, ni por listado del schema.
- Publicada — entra en el schema para todos los clientes con acceso.
Para guardar como publicada, la API tiene que estar completa. El constructor muestra los bloqueos junto a la cabecera — por ejemplo «Paso 2: el SQL está vacío.» o, en una API de tabla, «Para guardar como publicada, elige la tabla y al menos una acción CRUD.» Estos avisos nunca impiden el Guardar en borrador: impiden solo la publicación.
Nota
Eliminar una API publicada quita la operación inmediatamente del schema — los clientes que la llamaban pasan a recibir error. La plataforma avisa antes: la eliminación es permanente.
La documentación generada (pestaña Docs)
La pestaña Docs responde a la pregunta «¿cómo llamo a esto desde fuera?». Se genera de la versión guardada — guarda la API primero — y muestra:
- El endpoint (
POST /api/graphql/gestao-clientes), con botón de copiar. - La nota de autenticación: el header
x-api-keyes obligatorio para clientes externos — las claves se generan en Claves API. En la pestaña Probar (sesión interna) no hace falta. - Una entrada por operación de la API con cuatro bloques listos para copiar: Query GraphQL, Variables, curl y JavaScript (fetch). En una API de tabla, aparecen todas las operaciones activas (get, count, add, update, delete).

¿Por qué no…?
- ¿Por qué no puedo publicar? Falta que el pipeline esté completo — lee los bloqueos junto a la cabecera: cada paso que falta se lista con el número y el motivo.
- ¿Por qué el Ejecutar me pide confirmación? La API es una mutation: la prueba hace escrituras reales. Confirma que estás apuntando a datos de prueba.
- ¿Por qué no veo mi API nueva en el entorno de prueba GraphQL? Guarda primero — el entorno responde sobre la versión guardada. Los borradores guardados aparecen (estás autenticado); para clientes externos, solo cuando publiques.
- ¿Por qué no puedo juntar un paso SQL a una API de Tabla? Una API Tabla no se combina con otros bloques — quita el bloque Tabla primero (o los pasos, en el sentido inverso).