Docs
Logs

Send frontend logs

Frontend log ingestion is for log lines you want to explicitly emit from browser code: a caught exception, a validation warning, a custom application event. Uncaught exceptions and unhandled promise rejections are picked up automatically by the recorder script (Error Tracking) — you don't need to send those here.

Endpoint

POST https://api.nevision.app/public/logs/ingest
Content-Type: application/json

Frontend calls authenticate by Origin / Referer allowlist, not by API key — the domain you send from must match one of your site's authorized domains. Never put your server API key in browser code. Only warn and error levels are accepted on this endpoint; other levels are rejected server-side. Send debug/info/fatal from your backend instead.

Payload

{
  "siteId": "YOUR_SITE_ID",
  "entries": [
    {
      "level": "error",
      "message": "Checkout total mismatch",
      "fields": {
        "expected": 4200,
        "actual": 4199,
        "route": "/checkout"
      },
      "timestamp": "2026-04-27T12:34:56Z",
      "sessionId": "optional-session-id"
    }
  ]
}

level is required and must be warn or error. message is up to 64 KB. fields is an optional structured-context object — searchable in the dashboard. timestamp is ISO-8601 and optional (server fills it in if absent). Up to 500 entries per request.

Code examples

function logToNevision(level, message, fields) {
  return fetch("https://api.nevision.app/public/logs/ingest", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      siteId: "YOUR_SITE_ID",
      entries: [{
        level,           // "warn" or "error"
        message,
        fields,          // optional structured context
        timestamp: new Date().toISOString(),
      }],
    }),
    keepalive: true, // survive page navigation
  });
}

// usage
try {
  validateCart(cart);
} catch (err) {
  logToNevision("error", "Cart validation failed: " + err.message, {
    route: location.pathname,
    stack: err.stack,
  });
  throw err;
}

Response

{ "accepted": 1, "rejected": 0, "bytesIngested": 142 }

The endpoint always returns 200. If accepted is 0, the response includes an error field (Domain not authorized, Invalid site, Logs disabled, or limitReached: true).

Tips

  • Use keepalive: true so logs sent during page unload still ship.
  • Keep fields structured — search by JSON field is much faster than regex on message.
  • Need debug or info levels? Send those from your server using the backend logs endpoint. The browser path is intentionally limited to warn/error to bound bandwidth and PII exposure.