Proof-of-Human Verification API

Build with 5arz.

Verify a real human performed an action — a watch, a sign-up, a visit — and get a signed credential your app and your advertisers can verify. Three steps, one API call per event. Drop it into any app or dashboard.

1·2·3Quickstart

Sign up, buy credits, verify. Auth is a single Bearer key; verifications are prepaid.

# 1) Sign up → get your API key (shown once)
curl -X POST https://api.5arz.com/api/agents/register \
  -H "Content-Type: application/json" \
  -d '{"name":"Your Company","contactEmail":"you@company.com"}'

# 2) Buy credits → open the returned Stripe checkout
curl -X POST https://api.5arz.com/api/billing/checkout \
  -H "Authorization: Bearer arz_live_…" -d '{\"plan\":\"starter\"}'

# 3) Verify an event → a signed credential (1 credit)
curl -X POST https://api.5arz.com/api/agents/verify \
  -H "Authorization: Bearer arz_live_…" -d '{"sessionId":"…"}'
# → { "pohf_jwt": "eyJ…", "verified": true }

Get your API key

Self-serve, instant. Your key is shown once — store it. Start in Test mode: a free arz_test_ key with unlimited, uncharged verifications so you can integrate end-to-end before paying. Test credentials are signed but carry test:true — never treat them as production proof.

Two fields, no card. Pick Test for a free sandbox key, or Live for production credentials — both on the same account, so your key, billing and dashboard never drift apart.

Get your free API key →

Writing an autonomous agent that registers itself? Skip the browser and call POST /api/agents/register — see For AI agents.

The SDK zero dependencies

A thin JavaScript client for browsers and Node 18+. Import it directly, or copy the file into your project.

// import directly (browser ESM or bundler)
import { Sarz } from "https://5arz.com/sdk/sarz.js";

const sarz = new Sarz({ apiKey: "arz_live_…" });
const { pohf_jwt } = await sarz.verify(sessionId);        // 1 credit → signed credential

// physical presence (receipt / on-site)
const photoHash = await Sarz.hashPhoto(file);
const { lat, lng } = await Sarz.captureGeo();
await sarz.submitPhysical({ memberId, source:"receipt", lat, lng, photoHash });

// your advertisers verify it themselves — no key needed
const { valid, payload } = await Sarz.verifyCredential(pohf_jwt);

npm i @5arz/sdk · or hosted at 5arz.com/sdk/sarz.js.

API reference

Base URL https://api.5arz.com. Auth: Authorization: Bearer <apiKey> (all but register + jwks).

POST/api/agents/register
Sign up. Body { name, contactEmail, mode? } — pass mode:"test" for a free arz_test_ sandbox key. → { apiKey, agentId, mode }. No auth. Key shown once.
POST/api/billing/checkout
Subscribe { plan: "starter" | "growth" | "scale" }{ checkoutUrl } (Stripe). The plan activates on payment. Test keys skip this — unlimited free.
GET/api/agents/credits/balance
Remaining verifications → { balance, lifetimePurchased, lifetimeConsumed, packs }.
GET/api/agents/metrics
Verified-attention analytics — summary + per-view rows (focus, probe, input, gaze, quality, fraud flags), each tagged with its credential id. ?format=csv downloads; ?since=&limit= to page.
POST/api/agents/attest/challenge
Device attestation step 1 → one-time { nonce, challengeB64url } (anti-replay).
POST/api/agents/attest/verify
Step 2 — prove a genuine device, not an emulator. { method:"webauthn"|"play_integrity"|"app_attest", nonce, subjectRef }{ attested, assurance }. Attested devices add a device claim to the credential.
POST/api/track/event
Public beacon from the post-click tag — on-site behavior tied to the verified view (vt). Cookieless; sendBeacon-friendly.
POST/api/agents/track/conversion
Server-side (backend-confirmed) conversion tied to a verified view. { vt, name, value, currency }{ attributed }.
GET/api/agents/metrics/funnel
Verified views → landed → engaged → conversions, with rate + value. Every step provably from a verified human.
GET/api/agents/metrics/attribution
Multi-touch — credit conversions across the verified views that led to them. ?model=first|last|linear.
GET/api/agents/metrics/unique-humans
Cross-device dedup — the same person on phone + web + app counts once. Pass a stable uref on verify/track.
GET/api/tasks/next
Public — fetch a micro-task to embed in a pop-up. ?site=<agentId>{ task }.
POST/api/tasks/complete
Public — submit a completion (answer + attention). A verified completion mints a PoHF via /api/agents/verify.
POST/api/partner/points/convert
Convert a viewer's reward points → 5arz Stars. { userRef, points }{ balance }. Idempotent.
GET/api/partner/user/balance
A viewer's Star balance. ?userRef=…{ stars, lifetimeEarned }.
POST/api/partner/payout/request
Queue a cash-out (Stars → Wise). { userRef, stars }{ requestId, status }. Reviewed; no auto-transfer.
POST/api/agents/wallet/challenge
On-chain personhood — a nonce/message to personal_sign with an EVM wallet, then bind it via verify-personhood (adds a wallet claim).
POST/api/agents/webhooks
Register a push webhook. { url, events }{ id, signingSecret } (once). HMAC-signed (X-5arz-Signature); fires personhood.wallet_bound.
POST/api/agents/verify
Attest a verified human session. Body { sessionId }signed PoHF credential (1 credit). 402 if no credits.
POST/api/agents/verify-personhood
Prove a real, unique, live human. Body { memberId }signed Proof-of-Personhood credential (1 credit).
POST/api/kinetic/submit
Physical presence. Body { memberId, source:"receipt"|"geo_photo", lat, lng, photoHash } → scored session, mint a credential via /api/agents/verify. One-time-use per photo.
GET/.well-known/jwks.json
Public keys. Anyone validates a 5arz credential's ES256 signature against these — no 5arz software.

Verify a credential (the buyer side)

Every 5arz credential is an ES256 JWT. Your advertisers/partners verify it themselves with any standard JWT library, or our SDK:

import { Sarz } from "https://5arz.com/sdk/sarz.js";
const { valid, payload } = await Sarz.verifyCredential(pohf_jwt);
// valid === signature OK + iss is 5arz + not expired

Prefer no code? Paste any credential into the in-browser verifier.

Post-click tracking

Attach proof to your funnel: one tag adds a signed credential to each on-site action and conversion — so each one carries verifiable proof it came from a verified human. It augments your existing analytics; it doesn't replace them. Cookieless. Redirect verified click-throughs with ?sarz_vt=<attestationId>.

<!-- drop on the advertiser site -->
<script src="https://5arz.com/sdk/track.js" data-site="agt_your_id" async></script>

// fire a conversion anytime (value optional)
sarz("conversion", "purchase", { value: 49, currency: "USD" });

Auto-captures active (focused) time, scroll depth, clicks, and pointer-entropy (a bot-on-site signal). Backend conversion? Use server-side POST /api/agents/track/conversion. See the funnel at GET /api/agents/metrics/funnel.

In-break task widget

Turn idle moments — a video break, a loading screen — into verified human work. Drop the loader, then open a pop-up where the viewer completes a quick task and earns; a verified completion mints a signed PoHF a buyer can pay for.

<!-- on the partner page -->
<script src="https://5arz.com/sdk/task-widget.js" data-site="agt_your_id" async></script>

// during a 60-second break:
SarzTask.open({ vt: viewToken, member: viewerId, onComplete: function(r){ } });

Mint the credential from a verified completion: POST /api/agents/verify with { sessionId: completionId } → a signed PoHF (work_kind task).

Mobile & apps

Everything works on mobile web and inside native iOS / Android / React Native apps:

Verified-human wallet (on-chain / DeFi)

Bind a verified, unique human to a wallet so DeFi/RWA protocols can gate borrowers/depositors on real personhood (anti-sybil + compliance). Get a challenge, sign it with the wallet, mint a personhood credential carrying the wallet claim.

// 1) challenge
POST /api/agents/wallet/challenge  -> { nonce, message }
// 2) wallet.personal_sign(message) -> walletSig
// 3) bind
POST /api/agents/verify-personhood  { memberId, wallet, walletSig, walletNonce: nonce }
   -> pop_jwt with claims: wallet, wallet_proof:"eip191", unique_human, liveness

On-chain consumers read it via a 5arz attestation/registry — require(sarz.isVerifiedHuman(wallet)). Reference contract + EAS schema in our onchain/ kit.

Auth, credits & errors