Gebouwd om je stack te passen
Eenvoudige REST met één header, een getypeerde Node-client, een MCP-server, ondertekende webhooks en eigen domeinen. Niets te installeren op je server, tenzij je dat wilt.
Vijf manieren om binnen te komen
Dezelfde gebeurtenis, vanuit een shell, je code, een assistent of een 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' })- Server-API Lees, zoek en verwijder events en bezoekers met één header.
- Server-SDK Getypeerde Node-client met webhookcontroles en openen van verzegelde resultaten.
- MCP-server De API van je project als tools voor een AI-assistent.
- Webhooks Elke nieuwe gebeurtenis wordt ondertekend naar je server gePOST, met nieuwe pogingen.
- Aangepast domein Serveer de agent vanaf een subdomein van jou met één DNS-record, zoals elke live site zou moeten.
- Verzegelde resultaten Een versleuteld resultaat dat uw server opent zonder de API aan te roepen.
De agent op elke pagina
Start het wanneer het formulier opent en vraag een request ID op zodra de gebruiker actie onderneemt. Het draait op de achtergrond en blokkeert de pagina nooit.
- Geen afhankelijkheden
- /agent.js als script-tag om het uit te proberen, of een kleine npm-loader die de huidige agent via je eigen domein ophaalt.
- Elk framework
- React, Svelte, Vue, Next.js, Nuxt, Angular of geen.
- Ongeveer een kilobyte
- Het rapport dat het verstuurt. Het leest nooit WebRTC-netwerkadressen.
- Gecachet
- Een resultaat kan voor de sessie worden bewaard, zodat een login en de checkout daarna maar één identificatie kosten.
<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>Jouw data, jouw regels
Gebouwd voor de dataverzoeken die je krijgt.
Gehost in de EU
Events worden opgeslagen in AWS eu-west-1 totdat je ze verwijdert, of gedurende 1, 3 of 5 jaar als je dat kiest.
Verwijder een external ID in één aanroep
Verwijder een external ID en alle bijbehorende events en apparaatkoppelingen verdwijnen. Handig bij een gegevensverzoek of gesloten account.
Niets voor de browser om op af te stemmen
Flags bereiken de browser nooit. In de zero trust-modus krijgt de browser alleen een request ID.
Je eerste identificatie, in enkele minuten
Een public key in de browser, een secret key op je server.