Skip to content
Botscent

Change prices for agents

Compute an agent price on your server, in the direction that a forged verdict cannot exploit.

Show and charge agents a different price than people. Compute the price on your server, where the page's scripts cannot change it.

Before you start

  • Install both halves of Botscent. See Next.js.
  • Read The trust model. It says which verdicts a visitor can forge.

1. Choose the direction of the price

A visitor can pose as an agent. A page report comes from the visitor's browser, and anyone can send the headers that produce an unverified name.

A visitor cannot pose as a verified agent without the signer's key. isVerified is true only for a signature that verified against a key bundled in the release, or for the platform's verified-bot field. A captured signature can still be replayed to the same host within its time window.

So the direction of the price decides which verdict you can use:

  • If the agent price is higher, use any agent verdict. A visitor who forges an agent verdict pays more, so the forgery costs the forger.
  • If the agent price is lower, give the lower price only when isVerified is true. Otherwise any visitor can claim it.

An agent that shows no evidence pays the person's price. A person who works inside an agent's surface, such as a Muse session that the person took over, pays the agent price.

Warning: If you change prices for agents, check the pricing rules where you sell. An agent buys for a person, so that person pays the agent price.

2. Compute the price on the server

In a server module, compute the price from a verdict:

lib/price.ts
import type { Verdict } from 'botscent/server'

// Prices in cents. The agent price is higher, so a forged agent verdict costs the forger.
export function priceFor(verdict: Verdict): number {
  return verdict.type === 'agent' ? 5400 : 4800
}

Every price now comes from one function on the server.

3. Serve the price

In a route handler, join the request's own verdict and the page report with combine. Then return the price for the joined verdict.

app/api/price/route.ts
import { combine, inspect, readReport } from 'botscent/server'
import { priceFor } from '../../../lib/price'

export async function GET(request: Request) {
  const own = await inspect(request)
  const report = readReport(request.headers.get('botscent-report'))
  return Response.json({ cents: priceFor(combine(own, report)) })
}

The route handler returns 4800 for a person and 5400 for an agent that either half found.

At checkout, compute the charge with priceFor in the checkout route handler, in the same way. Send the page report on the checkout request with reportHeaders, and take the price from the server, never from the page.

4. Show the price in the page

In a client component, fetch the price with the page report. Fetch it again when the page verdict changes:

app/product/price.tsx
'use client'
import { reportHeaders } from 'botscent'
import { useBotscent } from 'botscent/react'
import { useEffect, useState } from 'react'

export function Price() {
  const type = useBotscent((verdict) => verdict.type)
  const [cents, setCents] = useState<number | null>(null)
  useEffect(() => {
    let current = true
    fetch('/api/price', { headers: { ...reportHeaders('/api/price') } })
      .then((response) => response.json())
      .then((body: { cents: number }) => current && setCents(body.cents))
    return () => {
      current = false
    }
  }, [type])
  return <p>{cents === null ? '' : `$${(cents / 100).toFixed(2)}`}</p>
}

A person sees $48.00. When the page verdict becomes agent, the page shows $54.00.

5. Optional: Give verified agents a lower price

If the agent price is lower, compute the price from the request's own verdict with isVerified:

lib/price.ts
import { isVerified, type Verdict } from 'botscent/server'

// Prices in cents. The agent price is lower, so only a verified signature gets it.
export function priceFor(own: Verdict): number {
  return isVerified(own) ? 4200 : 4800
}

Pass await inspect(request) to this priceFor. A page report adds nothing here, because only the request's own verdict can be verified.

For one agent, use isVerified(own, 'chatgpt'). isVerified reads only the request that it gets. A hosted agent can sign its page loads and nothing else, so compute a verified price where the signed request arrives.

Result

People pay the person's price. Agents pay the agent price, and no visitor gains from a forged verdict. Every price comes from your server.

Next steps