Подходит для вашего стека
Простой REST с одним заголовком, типизированный Node-клиент, MCP-сервер, подписанные webhook и собственные домены. Ничего не нужно устанавливать на сервер, если вы сами не захотите.
Пять способов начать
Одно и то же событие, из шелла, вашего кода, ассистента или 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 Читайте, ищите и удаляйте события и посетителей одним header.
- Серверный SDK Типизированный Node-клиент с проверкой webhook и открытием защищённых результатов.
- MCP-сервер API вашего проекта как инструменты для ИИ-ассистента.
- Webhooks Каждое новое событие отправляется POST-запросом на ваш сервер, подписывается и повторяется при сбоях.
- Свой домен Раздавайте агент с вашего поддомена одной DNS-записью, как и должен делать любой работающий сайт.
- Запечатанные результаты Зашифрованный результат, который ваш сервер открывает без вызова API.
Агент на любой странице
Запускайте при открытии формы и запрашивайте request ID после действия пользователя. Работает в фоне и никогда не блокирует страницу.
- Без зависимостей
- /agent.js как тег script для быстрого теста или небольшой npm-загрузчик, который получает актуальный агент через ваш домен.
- Любой фреймворк
- React, Svelte, Vue, Next.js, Nuxt, Angular или ничего.
- Около килобайта
- Отчёт, который он отправляет. Он никогда не читает сетевые адреса WebRTC.
- Из кэша
- Результат можно сохранить на время сессии, поэтому вход и последующая оплата требуют только одной идентификации.
<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>Ваши данные, ваши правила
Создано для запросов данных, с которыми вы столкнетесь.
Размещено в ЕС
События хранятся в AWS eu-west-1, пока вы их не удалите, или 1, 3 или 5 лет, если вы выберете этот вариант.
Удалите external ID одним вызовом
Удаление внешнего ID удаляет все его события и связи с устройствами, например для запроса данных или закрытого аккаунта.
Нет данных, по которым браузер может настроиться
Флаги никогда не попадают в браузер. В режиме zero trust браузер получает только request ID.
Ваша первая идентификация за несколько минут
Публичный ключ в браузере, секретный ключ на вашем сервере.