Public API v1 · no key needed
Ask whether a person really belongs to a project. Answers come from an ENSv2 team registry and signed attestations, and every “verified” carries a proof anyone can re-check. CORS is open, so browsers, extensions and other sites can call it directly. Limit: 60 requests per minute per client. Machine-readable spec: /api/v1/openapi.json (OpenAPI 3.1).
Give the numeric Telegram ID (the identity that is attested) and/or the @username and display name (used for lookalike detection).
curl "https://kakunin.xyz/api/v1/check?telegramId=100000001" # a lookalike of a real member curl "https://kakunin.xyz/api/v1/check?username=alice_kakunn"
{
"ok": true,
"api": "v1",
"checkedAt": "2026-09-27T01:02:03.000Z",
"result": {
"status": "verified",
"org": "kakunin-demo.eth",
"member": { "fqn": "alice.team.kakunin-demo.eth", "role": "Senior Engineer", "since": "2024-03-01" },
"attestation": { "valid": true, "signer": "0x9140…1044", "issuedAt": 1790425100, "version": 1 },
"proof": {
"chain": "sepolia",
"attesterName": "kakunin-demo.eth",
"recordKey": "attestations[org.telegram.id][kakunin-demo.eth]",
"envelope": "2GF0c3SD…",
"teamRegistry": "0x40C3…867f"
}
}
}| status | meaning |
|---|---|
| verified | Active subname, ID matches, attestation valid. Includes proof. |
| former | The subname was revoked. Includes revokedAt (from the ENSv2 event). |
| lookalike | No member match, but the handle or name imitates one (lookalikeOf, distance). |
| unknown | Not on the team. reason may be invalid-attestation, no-identifier or org-not-registered. |
Every non-verified answer also raises an impersonation alert for the org (dashboard feed and Telegram).
curl "https://kakunin.xyz/api/v1/org/kakunin-demo.eth"
Returns the members the org publishes (label, ENS name, role, status, dates) and the contract addresses. No Telegram IDs or usernames.
[](https://kakunin.xyz/v/alice)
A live SVG for a team member. Its profile page (/v/alice) shows the proof and the attested Telegram ID. A badge or a profile link only proves the member exists; to confirm the person you are talking to is them, compare their numeric Telegram ID.
The same check is sold per call at GET /api/paid/real for 0.001 USDC on Base Sepolia. It answers 402 Payment Required with the requirements; an x402 client pays and retries. A careful buyer screens the destination before signing:
import { x402Client } from '@x402/core/client'
import { ExactEvmScheme } from '@x402/evm/exact/client'
import { wrapFetchWithPayment } from '@x402/fetch'
const client = new x402Client()
client.register('eip155:*', new ExactEvmScheme(signer))
client.onBeforePaymentCreation(async ({ selectedRequirements: r }) => {
const risk = await screenWithIntercepta(r.payTo) // live risk API call
if (risk.level === 'high' || risk.level === 'critical')
return { abort: true, reason: risk.reasons.join('; ') } // refuse BEFORE signing
})
const res = await wrapFetchWithPayment(fetch, client)('https://kakunin.xyz/api/paid/real?telegramId=100000001')See it run, with one approved and one blocked payment, in the live demo. Source: agent.ts.
A “verified” answer is not a promise from Kakunin. Take the proof.envelope and check it against ENS. The signer must equal the address that the org’s ENS name currently resolves to (draft ENSIP “Text Record Attestations”).
import { decode, encode } from 'cborg'
import { hashMessage, hexToBytes, keccak256, recoverAddress, toHex } from 'viem'
const bytes = Uint8Array.from(Buffer.from(proof.envelope, 'base64')) // 0xda 61747374 (tag "atst") + CBOR
const [version, issuedAt, signature] = decode(bytes.subarray(5)) // [1, t, sig(65 bytes)]
const payload = encode({ n: proof.name, a: hexToBytes(proof.owner), k: 'org.telegram.id', v: telegramId, t: issuedAt })
const signer = await recoverAddress({ hash: hashMessage({ raw: keccak256(payload) }), signature: toHex(signature) })
// valid <=> signer === the address that "kakunin-demo.eth" resolves to (ENS addr record)@KakuninxyzBot: forward a suspicious message (or send an @username or numeric ID) and it answers with the same four verdicts. Members onboard through a one-time link from their org’s HR; org admins send /subscribe <secret> to receive impersonation alerts.