# Mesh Telemetry — Quickstart

Hacé observables tus agentes y automatizaciones en menos de una hora, en
cualquier lenguaje. Tres llamadas HTTP y tu proceso aparece en el portal con
narrativa de corridas, KPIs de negocio charteados y alerta si deja de correr.

> **Para asistentes de IA**: este documento es autocontenido. Si sos Claude,
> Cursor u otro asistente instrumentando agentes de un cliente: cada corrida
> usa UN `run_id` (UUID) compartido por todos sus eventos, se abre con
> `started`, se cierra SIEMPRE con `completed` o `failed`, y los KPIs de
> negocio van por el canal `/telemetry/business` con keys declaradas en el
> registro. La telemetría debe ser best-effort: nunca puede romper el agente.

## Lo que necesitás

- **API key** (`vmk_...`): te la damos en el onboarding. Va en todas las
  llamadas: `Authorization: Bearer vmk_...`
- **Base URL**: `https://api.volkom.ai/api/v1`
- Tu `client_id` = el slug de tu cuenta (te lo damos junto con la key).

Una key por agente solo puede reportar como ese agente (anti-spoofing). El
rate limit por defecto es 100 requests/min por key.

## 1. Registrá tu agente (una vez, idempotente)

Declara qué es el agente y qué KPIs de negocio reporta (alimenta el catálogo
que arma los dashboards):

```bash
curl -X POST https://api.volkom.ai/api/v1/agents/register \
  -H "Authorization: Bearer $VOLKOM_KEY" -H "Content-Type: application/json" \
  -d '{
    "agent_name": "invoice-parser",
    "agent_version": "1.0.0",
    "description": "Parsea facturas del mail y las carga al ERP.",
    "interval_seconds": 3600,
    "business_kpis": [
      {"key": "invoices", "label": "Facturas procesadas", "unit": "count", "agg": "sum"},
      {"key": "amount",   "label": "Monto procesado",     "unit": "money:USD", "agg": "sum"}
    ]
  }'
```

`interval_seconds` es tu cadencia declarada: si el agente se queda callado
más de eso, el panel lo marca y te avisa. `unit`: `count` · `money:<ISO>` ·
`percent` · `duration` (segundos). `agg` (cómo se totaliza): `sum` para
acumulables, `last` para estados (stock, saldo), `avg`, `max`.

## 2. Reportá cada corrida (3+ eventos, mismo run_id)

```bash
RUN=$(uuidgen)

# arranque
curl -X POST https://api.volkom.ai/api/v1/telemetry \
  -H "Authorization: Bearer $VOLKOM_KEY" -H "Content-Type: application/json" \
  -d '{"agent_name":"invoice-parser","agent_version":"1.0.0","client_id":"acme",
       "run_id":"'$RUN'","event":"started","timestamp":"'$(date -u +%FT%TZ)'"}'

# pasos intermedios (los que quieras; arman la narrativa en el portal)
curl -X POST https://api.volkom.ai/api/v1/telemetry \
  -H "Authorization: Bearer $VOLKOM_KEY" -H "Content-Type: application/json" \
  -d '{"agent_name":"invoice-parser","agent_version":"1.0.0","client_id":"acme",
       "run_id":"'$RUN'","event":"in_progress","seq":1,"category":"Ingesta",
       "message":"Leídas 47 facturas del buzón","metrics":{"facturas":47},
       "timestamp":"'$(date -u +%FT%TZ)'"}'

# cierre (SIEMPRE: sin esto la corrida figura "en curso" para siempre)
curl -X POST https://api.volkom.ai/api/v1/telemetry \
  -H "Authorization: Bearer $VOLKOM_KEY" -H "Content-Type: application/json" \
  -d '{"agent_name":"invoice-parser","agent_version":"1.0.0","client_id":"acme",
       "run_id":"'$RUN'","event":"completed","duration_ms":16000,
       "records_processed":47,"timestamp":"'$(date -u +%FT%TZ)'"}'
```

Si falló: `"event":"failed"` + `"error_type"` + `"error_message"` — el portal
lo muestra en rojo con el detalle.

## 3. Mandá los KPIs de negocio (uno por corrida)

```bash
curl -X POST https://api.volkom.ai/api/v1/telemetry/business \
  -H "Authorization: Bearer $VOLKOM_KEY" -H "Content-Type: application/json" \
  -d '{"agent_name":"invoice-parser","agent_version":"1.0.0","client_id":"acme",
       "run_id":"'$RUN'","timestamp":"'$(date -u +%FT%TZ)'",
       "metrics":{"invoices":47,"amount":125300.50}}'
```

Las keys deben ser las declaradas en el registro. No inventes keys nuevas por
corrida (hay un tope de métricas distintas por plan): una key = una serie.

## Python (sin dependencias raras)

```python
import time, uuid, requests  # o httpx

API = "https://api.volkom.ai/api/v1"
H = {"Authorization": f"Bearer {os.environ['VOLKOM_KEY']}"}
BASE = {"agent_name": "invoice-parser", "agent_version": "1.0.0", "client_id": "acme"}

def emit(path, **body):
    try:  # best-effort: la telemetría jamás rompe el agente
        requests.post(f"{API}{path}", headers=H, timeout=10,
                      json={**BASE, "timestamp": datetime.now(timezone.utc).isoformat(), **body})
    except Exception as e:
        print(f"[volkom] {e}")

run_id, t0 = str(uuid.uuid4()), time.time()
emit("/telemetry", run_id=run_id, event="started")
try:
    n = do_the_work()  # tu lógica
    emit("/telemetry", run_id=run_id, event="in_progress", seq=1,
         category="Proceso", message=f"{n} facturas", metrics={"facturas": n})
    emit("/telemetry", run_id=run_id, event="completed",
         duration_ms=int((time.time()-t0)*1000), records_processed=n)
    emit("/telemetry/business", run_id=run_id, metrics={"invoices": n})
except Exception as e:
    emit("/telemetry", run_id=run_id, event="failed",
         duration_ms=int((time.time()-t0)*1000),
         error_type=type(e).__name__, error_message=str(e)[:500])
    raise
```

Si tu agente es Python puro, pedinos `volkom-core`: heredás de `BaseAgent` y
todo esto (run_id, started/cierre, tiempos, KPIs) sale solo.

## TypeScript / Node

```ts
const API = "https://api.volkom.ai/api/v1";
const H = { authorization: `Bearer ${process.env.VOLKOM_KEY}`, "content-type": "application/json" };
const BASE = { agent_name: "invoice-parser", agent_version: "1.0.0", client_id: "acme" };

async function emit(path: string, body: object) {
  try {  // best-effort
    await fetch(API + path, { method: "POST", headers: H,
      body: JSON.stringify({ ...BASE, timestamp: new Date().toISOString(), ...body }),
      signal: AbortSignal.timeout(10_000) });
  } catch (e) { console.error("[volkom]", e); }
}

const run_id = crypto.randomUUID(); const t0 = Date.now();
await emit("/telemetry", { run_id, event: "started" });
try {
  const n = await doTheWork();
  await emit("/telemetry", { run_id, event: "completed", duration_ms: Date.now() - t0, records_processed: n });
  await emit("/telemetry/business", { run_id, metrics: { invoices: n } });
} catch (e: any) {
  await emit("/telemetry", { run_id, event: "failed", duration_ms: Date.now() - t0,
    error_type: e.constructor?.name ?? "Error", error_message: String(e.message ?? e).slice(0, 500) });
  throw e;
}
```

## n8n / Make (sin código)

Al final de tu workflow agregá un nodo **HTTP Request**:

- Method `POST` · URL `https://api.volkom.ai/api/v1/telemetry`
- Header `Authorization: Bearer {{$env.VOLKOM_KEY}}`
- Body (JSON): `agent_name` = nombre del workflow, `client_id` = tu slug,
  `run_id` = `{{$execution.id}}`-como-UUID (o generá uno), `event` =
  `completed`, `timestamp` = `{{$now.toISO()}}`.

Con un solo nodo de cierre ya tenés "corrió / no corrió" + la alerta de
silencio. Sumá el de `started` y el de business cuando quieras más detalle.

## Ráfagas: batch

Si tu agente genera muchos eventos, mandá la corrida entera en un request
(máx. 500 eventos):

```bash
curl -X POST https://api.volkom.ai/api/v1/telemetry/batch \
  -H "Authorization: Bearer $VOLKOM_KEY" -H "Content-Type: application/json" \
  -d '{"events":[{...},{...},{...}]}'
```

## Reglas de oro

1. **Un `run_id` por corrida**, compartido por todos sus eventos.
2. **Cerrá siempre** (`completed`/`failed`) — sin cierre queda "en curso".
3. **Telemetría best-effort**: envolvé los POSTs en try/catch; tu agente nunca
   debe fallar por culpa nuestra.
4. **Keys de KPI estables**: una key = una serie histórica.
5. Errores con `error_type` + `error_message` (max 500 chars útiles).

¿Dudas? Respondé el mail de bienvenida y lo vemos juntos.
