npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agentvisa/verify

v0.1.1

Published

AgentVisa verifier — verify human-authorized AI agents in one call. Supports Web Bot Auth (RFC 9421) via AgentVisa-Assertion header.

Readme

@agentvisa/verify

Verify human-authorized AI agents in one call. Drop into any Node.js backend — Express, Fastify, Next.js, or plain fetch. Supports Web Bot Auth (RFC 9421) via the AgentVisa-Assertion header.

npm install @agentvisa/verify

Which package should I use?

  • @agentvisa/verify (this package) — use when you want to verify a token and get a clean result. Simple valid / reason response, onFail: 'reject' | 'flag', works with any framework. No redirect behavior.
  • @agentvisa/widget — use when you want the viral redirect loop: unverified AI agents are sent to AgentVisa to sign up, then return verified. Built-in agent detection so browsers and bots get a plain 401. Express and Next.js.

The two-layer model

Cloudflare's Web Bot Auth tells you which company's agent is making a request — operator identity, cryptographically signed. It stops there by design. AgentVisa adds the missing half:

Layer 1 — Web Bot Auth (Cloudflare)
  "This request is from Acme Corp's agent — verified."

Layer 2 — AgentVisa (this library)
  "A real human (Face ID, just now) authorized that agent to act."

When both are present, the AgentVisa-Assertion token is covered by the RFC 9421 signature — operator identity and human authorization cryptographically bound in one request.


Quick start

Get your widgetId and apiKey from your AgentVisa dashboard.

Express middleware

import express from 'express';
import { agentVisa } from '@agentvisa/verify';

const app = express();

// Reject any request without a valid AgentVisa token
app.use('/api', agentVisa({
  widgetId: process.env.AGENTVISA_WIDGET_ID!,
  apiKey:   process.env.AGENTVISA_API_KEY!,
}));

app.post('/api/checkout', (req, res) => {
  // req.agentVisa is populated — token is valid
  res.json({ ok: true });
});

Flag mode (decide in your handler)

app.use(agentVisa({
  widgetId: process.env.AGENTVISA_WIDGET_ID!,
  apiKey:   process.env.AGENTVISA_API_KEY!,
  onFail: 'flag',   // don't auto-reject — let the handler decide
}));

app.post('/api/order', (req, res) => {
  if (!req.agentVisa?.valid) {
    // Downgrade: show a CAPTCHA, require extra confirmation, etc.
    return res.status(401).json({ error: 'human_required' });
  }
  // Full trust path
  res.json({ ok: true });
});

Standalone (any framework)

import { extractToken, verify } from '@agentvisa/verify';

// Works with any framework — Next.js, Fastify, plain Node http, etc.
async function handler(req, res) {
  const { token } = extractToken(req.headers);
  if (!token) return res.status(401).json({ error: 'agentvisa_required' });

  const result = await verify(token, {
    widgetId: process.env.AGENTVISA_WIDGET_ID!,
    apiKey:   process.env.AGENTVISA_API_KEY!,
  });

  if (!result.valid) return res.status(401).json({ error: result.reason });
  // Proceed
}

Web Bot Auth (RFC 9421)

When an agent sends AgentVisa-Assertion instead of X-AgentVisa-Token, the library detects that the token was bound in a Web Bot Auth signature and reports it:

app.post('/api/action', (req, res) => {
  const av = req.agentVisa!;

  console.log(av.valid);           // true  — human verified
  console.log(av.webBotAuthBound); // true  — token covered by RFC 9421 signature
                                   // false — arrived via X-AgentVisa-Token (standard)

  // Both true = complete trust: which agent + which human, cryptographically bound
});

Note: webBotAuthBound: true confirms the structural binding is present. The RFC 9421 signature cryptography is verified by your WAF/CDN (e.g. Cloudflare Web Bot Auth) before the request reaches your app.


API reference

agentVisa(options) — Express middleware

| Option | Type | Required | Description | |--------|------|----------|-------------| | widgetId | string | ✓ | Your wgt_xxx widget ID | | apiKey | string | ✓ | Your wk_xxx API key | | onFail | 'reject' \| 'flag' | — | 'reject' (default) sends 401; 'flag' sets req.agentVisa and continues | | rejectBody | object | — | Custom body for 401 responses | | apiUrl | string | — | Override API base URL (testing) |

Attaches req.agentVisa: VerifyResult & { token: string \| null } to the request.


verify(token, options, headers?) — standalone

const result = await verify(token, { widgetId, apiKey }, req.headers);

Returns a VerifyResult:

| Field | Type | Description | |-------|------|-------------| | valid | boolean | Token is valid and human is verified | | humanVerified | boolean | Alias for valid | | reason | string | 'ok' or error code | | verifiedAt | string | ISO timestamp of human verification | | expiresAt | string | ISO timestamp of token expiry | | domainVerified | boolean | Requesting domain is verified by the Widget Holder | | webBotAuthBound | boolean | Token was covered by RFC 9421 Signature-Input | | raw | object | Raw AgentVisa API response |


extractToken(headers) — utility

const { token, source } = extractToken(req.headers);
// source: 'assertion' | 'header' | null
// 'assertion' = AgentVisa-Assertion header (Web Bot Auth mode)
// 'header'    = X-AgentVisa-Token header (standard mode)

How agents send the token

Agents use the AgentVisa MCP server (@agentvisa/mcp) to get a tmp_xxx token, then send it in one of two ways:

Standard mode:

X-AgentVisa-Token: tmp_xxxxxxxxxxxxxxxxxxxx

Web Bot Auth mode (RFC 9421 — token bound in the signature):

AgentVisa-Assertion: tmp_xxxxxxxxxxxxxxxxxxxx
Signature-Input: sig1=("@method" "@path" "host" "agentvisa-assertion");keyid="acme-bot-key";created=1234567890
Signature: sig1=:base64sig:

License

MIT · agentvisa.ai