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, verify. Auth is a single Bearer key; the Free plan includes 1,000 signed credentials a month, no card required, and paid plans raise the ceiling.

# 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) Optional: pick a paid plan → 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 (one seal against your plan)
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
Your plan and remaining allowance → { plan, sealsUsed, sealsRemaining, plans }.
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 (one seal). 402 with an upgrade object when the monthly allowance is used.
POST/api/agents/verify-personhood
Prove a real, ID-verified, live human. Body { memberId } → signed Proof-of-Personhood credential (one seal).
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, live human to a wallet so DeFi/RWA protocols can gate borrowers/depositors on real personhood (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", sybil_checked, 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