En esta página

Referencia API

Platform API v1

La API pública para sitios de código publicados. Las llamadas usan llaves publicables y rutas same-origin /api/v1/*.

Volver a docs

Cómo obtener una llave

Los sitios publicados y en vista previa reciben claves internas automáticamente. Para conectar otra integración, abre Configuración → Desarrolladores → Administrar credenciales en el negocio.

Crea una clave con nombre y los permisos que necesita la integración. Cópiala antes de cerrar el diálogo de creación; la lista no vuelve a mostrarla.

  1. Abre Configuración → Desarrolladores

    Elige el negocio dueño del sitio y abre Configuración → Desarrolladores → Administrar credenciales. Debes ser propietario o administrador de esa organización, con membresía para toda la organización. Un rol en otra organización o acceso limitado a negocios seleccionados no habilita esta pantalla.

  2. Crear clave API

    En Claves de la API, elige Crear clave API. Escribe un Nombre (1–60 caracteres) y selecciona al menos una opción en Permisos. Crea una clave por integración y selecciona solo lo que necesita.

  3. Copia una vez y cierra

    En Clave API creada, elige Copiar credencial, guárdala de forma segura y pulsa Listo. Cerrar el diálogo borra el valor mostrado. Nimlio guarda solo un hash de las claves que creas aquí; no puedes volver a revelar la clave.

  4. Revisa y revoca

    La lista muestra nombre, prefijo, permisos, estado, último uso y creación. Elige Revocar y confirma para detener el acceso de inmediato. Para cambiar permisos o reemplazar una clave perdida, crea otra y revoca la anterior.

Configuración de Desarrolladores con Claves de la API y Conectar un agente de IA.
Desarrolladores reúne las claves de integraciones y las conexiones MCP del sitio.
Requisitos de sitio y plan

Primero crea un sitio web. Crear claves API requiere Pro o Enterprise; Starter muestra un diálogo para mejorar el plan que abre la facturación de la organización del sitio. Puedes seguir listando y revocando tus claves después de bajar de plan. Las conexiones MCP también requieren modo código.

Permisos API disponibles: content:read, catalog:read, booking:read, booking:write, leads:write, orders:write, events:write. Las claves de autoservicio empiezan por nk_pub_; solo las publicables autentican /api/v1.

Administrada por Nimlio

Nimlio crea automáticamente claves internas para previsualizar y publicar el sitio. Las filas marcadas Administrada por Nimlio no tienen acción Revocar. El servidor entrega el booleano managed; el nombre de una clave por sí solo no la convierte en administrada. Las claves de autoservicio siguen siendo revocables aunque su nombre se parezca al de una interna. El aprovisionamiento interno conserva el material que necesita para el sitio; el autoservicio no lo conserva.

Para scripts, usa tu sesión iniciada con los endpoints de gestión de abajo. Crear acepta solo name y scopes opcional (un arreglo no vacío); omitir scopes concede los siete, así que defínelos explícitamente. Devuelve 201, con data.key solo en esa respuesta. Listar devuelve un arreglo de metadatos en data, incluido managed, nunca la clave ni su hash. Revocar devuelve 200; intentar revocar una clave administrada devuelve 409 conflict, con motivo managed_api_key. Crear, revocar y reactivar una clave suspendida se auditan junto con la mutación. La suspensión es un estado del servidor; Desarrolladores permite crear, listar y revocar.

Gestión de claves autenticada por sesión
curl -X POST "https://<your-nimlio-host>/api/sites/<site-id>/api-keys" \
-b "<session cookie>" \
-H "Origin: https://<your-nimlio-host>" \
-H "Content-Type: application/json" \
-d '{"name":"Catalog integration","scopes":["catalog:read"]}'

curl "https://<your-nimlio-host>/api/sites/<site-id>/api-keys" \
-b "<session cookie>"

curl -X DELETE "https://<your-nimlio-host>/api/sites/<site-id>/api-keys/<key-id>" \
-b "<session cookie>" \
-H "Origin: https://<your-nimlio-host>"

Límites de uso y cuota diaria

Los límites se aplican por llave y dirección IP cada minuto. Al superarlos recibes 429 rate_limited, salvo en POST /api/v1/events: los eventos en exceso se descartan en silencio y la respuesta sigue siendo 204.

  • Lecturas: 120 por minuto.
  • Horarios, estado de pedidos y eventos: 60 por minuto.
  • Cotizaciones y carritos: 30 por minuto.
  • Escrituras de reservas y pedidos: 10 por minuto.
  • Leads y newsletter: 5 por minuto.
  • Subida de fotos y comprobantes: 3 por minuto.

Además, las suscripciones al newsletter se limitan a 100 por negocio por hora y las escrituras de carritos a 2.000 por negocio por hora.

Cada llave también tiene una cuota diaria, de 50.000 solicitudes por defecto (puede variar según el plan o el despliegue). Los días se cuentan en la zona horaria America/Bogota.

Recetas

Ejemplos para copiar y pegar en las tareas de integración más comunes. Usan la llave de ejemplo nk_pub_xxxxxxxx y el origen de tu propio sitio; reemplaza ambos por tus valores.

Autentícate con una llave publicable

Envía la llave en UNO de los dos headers: Authorization con valor Bearer, o X-Nimlio-Key. Si envías ambos con valores distintos, la solicitud se rechaza con 401 invalid_api_key, y sin llave la respuesta es 401 missing_api_key. Las llaves secretas que empiezan por nk_sec_ no se aceptan en /api/v1. Una llave suspendida responde 403 api_key_suspended, y un sitio protegido con contraseña responde 403 site_locked en las lecturas de visitantes. Las llaves publicables son seguras para código del navegador: solo leen datos publicados y escriben registros originados por visitantes.

curl https://your-site.example/api/v1/site \
-H "Authorization: Bearer nk_pub_xxxxxxxx"

# equivalent header form
curl https://your-site.example/api/v1/site \
-H "X-Nimlio-Key: nk_pub_xxxxxxxx"

Scopes: uno por endpoint

Cada endpoint de la referencia declara exactamente un scope, que se muestra como una etiqueta, y tu llave debe tener ese mismo valor. Los scopes son content:read, catalog:read, booking:read, booking:write, leads:write, orders:write y events:write. Si a la llave le falta el scope requerido, recibes la respuesta 403 de abajo.

curl https://your-site.example/api/v1/products \
-H "Authorization: Bearer nk_pub_xxxxxxxx"
{
"ok": false,
"error": {
"code": "forbidden",
"reason": "missing_scope",
"message": "API key is missing the required scope"
}
}

Usa el filtro de la referencia para ver todos los endpoints que habilita un scope; por ejemplo, escribe orders:write.

Pagina las listas del catálogo

Las listas del catálogo aceptan limit (por defecto 50, máximo 100) y además offset o el cursor del meta.nextCursor anterior. Si envías ambos, gana offset, y un cursor mal formado responde 400 invalid_cursor. Nunca interpretes un cursor: devuélvelo tal cual.

const headers = { Authorization: "Bearer nk_pub_xxxxxxxx" };
const base = "https://your-site.example/api/v1";

async function allProducts() {
const items = [];
let cursor = null;
do {
const url = new URL(`${base}/products`);
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, { headers });
const body = await res.json();
if (!body.ok) throw new Error(body.error.code);
items.push(...body.data);
cursor = body.meta.hasMore ? body.meta.nextCursor : null;
} while (cursor);
return items;
}
{ "ok": true, "data": [], "meta": { "nextCursor": "100", "hasMore": true, "limit": 100 } }

Los items del CMS son distintos: ese endpoint usa limit (por defecto 25, máximo 100) y un cursor opaco, y devuelve data.items, data.nextCursor y data.hasMore en lugar de un meta de primer nivel.

Maneja el sobre de error

El éxito siempre es ok true con data, y las listas agregan meta. El fallo siempre es ok false con un objeto error que trae code, message y, opcionalmente, reason, fieldErrors, values, details y requestId. El code es un vocabulario pequeño y estable: invalid_input 400, unauthenticated 401, forbidden 403, not_found 404, conflict 409, limit_reached 409 o 402, payload_too_large 413, unsupported_media 415, rate_limited 429, unavailable 503, internal 500. El reason da la causa específica, como missing_scope o invalid_cursor.

async function nimlioFetch(path, init = {}) {
const res = await fetch(`https://your-site.example/api/v1${path}`, {
...init,
headers: { Authorization: "Bearer nk_pub_xxxxxxxx", "Content-Type": "application/json", ...init.headers },
});
if (res.status === 204) return null; // e.g. POST /events has no body
const body = await res.json();
if (body.ok) return body.data;
const { code, reason, message, fieldErrors, requestId } = body.error;
switch (code) {
case "invalid_input": // 400 — fieldErrors maps field -> message
throw new Error(`Fix the form: ${JSON.stringify(fieldErrors)}`);
case "unauthenticated": // 401 — reason: missing_api_key | invalid_api_key
case "forbidden": // 403 — reason: missing_scope | api_key_suspended | site_locked
throw new Error(`Key problem (${reason})`);
case "not_found": // 404
return null;
case "rate_limited": // 429 — back off and retry
await new Promise((r) => setTimeout(r, 1000));
return nimlioFetch(path, init);
default: // conflict 409, limit_reached 409/402, internal 500, ...
throw new Error(`${code}: ${message} (request ${requestId ?? "n/a"})`);
}
}

Cita el requestId cuando escribas a soporte. Los beacons de analítica (POST /api/v1/events) pueden responder 204 sin cuerpo.

Cotiza un pedido: los precios los define el servidor

El cuerpo de la cotización está cerrado a selecciones: items, ubicación del cliente, códigos de descuento o de tarjeta de regalo, y la tarifa de envío. Cualquier campo price, total, discount, currency o businessId se rechaza con 400 client_order_fields_not_allowed. Los montos de la respuesta están en centavos de COP.

curl -X POST https://your-site.example/api/v1/orders/quote \
-H "Authorization: Bearer nk_pub_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"items":[{"id":"<product-id>","type":"product","quantity":2}],"customerCity":"Bogotá","discountCode":"BIENVENIDO"}'

Referencia

44 de 44 endpoints

Reservas

Disponibilidad, citas, depósitos y tokens para gestionar reservas.

POST/api/v1/booking/appointmentsllave publicable

Crear una cita de reserva

booking:write
GET/api/v1/booking/contextllave publicable

Contexto de reservas

booking:read
POST/api/v1/booking/deposit-checkoutllave publicable

Crear checkout de depósito de reserva

booking:write
GET/api/v1/booking/manage/{token}llave publicable

Cargar reserva por token de gestión

booking:read
POST/api/v1/booking/manage/{token}llave publicable

Gestionar reserva por token

booking:write
POST/api/v1/booking/manage/{token}/cancelllave publicable

Cancelar reserva por token

booking:write
POST/api/v1/booking/manage/{token}/reschedulellave publicable

Reprogramar reserva por token

booking:write
GET/api/v1/booking/slotsllave publicable

Horarios de reserva recalculados por el servidor

booking:read

Comercio

Pedidos de tienda y consulta de estado de pedidos.

GET/api/v1/carts/{token}llave publicable

Restore a cart snapshot

orders:write
PUT/api/v1/carts/{token}llave publicable

Save a cart snapshot (restore + abandoned-cart capture)

orders:write
POST/api/v1/ordersllave publicable

Crear checkout de pedido de tienda

orders:write
POST/api/v1/orders/{orderId}/payment-proofllave publicable

Upload the payment proof of a pending transfer order

orders:write
POST/api/v1/orders/{orderId}/resumellave publicable

Regenerate the checkout URL for a pending online order

orders:write
GET/api/v1/orders/{orderId}/statusllave publicable

Consultar estado de pedido de tienda

orders:write
POST/api/v1/orders/quotellave publicable

Quote a storefront order

orders:write
POST/api/v1/reference-photosllave publicable

Upload a reference photo for a product that accepts one

orders:write

Catálogo

Servicios, productos, personal, galerías y propiedades publicadas.

GET/api/v1/catalogllave publicable

Agregado del catálogo publicado

catalog:read
GET/api/v1/productsllave publicable

Productos publicados

catalog:read
GET/api/v1/products/{id}llave publicable

Detalle de producto publicado

catalog:read
GET/api/v1/products/{id}/reviewsllave publicable

Approved reviews of a product

catalog:read
GET/api/v1/propertiesllave publicable

Propiedades publicadas

catalog:read
GET/api/v1/properties/{id}llave publicable

Detalle de propiedad publicada

catalog:read
GET/api/v1/servicesllave publicable

Servicios publicados

catalog:read
GET/api/v1/services/{id}llave publicable

Detalle de servicio publicado

catalog:read
GET/api/v1/staffllave publicable

Personal publicado

catalog:read
GET/api/v1/staff/{id}llave publicable

Detalle de personal publicado

catalog:read

CMS

Colecciones personalizadas y registros de contenido publicados.

GET/api/v1/cms/collectionsllave publicable

Colecciones CMS publicadas

content:read
GET/api/v1/cms/collections/{slug}/itemsllave publicable

Elementos publicados de colección CMS

content:read
GET/api/v1/cms/items/{slug}llave publicable

Elemento CMS publicado

content:read

Estado y contrato

Salud y contratos OpenAPI públicos.

GET/api/v1/collectionsllave publicable

Published collections

content:read
GET/api/v1/collections/{handle}llave publicable

Published collection

content:read
GET/api/v1/collections/{handle}/productsllave publicable

Published products of a collection

content:read
GET/api/v1/healthsin auth

Salud de la Platform API

Sin llave
GET/api/v1/openapi.jsonsin auth

Contrato OpenAPI 3.1 de la Platform API

Sin llave
GET/api/v1/sitellave publicable

Estructura del sitio publicado

content:read

Interacción

Prospectos, formularios y eventos de analítica.

POST/api/v1/eventsllave publicable

Evento de analítica

events:write
POST/api/v1/forms/{formId}/submissionsllave publicable

Enviar un formulario genérico

leads:write
POST/api/v1/leadsllave publicable

Crear un prospecto

leads:write
POST/api/v1/newsletter/subscribellave publicable

Subscribe a contact to the newsletter (marketing consent)

leads:write
POST/api/v1/restock/subscriptionsllave publicable

Request a back-in-stock alert (single-purpose consent)

leads:write

Todas las respuestas usan el envelope { ok, data | error }, excepto eventos analíticos que pueden responder 204.