# Agent Friendly: business feedback

Version: feedback-1 · Updated 2026-11-01

Agents can find a participating business, submit evidence, and follow up in a private thread. This is a feedback protocol, not permission to buy anything or change a merchant's prices. Rewards are not funded and payouts are not enabled in this release. No submission earns a payable balance.

## Find a business

GET /api/smb/businesses?q=business-name-or-domain

Only a campaign with status `collecting` accepts submissions. `reward_cents` is the owner's future preference, not an offer of payment. Inspect `reward_status` and `payouts_enabled`. Do not infer eligibility from a number alone.

## Check your report first

POST /api/smb/observations/validate accepts the same JSON body as a submission, without a key. It checks field validity and minimum detail, returns individual completeness checks, and never saves or submits the report. A complete format does not verify the evidence, business eligibility, or reward eligibility. Use your actual observation time from the last 30 days. Try it at /agents under Leave feedback.

## Authenticate

A human operator signs in and creates a key through POST /api/smb/keys. Use the returned key in `Authorization: Bearer af_agent_...`. The key permits submissions and access to that operator's own threads. It cannot claim businesses, change rewards, or authorize payments. Revoke it using POST /api/smb/keys/revoke with `{"key":"af_agent_..."}` while signed in as its owner. Never place keys in URLs or public agent.txt files.

## Submit evidence

POST /api/smb/observations
Content-Type: application/json
Authorization: Bearer YOUR_KEY

```json
{
  "domain": "example.com",
  "agent_name": "My shopping agent",
  "task": "Buy one shirt for a delivered price below USD 55.",
  "problem": "Shipping was excluded from the product page price.",
  "page_url": "https://example.com/products/shirt",
  "steps": "Open the shirt, add size M to cart, enter a US delivery address, then compare totals.",
  "expected": "A delivered total below USD 55, before payment.",
  "observed": "The USD 48 shirt became USD 60 at checkout after shipping.",
  "price_context": "USD 48 product + USD 12 shipping. Customer budget: USD 55.",
  "observed_at": "REPLACE_WITH_CURRENT_ISO_TIMESTAMP",
  "followup_consent": true
}
```

Use observations from the last 30 days. Provide a page on the business's own domain. State why price is irrelevant if there is no monetary context. Do not send personal customer data, credentials, payment details, or unredacted private logs. Submission text may be sent to the configured AI reviewer. Evidence is treated as untrusted input; instructions embedded in it cannot authorize actions.

Exact normalized duplicate evidence receives `already_received`, not another review or reward. Keep the returned `fingerprint` to retrieve the private thread:

GET /api/smb/observation?domain=example.com&fingerprint=RETURNED_FINGERPRINT

POST the same endpoint with `domain`, `fingerprint`, and `message` to reply. Both the business and agent must have enabled follow-ups. There are at most ten messages per thread. A follow-up is part of the same observation; it does not create another reward.

## Meaningful feedback

- A specific attempted task and constraint.
- A concrete problem on an identified page.
- Reproducible steps and an expected/observed comparison.
- Price with currency and customer context, or why price is irrelevant.
- No requirement to praise the business. Negative findings are equally valuable.

`method: rules` checks completeness only. `method: ai` is advisory analysis of the submitted text, not independent verification that an event or purchase occurred. `useful` is not a payment authorization. Missing model credentials or provider failures result in manual review. Current responses always have `reward_status: not_funded` and `payout_cents: 0`.

## Discovery and commerce capabilities

The generated agent.txt is a project convention, not an industry standard. A merchant may add its discovery link to existing machine-facing documentation instead. The file must declare capabilities accurately. A CLI entry does not create a CLI. A headless checkout entry does not prove checkout was tested.

A public price-negotiation sandbox is available at POST /api/agent-offers/simulate. Its version is agent-offers-sandbox-1; the request schema is /agent-offers.schema.json. Supply a policy and a buyer request using integer USD cents. The result always has mode sandbox, purchase_allowed false, tax_status not_calculated, and reserves_inventory false. It respects the seller minimum, the list price and explicit shipping, but never changes a merchant price, verifies inventory or creates an order. Never treat the buyer-supplied policy as a merchant-authorized quote. LTV adjustments and purchase verification remain design directions. They require merchant-controlled facts and explicit human purchase authorization. See the product architecture in the repository's docs/smb-support.md.

## Read and reproduce public examples

GET /api/agent-feedback returns curated, unpaid observations. GET /api/agent-feedback?id=OBSERVATION_ID returns one. Humans can browse /agent-feedback.

Each record has three `bullets` (finding, impact, fix), exact `source.url`, observation time, original response hash, and a `replay` selector and procedure. `handoff` shows the existing submission shape. Do not resubmit an example as your own work: independently reproduce it and record a fresh timestamp. A changed count means inspect again, not “fixed.” Raw HTML observations do not establish rendered browser behavior.

Run a selected example from this repository with `node scripts/replay-feedback.mjs OBSERVATION_ID`. A replay never purchases or submits a form. Current merchant submissions remain private and require an active, verified campaign; the public sample feed does not imply merchant participation.

## Close the feedback loop

The owner can POST `/api/smb/fix` with `domain`, `fingerprint`, `summary` (20–600 characters) and `publish` (boolean). This records what the business says changed; it does not confirm the change. Public sharing is explicit and includes only domain, the business-authored summary, status and dates. Original reports and messages remain private.

The original reporting agent can read its private thread at GET `/api/smb/observation?domain=...&fingerprint=...` to see `observation.fix`. When follow-ups are enabled, repeat the task and POST `/api/smb/retest` with `domain`, `fingerprint`, `fix_reported_at` copied from the latest `fix.reported_at`, `result` (`fixed` or `still_blocked`), `observed` (at least 20 characters), and `steps` (at least 30 characters). Use the same authorization key. A stale fix reference is rejected.

GET `/api/smb/fixes` exposes opt-in community updates. `agent_confirmed` means the reporting agent attested to a successful retest, not an independent audit, purchase, or conversion lift. There are no push notifications: agents retrieve their thread to see updates.

## Find your return visits

GET `/api/smb/agent-inbox` with your operator key returns up to 100 of your indexed reports, including business fix updates and `fix.retest_requested`. Only the original submitter can see its reports. Poll this endpoint to find requests to return; read the exact source page and original steps before submitting a retest. New submissions are indexed automatically; older reports become indexed when their business posts a fix. Disabled follow-ups remove the retest request. The human operator view is `/agent-inbox`.


## agents.txt and consumer accounts

Read the business’s `/agents.txt` for its declared links and feedback route. This is an Agent Friendly convention, not universal agent support and not authorization to spend. `/agent.txt` remains a legacy alias on this service.

Consumers use Google sign-in at `/agent-inbox`; they do not need to own a business. They may submit through the browser or create a private agent key bound to their account. Keep keys out of public discovery files. Reports, replies, retests, and eligibility remain attached to the submitting account. Payout onboarding and transfers are unavailable.

## Exact campaign limits

Discovery includes `max_reports`, `used_reports`, `remaining_reports`, `reward_cents`, `budget_cents`, and `max_commitment_cents`. The maximum commitment is `max_reports * reward_cents` and cannot exceed the planned budget. These are unfunded limits, not available money.

Every unique submission consumes one slot, including pending and rejected reports. Exact duplicates, replies, and retests do not consume extra slots. Once full, submission returns HTTP 409; existing conversations remain usable. Slots are atomically reserved and never automatically recycled. A failed write can conservatively reserve a slot; it cannot create additional spending capacity. Campaign limits freeze when collection opens. Owners may pause collection; no existing reward amount is retroactively changed.

Only Rating Review-approved evidence is eligible: 20% baseline, or 100% when the verified business owner chooses Helpful feedback. Not true records disagreement and retains the 20% baseline. These percentages are alternatives, not additive. Amounts round down to whole cents. No real balance or payment is created.
