Skip to main content
Glama
README.md
# ReturnCheck — Return-policy verification for AI shopping agents

[![Wellknown verified](https://wellknown.network/agents/returncheck/badge.svg)](https://wellknown.network/agents/returncheck)

**ReturnCheck verifies which return policy actually applies to this purchase.**
For AI shopping agents, it resolves the case with a **verified** verdict — not a guess.

Give it a `product_url` and a `buyer_country` and it returns a verdict
(`YES` / `YES_WITH_CONDITIONS` / `NO` / `UNKNOWN`) with the **exact policy clause
quoted from the page**, the **source URL**, the return window, and a confidence
score. If it cannot verify a clause on the page, it returns `UNKNOWN` — it
**never invents**.

Built for **agent-to-agent commerce**: an MCP tool plus x402-friendly
micro-pricing at **$0.02 per verified answer** (UNKNOWN is free; a keyless free
trial is available).

---

## Why it exists

AI agents are starting to buy things. Before they buy, they need to know if a
purchase is reversible — and today no one answers "is this returnable?" in a way
a machine can trust and act on. ReturnCheck is the neutral verification primitive
for that: it sells to **every** shopping agent and competes with none of them.

## Quick start

**MCP (Streamable HTTP)** — tool: `check_return`
```
https://returncheck.m-angelmartinez-fer.workers.dev/mcp
```

**HTTP**
```bash
curl -X POST https://returncheck.m-angelmartinez-fer.workers.dev/v1/check \
  -H "content-type: application/json" \
  -d '{"product_url":"https://store.example/p/shoe","buyer_country":"US","item_condition":"unopened"}'
```

If you already have the product/policy page rendered, pass it as `page_html` or
`page_text` — ReturnCheck verifies against it and skips fetching (best coverage,
bypasses sites that block server-side reads). It still never invents.

When that content comes from a separate policy page, also send `page_source_url`
with its HTTP(S) URL. This preserves the supplied source in `evidence.source_url`
and the corpus while keeping `product_url` as the product context. The URL is
caller-declared and is not independently fetched. Without it, the existing
`product_url` fallback remains; legacy callers should add the field when supplying
a different page. Opened-product alternatives are recovered only for an explicit
adjacent generic clause; ambiguous, category-specific or conflicting terms still
require the normal verification path.

## x402 paid calls

The paid HTTP route is the same endpoint: `POST /v1/check`.

To inspect the live x402 terms without consuming the free allowance, send a
**bodyless** `POST /v1/check` with no `PAYMENT-SIGNATURE`. ReturnCheck responds
with the live 402 challenge. Do not send `{}` or a real check body for this
discovery probe.

For a paid call, base64-encode a JSON envelope in the `PAYMENT-SIGNATURE` header:

```json
{
  "x402Version": 2,
  "accepted": {
    "scheme": "exact",
    "network": "eip155:8453",
    "amount": "20000",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0xbF428071027402E9b0cE85e22146EDdc028cEB3b",
    "maxTimeoutSeconds": 60,
    "extra": { "name": "USD Coin", "version": "2" }
  },
  "payload": {
    "signature": "0x...",
    "authorization": {
      "from": "0x...",
      "to": "0x...",
      "value": "20000",
      "validAfter": "0",
      "validBefore": "...",
      "nonce": "0x..."
    }
  },
  "extensions": {
    "payment-identifier": {
      "info": {
        "required": true,
        "id": "unique-id-16-to-128-chars"
      }
    }
  }
}
```

Rules:

- `accepted` is the full accepted payment requirement object, not a boolean.
- `payload` directly contains `signature` and `authorization`.
- The canonical identifier path is
  `extensions["payment-identifier"].info.id`.
- Do not copy the `bazaar` discovery extension into `PAYMENT-SIGNATURE`.
- The live 402 challenge is authoritative for current payment terms.
- A signed request enters the payment path directly; there is no need to exhaust
  the free allowance first.
- Replay the same paid operation with the same endpoint, body, identifier,
  signature and nonce. If an authorization expires before the paid call, sign a
  fresh authorization; that fresh authorization is then the one to replay.
- On `pending`, `unconfirmed`, HTTP 500, or another ambiguous settlement
  outcome, do not create a second authorization until the first outcome is
  reconciled.

## What you get back

```json
{
  "verdict": "YES_WITH_CONDITIONS",
  "returnable": true,
  "confidence": 0.9,
  "policy": { "merchant_return_days": 30, "return_category": "FiniteReturnWindow" },
  "evidence": {
    "source_url": "https://store.example/policies/refund-policy",
    "exact_clause": "Items may be returned within 30 days of delivery for a full refund.",
    "verified_on": "2026-08-23"
  }
}
```

## Pricing

| | |
|---|---|
| Verified answer (YES / NO / conditions) | **$0.02** |
| UNKNOWN | **Free** |
| Keyless free trial | a few calls/day, no signup |

## Discovery for agents

- OpenAPI: `/openapi.json`
- Plugin manifest: `/.well-known/ai-plugin.json`
- Agents manifest: `/agents.json`
- LLM manifest: `/llms.txt`
- MCP tool list: `/mcp`

## Deterministic preflight

Run `npm run check` to validate registered work and run the full regression suite.
Use `npm run work:new -- ucp job-name` to register new work (payment, corpus and
artifact profiles are also available). All registered jobs run automatically on
every push and pull request. See `AGENTS.md` for the permanent review routine.
Registered jobs now require a review receipt bound to the exact inputs. The check
also detects uncovered changed files and cross-lot corpus contamination. Delivery
and historical metrics profiles provide package/snapshot and benchmark checks.

Run `npm run validate` before reviewing payment packages, UCP evidence or corpus
changes. Three offline profiles produce PASS/FAIL, blocking errors, warnings,
SHA-256 hashes and fields requiring subsequent AI review. See
[preflight/README.md](preflight/README.md) for input contracts, limits and commands.
`npm test` includes the preflight regression tests. A PASS is not deployment or
payment authorization.

## Design principles

- **Never invent.** Every determinate verdict carries a clause verified literally
  against the page. If it can't be verified, the answer is `UNKNOWN`.
- **Frozen contract (v1.0).** Fields are only ever added, never broken.
- **US data first, global architecture.** Runs 100% serverless on the edge
  (Cloudflare Workers + D1 + Workers AI).

## Keywords

return policy API · returns verification · AI shopping agents · agentic commerce ·
MCP server · check_return · x402 · agent-to-agent payments · e-commerce returns ·
is this returnable · refund policy checker