Diseñado para encajar con tu stack
REST sencillo con un solo header, un cliente Node tipado, un servidor MCP, webhooks firmados y dominios personalizados. Nada que instalar en tu servidor, salvo que lo quieras.
Cinco formas de empezar
El mismo evento, desde una shell, tu código, un asistente o un push.
curl "https://api.zeno.id/events/1792578564800.yU4Ety" \
-H "Auth-API-Key: sk_..."const event = await fetch(`https://api.zeno.id/events/${requestId}`, {
headers: { 'Auth-API-Key': process.env.FP_SECRET_KEY },
}).then(response => response.json())import { createClient } from '@zeno-id/server'
const fingerprint = createClient({ secretKey: process.env.FP_SECRET_KEY, endpoint: 'https://api.zeno.id' })
const event = await fingerprint.getEvent(requestId)
const page = await fingerprint.searchEvents({ externalId: user.id, signal: 'vpn' })
await fingerprint.updateEvent(requestId, { action: 'checkout' })
await fingerprint.forgetExternalId(user.id)# Your project's API as tools for Claude Code, Cursor or any MCP client.
claude mcp add zeno --env FP_SECRET_KEY=sk_... --env FP_ENDPOINT=https://api.zeno.id -- npx -y @zeno-id/mcpimport { verifyWebhook } from '@zeno-id/server'
app.post('/fingerprint', express.text({ type: 'application/json' }), (request, response) => {
if (!verifyWebhook(request.body, request.header('fingerprint-signature') ?? '', process.env.FP_WEBHOOK_SECRET)) {
return response.sendStatus(401)
}
const event = JSON.parse(request.body)
response.sendStatus(200)
})// Serve the agent and identify from a subdomain of your own site, so content
// blockers that list ours don't drop identifications. Add it in Settings ›
// Custom domain, create the one DNS record it shows, then:
import { start } from 'zeno-id'
const agent = start({ publicKey: 'pk_...', endpoint: 'https://metrics.example.com' })- API de servidor Lee, busca y elimina eventos y visitantes con un solo header.
- SDK de servidor Cliente Node tipado con verificación de webhooks y apertura de resultados sellados.
- Servidor MCP La API de tu proyecto como herramientas para un asistente de IA.
- Webhooks Cada evento nuevo enviado por POST a tu servidor, firmado, con reintentos.
- Dominio personalizado Sirva el agente desde un subdominio suyo con un solo registro DNS, como debe hacer todo sitio en producción.
- Resultados sellados Un resultado cifrado que tu servidor abre sin llamar a la API.
El agente en cualquier página
Inícialo al abrir el formulario y solicita un request ID cuando el usuario actúe. Se ejecuta en segundo plano y nunca bloquea la página.
- Sin dependencias
- /agent.js como etiqueta script para probarlo, o un pequeño cargador npm que obtiene el agente actual a través de tu propio dominio.
- Cualquier framework
- React, Svelte, Vue, Next.js, Nuxt, Angular o ninguno.
- Aproximadamente un kilobyte
- El informe que envía. Nunca lee las direcciones de red de WebRTC.
- En caché
- Un resultado puede guardarse para la sesión, así el inicio de sesión y el pago posterior cuestan una sola identificación.
<script src="https://zenocdn.net/agent.js"></script>
<script>
const agent = FingerprintAgent.start({ endpoint: 'https://zenocdn.net', publicKey: 'pk_...' })
// Once the user logs in, hand the request ID to your server:
agent.get({ externalId: user.id }).then(({ requestId }) => verifyOnServer(requestId))
</script>Tus datos, tus reglas
Diseñado para las solicitudes de datos que recibirás.
Alojado en la UE
Los eventos se almacenan en AWS eu-west-1 hasta que los elimines, o durante 1, 3 o 5 años si lo eliges.
Borra un external ID en una sola llamada
Elimina un ID externo y todos sus eventos y vínculos de dispositivo desaparecen, por una solicitud de datos o una cuenta cerrada.
Nada con lo que el navegador pueda ajustarse
Los flags nunca llegan al navegador. El modo zero trust va más allá: el navegador solo recibe un request ID.
Tu primera identificación, en minutos
Una public key en el navegador, una secret key en tu servidor.