◉ DOCUMENTACIÓN TÉCNICA

Referencia de API

Conecta tu taller con herramientas externas usando la API REST de Nofacto, recibe notificaciones vía webhooks, embebe el cotizador en tu sitio web y configura nuestro servidor MCP para agentes de IA.

⚠Las integraciones (API, webhooks, widget, MCP) requieren plan Ultra. Ver planes →

01 · AUTENTICACIÓN

Autenticación

Todas las llamadas a la API se autentican con una API key en formato nk_live_…. La clave va en el header Authorization como token Bearer.

Cómo generar tu API key

Ve a Ajustes → Integraciones en tu panel de Nofacto. Haz clic en Crear API key, escribe una etiqueta descriptiva (por ejemplo: mi-integracion) y confirma. La clave completa se muestra una sola vez — guárdala en un lugar seguro porque no podrás verla de nuevo.

Header de autenticación

Authorization: Bearer nk_live_xxxxxxxxxxxxxxxxxxxx

Ejemplo con curl

curl https://nofacto.com/api/v1/workshop \
  -H "Authorization: Bearer nk_live_xxxxxxxxxxxxxxxxxxxx"
Seguridad: nunca expongas tu API key en el frontend de tu sitio web. Úsala solo desde un servidor o entorno seguro. Si sospechas que una clave fue comprometida, revócala desde Ajustes → Integraciones y genera una nueva.

02 · ENDPOINTS REST

Endpoints REST

Base URL: https://nofacto.com/api/v1
Todas las respuestas son JSON. Los errores siguen la forma {"error":"mensaje","code":"ERROR_CODE"}.

GET/workshop

Devuelve la configuración pública del taller: nombre, slug, país, moneda, idioma y plan activo.

curl https://nofacto.com/api/v1/workshop \
  -H "Authorization: Bearer nk_live_xxxx"

# Respuesta
{
  "id": "wshop_abc123",
  "name": "Taller Láser Bogotá",
  "slug": "taller-laser-bogota",
  "country": "CO",
  "currency": "COP",
  "plan": "multi"
}
GET/materials

Lista los materiales del catálogo del taller con su precio base, stock disponible y unidad de medida.

curl https://nofacto.com/api/v1/materials \
  -H "Authorization: Bearer nk_live_xxxx"

# Respuesta
[
  {
    "id": "mat_001",
    "name": "MDF 3mm",
    "pricePerSheet": 25000,
    "currency": "COP",
    "stockSheets": 12,
    "sheetWidthMm": 1220,
    "sheetHeightMm": 2440
  }
]
GET/machines

Lista las máquinas del taller con sus tarifas de corte (por minuto o por hora).

curl https://nofacto.com/api/v1/machines \
  -H "Authorization: Bearer nk_live_xxxx"

# Respuesta
[
  {
    "id": "mach_001",
    "name": "CO2 80W",
    "ratePerMinute": 1200,
    "currency": "COP"
  }
]
GET/catalog

Lista las piezas del catálogo del taller (solo las habilitadas) con sus renders y su modelo 3D, tal como los exporta Nofacto Studio. Es lo que una tienda externa usa para publicar una pieza sin volver a dibujar nada.

curl https://nofacto.com/api/v1/catalog   -H "Authorization: Bearer nk_live_xxxx"

# Respuesta
[
  {
    "id": "prod_001",
    "codigo": "N-001",
    "name": "Souvenir Restrepo",
    "categoria": "souvenirs",
    "imagenUrl": null,
    "renders": [
      { "url": "https://.../renders/N-001-frontal.jpg", "vista": "frontal", "w": 1600, "h": 1200 },
      { "url": "https://.../renders/N-001-tres-cuartos.jpg", "vista": "tres-cuartos", "w": 1600, "h": 1200 }
    ],
    "modelo3d": { "glb": "https://.../ar/N-001.glb", "usdz": "https://.../ar/N-001.usdz", "actualizadoEn": 1789660000000 },
    "dimensionsW": 90,
    "dimensionsH": 120,
    "suggestedPrice": 15000
  }
]
GET/models3d

Lista los modelos 3D que el taller compartió en realidad aumentada desde Nofacto Studio (los del enlace «ver en tu mesa»), aunque todavía no estén enlazados a una pieza del catálogo. Los más recientes primero.

curl https://nofacto.com/api/v1/models3d   -H "Authorization: Bearer nk_live_xxxx"

# Respuesta
[
  {
    "id": "mfz1abc-souvenir-restrepo",
    "nombre": "souvenir restrepo",
    "glb": "https://.../ar/mfz1abc-souvenir-restrepo.glb",
    "usdz": "https://.../ar/mfz1abc-souvenir-restrepo.usdz",
    "bytesGlb": 412000,
    "actualizadoEn": 1789660000000
  }
]
POST/quote

Calcula el precio estimado de un trabajo sin crear un pedido. Útil para mostrar precios en tiempo real.

Cuerpo de la solicitud

machineId string · requerido
materialId string · requerido
productSpec object · requerido — dimensiones y detalles del trabajo.
curl -X POST https://nofacto.com/api/v1/quote \
  -H "Authorization: Bearer nk_live_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "machineId": "mach_001",
    "materialId": "mat_001",
    "productSpec": {
      "widthMm": 200,
      "heightMm": 150,
      "quantity": 10,
      "cutMinutes": 3.5
    }
  }'

# Respuesta
{
  "subtotal": 85000,
  "currency": "COP",
  "breakdown": {
    "material": 35000,
    "machine": 42000,
    "overhead": 8000
  }
}
POST/orders

Crea un nuevo pedido (en estado borrador). El taller lo recibe en su panel para procesar.

curl -X POST https://nofacto.com/api/v1/orders \
  -H "Authorization: Bearer nk_live_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "name": "María García",
      "email": "[email protected]",
      "phone": "+573001234567"
    },
    "lines": [
      {
        "kind": "simple",
        "description": "Llaveros MDF 3mm",
        "quantity": 50,
        "pricePerUnit": 3500
      }
    ],
    "paymentMode": "cash"
  }'

# Respuesta
{
  "id": "ord_xyz789",
  "status": "quote",
  "total": 175000,
  "currency": "COP",
  "createdAt": "2026-07-02T10:00:00Z"
}

Pedido completo (tiendas en línea). Si tu tienda ya trae el trabajo hecho —el cliente personálizó su pieza y hay un archivo de corte listo— puedes mandarlo todo y el taller produce sin volver a dibujar nada. Todos estos campos son opcionales: si ya usabas la API, nada cambia.

curl -X POST https://nofacto.com/api/v1/orders \
  -H "Authorization: Bearer nk_live_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "TIENDA-A1B2C3",
    "customer": {
      "name": "Ana María Rincón",
      "phone": "+573107999230",
      "nit": "1.049.657.235"
    },
    "delivery": {
      "method": "national",
      "address": "Calle 20 # 12-45",
      "city": "Villavicencio",
      "cost": 21000
    },
    "notes": "La placa de Julián va empacada aparte, es sorpresa.",
    "lines": [
      {
        "description": "Placa de reconocimiento — MDF negro 90×60 mm",
        "referencia": "PLACA-MDF-90x60",
        "quantity": 2,
        "total": 37000,
        "pricePerUnit": 18500,
        "service": "grabado",
        "dimensionsW": 90,
        "dimensionsH": 60,
        "file": {
          "url": "https://tu-tienda.com/pedidos/A1B2C3/corte.svg",
          "name": "corte.svg",
          "type": "image/svg+xml",
          "sizeBytes": 4096
        },
        "svgString": "<svg …/>"
      }
    ]
  }'

# Respuesta (201; 200 si el externalId ya existía)
{
  "orderId": "aB3dE5fG7hJ9",
  "status": "pending",
  "total": 37000,
  "publicUrl": "https://nofacto.com/tu-taller/order/aB3dE5fG7hJ9/review",
  "customerId": "kL2mN4pQ6rS8"
}

externalId — el identificador del pedido en TU sistema. Con él, reintentar es seguro: si se te cae la red después de crear el pedido, vuelves a llamar con el mismo externalId y recibes el que ya existe (con 200 en vez de 201) en lugar de crear un duplicado. Sin esto, un tiempo de espera agotado deja al taller cortando dos veces lo mismo.

file — el archivo de corte, con su nombre y tipo. El taller lo abre directo. svgString deja ver el corte sin descargarlo (máximo 200.000 caracteres). service es corte, grabado, delineado o ambos, y las dimensiones van en mm.

delivery.method es pickup, local o national. Antes se asumía siempre que el cliente recogía en el taller. Las URLs de archivo deben ser http o https.

customer.nit — NIT o cédula del cliente, como lo escriba (con puntos, guion o dígito de verificación; máximo 32 caracteres). Si el cliente ya está en el Directorio del taller —por ese NIT o, si no, por su teléfono— el pedido queda enlazado a su ficha, lleva el nombre con el que el taller lo conoce y la respuesta trae su customerId. Si no está, el pedido se crea con los datos que mandaste y la respuesta no trae customerId: la API no crea ni modifica fichas, eso lo decide el taller.

lines[].referencia — la referencia interna del producto (p. ej. CAL-IMAN-2027, máximo 64 caracteres). El taller la ve en la línea, la encuentra con el buscador de pedidos y sale en la factura electrónica como código del ítem.

GET/orders

Lista los pedidos del taller. Parámetros opcionales: status (quote, pending, accepted, completed, cancelled), limit (máx 100, default 20), cursor (paginación).

GET/orders/:id

Devuelve el detalle completo de un pedido incluyendo líneas, cliente, historial de pagos y etapa del kanban.

PATCH/orders/:id

Actualiza campos del pedido. Campos actualizables: status, stageId, specs, deliveryDate.

curl -X PATCH https://nofacto.com/api/v1/orders/ord_xyz789 \
  -H "Authorization: Bearer nk_live_xxxx" \
  -H "Content-Type: application/json" \
  -d '{"status": "accepted", "specs": "Diseño aprobado por cliente"}'
POST/orders/:id/pay

Registra un pago contra el pedido. Usa el header Idempotency-Key para evitar pagos duplicados ante reintentos.

Headers

Idempotency-Key string · recomendado — UUID único por intento de pago. Si el servidor ya procesó esta clave, devuelve la respuesta original sin duplicar el cobro.
curl -X POST https://nofacto.com/api/v1/orders/ord_xyz789/pay \
  -H "Authorization: Bearer nk_live_xxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -d '{
    "amount": 87500,
    "reference": "TRANSF-2026-0702"
  }'

# Respuesta
{
  "paymentId": "pay_abc001",
  "amountPaid": 87500,
  "balance": 87500,
  "order": { "id": "ord_xyz789", "status": "pending" }
}

03 · WEBHOOKS

Webhooks

Los webhooks envían notificaciones HTTP POST a tu servidor cuando ocurren eventos en el taller. Registra tus endpoints en Ajustes → Integraciones.

Eventos disponibles

order.createdSe crea un nuevo pedido (por el cotizador público, API o dashboard).
order.status_changedEl estado del pedido cambia (quote → pending → accepted → completed).
order.paidSe registra un pago contra el pedido.

Payload de ejemplo

POST https://tu-servidor.com/webhook/nofacto
Content-Type: application/json
X-Nofacto-Signature: sha256=a3f8b2c1d4e5...

{
  "event": "order.status_changed",
  "workshopId": "wshop_abc123",
  "data": {
    "orderId": "ord_xyz789",
    "previousStatus": "quote",
    "currentStatus": "accepted",
    "updatedAt": "2026-07-02T10:05:00Z"
  }
}

Verificar la firma HMAC

Cada llamada incluye el header X-Nofacto-Signature con un HMAC-SHA256 del cuerpo firmado con tu webhook secret (visible en Ajustes → Integraciones al crear el endpoint). Verifica la firma antes de procesar el evento para descartar llamadas fraudulentas.

// Node.js — verificación de firma
const crypto = require('crypto');

function verifySignature(rawBody, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// En tu handler Express:
app.post('/webhook/nofacto', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-nofacto-signature'];
  if (!verifySignature(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Firma inválida');
  }
  const payload = JSON.parse(req.body);
  // Procesar payload.event ...
  res.sendStatus(200);
});
Reintentos: si tu endpoint devuelve un código distinto de 2xx, Nofacto reintenta la entrega hasta 3 veces con backoff (0 s, 1 s, 4 s).

04 · WIDGET EMBEBIBLE

Widget embebible

El widget de Nofacto te permite incrustar el cotizador de tu taller directamente en tu sitio web con una sola línea de código. El cliente final cotiza y hace su pedido sin salir de tu página.

Snippet de instalación

<script
  async
  src="https://nofacto.com/embed.js"
  data-slug="tu-slug-de-taller"
  data-accent="#FF4A1C"
  data-layout="stepper"
  data-hide="location"
  data-lang="es"
></script>

Atributos disponibles

data-slugrequerido
El slug único de tu taller en Nofacto (ej. "taller-laser-bogota").
data-accent
Color de acento en formato hex. Por defecto usa el color del taller.
data-layout
"vertical" (por defecto), "compact" o "stepper". Controla el layout visual del cotizador embebido.
data-hide
Campos a ocultar, separados por coma. Valores posibles: location, phone.
data-lang
Idioma del widget: es, en, pt, fr. Por defecto detecta el idioma del taller.

Ejemplo en una página HTML

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <title>Mi Taller</title>
</head>
<body>
  <h1>¿Cuánto cuesta tu proyecto?</h1>

  <!-- El botón "Cotizar ahora" aparece aquí automáticamente -->
  <script
    async
    src="https://nofacto.com/embed.js"
    data-slug="mi-taller-laser"
    data-accent="#2D3748"
  ></script>
</body>
</html>

El widget es responsive y funciona en móvil. No requiere configuración adicional — el script detecta el slug y carga la configuración del taller desde los servidores de Nofacto.


05 · SERVIDOR MCP

Servidor MCP

Nofacto expone un servidor Model Context Protocol (MCP) que puedes conectar a tu agente o cliente de IA (Claude, Cursor, Copilot Chat, etc.) para que interactúe directamente con tu taller.

Configuración

URL del servidorhttps://nofacto.com/mcp
TransporteHTTP with SSE (Streamable HTTP)
AutenticaciónHeader: Authorization: Bearer <api-key>

Configuración en claude_desktop_config.json

{
  "mcpServers": {
    "nofacto": {
      "url": "https://nofacto.com/mcp",
      "headers": {
        "Authorization": "Bearer nk_live_xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Tools disponibles

get_workshop_configDevuelve la configuración del taller (nombre, slug, plan, moneda).
list_materialsLista los materiales disponibles con stock y precio por plancha.
list_machinesLista las máquinas con sus tarifas de corte.
compute_priceCalcula el precio de un trabajo dado machine, material y especificaciones.
create_orderCrea un nuevo pedido con las líneas indicadas y datos del cliente.
list_ordersLista los pedidos con filtros opcionales por estado y fecha.
get_embed_snippetGenera el snippet HTML del widget listo para copiar a cualquier página.
get_integration_guideDevuelve una guía paso a paso para integrar Nofacto en un proyecto específico.

Ejemplo de uso con Claude

Una vez configurado el servidor MCP, puedes hablar con tu taller en lenguaje natural:

TÚ
¿Cuánto costaría cortar 200 llaveros en MDF 3mm de 5×5 cm?
CLAUDE
Usando la herramienta compute_price con tu configuración de Nofacto... El costo estimado es $87.000 COP (material: $35.000, máquina: $42.000, overhead: $10.000). ¿Quieres que cree el pedido?
TÚ
Sí, créalo para el cliente Juan Pérez, teléfono 3001234567.
CLAUDE
Pedido creado. ID: ord_xyz789. El taller lo recibirá en su panel.
¿Listo para integrar tu taller?
Crea tu cuenta gratis, configura tu taller y activa las integraciones desde el plan Ultra.