Conectando con el backend…

Quick start

setup

Conectar tu app al backend en 30 segundos.

Variables de entorno

.env
NEXT_PUBLIC_API_URL=https://nomad-centinela-api.vercel.app

Smoke test

curl
curl -s https://nomad-centinela-api.vercel.app/api/health | jq

Endpoints disponibles

MethodPathDescripcion
GET/api/healthSalud del sistema
GET/api/institutionsLista de instituciones monitoreadas
GET/api/eventsEventos de exposicion
GET/api/events/:idDetalle de un evento
POST/api/citizen/checkVerificar si un hash esta expuesto
GET/api/playbooksLista de playbooks
GET/api/playbooks/search?q=Buscar playbooks (FTS)
GET/api/playbooks/:slugContenido de un playbook
POST/api/agent/triageEjecutar agente Triage
POST/api/agent/investigateEjecutar agente Investigator
POST/api/agent/pipelineTriage + Investigator + HITL en una llamada
POST/api/agent/chatChat ciudadano (respuesta diferida JSON)
POST/api/webhooks/make/ingestIngesta desde Make.com

API explorer

interactive

Ejecuta cada endpoint en tiempo real contra produccion.

GET/api/health

Verifica que Supabase, MiniMax y el webhook de Make estan operativos.

GET/api/institutions

Lista todas las instituciones que NOMAD monitorea con conteo de eventos.

GET/api/events

Lista eventos de exposicion. Filtra por status o severity.

GET/api/events/:id

Detalle completo de un evento: traces de agentes, reviews HITL, payload.

POST/api/citizen/check

Verifica si un prefijo de hash aparece en la base de datos de breach. Solo k-anonymity: nunca se expone el hash completo.

GET/api/playbooks/search

Busqueda en lenguaje natural sobre playbooks de respuesta. Usa pgvector FTS.

GET/api/playbooks/:slug

Contenido completo de un playbook en Markdown.

POST/api/agent/triage

Clasifica la severidad de un evento usando MiniMax. Si MiniMax falla, devuelve resultado mock.

POST/api/agent/investigate

Busca fuentes OSINT para verificar el evento. Usa MiniMax.

POST/api/agent/pipeline

Ejecuta Triage + Investigator + estado HITL en una sola llamada atomica.

POST/api/webhooks/make/ingest

Ingesta evento sintetico desde Make.com. El secret ya viene configurado.

Integration recipes

cookbook

Patrones reales para conectar frontend y mobile al backend.

Recipe A — Next.js Server Component

Datos en el servidor (RSC). Ideal para pages sin interactividad en tiempo real.

app/dashboard/page.tsx
// app/dashboard/page.tsx (Next.js 15 Server Component)
import { fetchEvents } from '@/lib/api';

export default async function DashboardPage() {
  const { data: events } = await fetchEvents({ status: 'pending_review' });

  return (
    <ul>
      {events.map((e) => (
        <li key={e.id}>
          <span className={severityColor(e.severity)}>{e.severity}</span>
          {' '}{e.title}
        </li>
      ))}
    </ul>
  );
}

Recipe B — Next.js Client Component

Interactividad. Ejecuta agentes, polling, streaming de chat.

components/AgentPanel.tsx
'use client';
import { useState } from 'react';
import { runTriage, runInvestigate } from '@/lib/api';

export function AgentPanel({ eventId }: { eventId: string }) {
  const [loading, setLoading] = useState(false);
  const [result, setResult] = useState<unknown>(null);

  async function handleTriage() {
    setLoading(true);
    try {
      const json = await runTriage(eventId);
      setResult(json.triage);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div>
      <button onClick={handleTriage} disabled={loading}>
        {loading ? 'Ejecutando…' : 'Ejecutar Triage'}
      </button>
      {result && <pre>{JSON.stringify(result, null, 2)}</pre>}
    </div>
  );
}

Recipe C — Flutter con http

Equivalente movil del fetch. Compatible with emulator (http://10.0.2.2:3001 for Android).

lib/services/nomad_api.dart
import 'dart:convert';
import 'package:http/http.dart' as http;

class NomadApi {
  static const apiBase = String.fromEnvironment(
    'API_BASE',
    defaultValue: 'https://nomad-centinela-api.vercel.app',
  );

  static Future<List<dynamic>> getEvents({String? status}) async {
    final qs = status != null ? '?status=$status' : '';
    final resp = await http.get(
      Uri.parse('$apiBase/api/events$qs'),
      headers: {'Content-Type': 'application/json'},
    );
    final json = jsonDecode(resp.body);
    return json['data'] as List<dynamic>;
  }

  static Future<Map<String, dynamic>> checkCitizen(String hashPrefix) async {
    final resp = await http.post(
      Uri.parse('$apiBase/api/citizen/check'),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'hash_prefix': hashPrefix}),
    );
    return jsonDecode(resp.body) as Map<String, dynamic>;
  }
}

Recipe D — SSE streaming (limitacion en Vercel)

POST /api/agent/chat soporta streaming SSE en desarrollo local. En Vercel (serverless), el stream se convierte a JSON por incompatibilidad del runtime. La UI del chat ya tiene fallback JSON que funciona indistintamente.

chat fallback (funciona en prod)
const res = await fetch(`${API_URL}/api/agent/chat`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ messages: [{ role: 'user', content: '¿Estoy expuesto?' }] }),
});
const { messages } = await res.json(); // JSON normal, no stream
const reply = messages[messages.length - 1].content;

Make.com scenarios

make

Los webhooks activos en tu cuenta. Puedes dispararlos manualmente o conectar fuentes OSINT.

NOMAD Centinela - Ingesta OSINT sintética

id 5087018

Trigger: webhook personalizado. Envía datos al backend via POST /api/webhooks/make/ingest.

https://hook.us2.make.com/vz2nrhdwcfdh64iz7igbbj0iirem4wx5

NOMAD Centinela - HITL email

id 5087019

Trigger: webhook personalizado. Envía email a z648s.7bt@gmail.com cuando el backend detecta pending_review.

https://hook.us2.make.com/1f2bkj72aiqxb4abellrbn3ulkwcbttv

FTS vs Vector — RAG semantico

rag

Dos modos de busqueda en playbooks: Full-Text Search (FTS) y busqueda vectorial (pgvector). Cambia el modo y observa la diferencia en los rankings.

Vector mode usa embeddings MiniMax (embo-01) + pgvector cosine distance. Requires: migracion 0003 aplicada + npm run embed:playbooks corrido. Sin embeddings, Vector cae automaticamente a FTS.
NOMAD Centinela · Track Def/Acc · hack@latam · 2026
API: https://nomad-centinela-api.vercel.app
NOMAD Centinela — Alerta temprana de credenciales para instituciones públicas LATAM