# Agent Payment Checker — x402, MPP, L402, UCP & AP2 Detector (`samgov-tools/agentpay-checker`) Actor

Check which AI-agent payment protocols a URL supports: x402, MPP (Machine Payments Protocol), L402, UCP and A2A/AP2 discovery files. Decodes prices, networks and recipients, flags errors. Read-only, never pays.

- **URL**: https://apify.com/samgov-tools/agentpay-checker.md
- **Developed by:** [AgentReady Tools](https://apify.com/samgov-tools) (community)
- **Categories:** Developer tools, AI, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 url checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Agent Payment Checker: x402, MPP, L402, UCP & AP2 Detector

Check which AI-agent payment protocols a public URL supports, and whether they are set up correctly. Give it API endpoints, MCP/HTTP routes or site homepages. For each URL it reports:

- **x402** (v1 body or v2 `PAYMENT-REQUIRED` header): scheme, network, asset, price in atomic units and USD for known stablecoins, `payTo`.
- **MPP / Machine Payments Protocol** (`WWW-Authenticate: Payment`): method (tempo, stripe, solana…), intent (charge, session), amount, currency, recipient, expiry.
- **L402 / LSAT** (Lightning): macaroon and invoice present, invoice network, amount in sats.
- **Discovery files**: `/.well-known/x402`, UCP profile `/.well-known/ucp`, A2A agent card with **AP2** or x402 extensions, and mentions in `llms.txt` / `agents.json`. Mentions are reported only as unverified hints, for example ACP.
- **Issues** with stable codes and a fix hint for each: missing fields, testnet networks, expired challenges, a 402 with no recognizable challenge, UCP cache rules, CORS headers browser agents need.

**Read-only by design.** Every request is a plain `GET` with no cookies, no `Authorization` and no payment headers. The Actor never signs, never pays, and never completes a checkout.

### For AI agents

Apify MCP: `https://mcp.apify.com?tools=samgov-tools/agentpay-checker`

Example prompt: "Use samgov-tools/agentpay-checker on https://api.example.com/v1/search and tell me which payment protocols it accepts and what one call costs."

- Start with `{"urls": ["https://..."]}`. One dataset item per fetched URL. Read `protocolsDetected` (verified) and `hints` (unverified mentions) first, then `summary` and `issues`.
- To check the price before paying a 402 endpoint yourself, read `x402.options[].amountUsd` or `mpp.challenges[].amountUsd`. A null `amountUsd` means the asset is not a known USD stablecoin, so use `amountAtomic` plus `asset` or `currency`.
- `issues[].code` values are stable, so you can branch on them, for example `x402_testnet`, `mpp_test_network`, `mpp_expired` or `unrecognized_402`.
- Set `checkDiscovery: false` to probe only the exact URLs. Discovery runs once per site, even for many URLs on the same site.
- Refused URLs (private or local network, non-default port, embedded credentials, robots.txt disallow, invalid) appear only in `OUTPUT` and are not charged.

#### Paying agents without an Apify account (x402 / MPP)

An agent without an Apify account can buy a prepaid Apify API token from Apify AGI (`agi.apify.com`) with x402 (USDC on Base or Solana), MPP (Tempo or Solana) or Skyfire. It then uses that token as the Apify API token in the REST example below (Actor `samgov-tools~agentpay-checker`), or as the bearer token for the Apify MCP server.

This Actor uses limited permissions, which prepaid tokens require. Apify's current terms: minimum $1, the balance is a hard spending cap, the token expires 14 days after purchase, unused balance is non-refundable, and the feature is experimental. Check `agi.apify.com` for current terms before paying.

### Quick start

```bash
curl -X POST "https://api.apify.com/v2/acts/samgov-tools~agentpay-checker/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"urls":["https://x402.payai.network/api/base/paid-content","https://mpp.dev/api/ping/paid"]}'
```

### Input

| Field | Type | Default | Notes |
| --- | --- | --- | --- |
| `urls` | string\[] (max 50) | two public demo endpoints | Bare domains get `https://`. Duplicates are removed. |
| `checkDiscovery` | boolean | `true` | Adds about 6 polite GETs per site. |

### Output (one item per fetched URL)

```json
{
  "url": "https://x402.payai.network/api/base/paid-content",
  "httpStatus": 402, "paymentRequired": true, "status": "ok",
  "protocolsDetected": ["x402"], "hints": [],
  "x402": { "detected": true, "version": 2, "location": "header",
    "options": [{ "scheme": "exact", "network": "eip155:8453", "networkName": "Base", "assetName": "USDC (Base)", "amountAtomic": "10000", "amountUsd": 0.01, "payTo": "0xE383…08E6" }] },
  "mpp": { "detected": false, "challenges": [] },
  "issues": [{ "level": "info", "code": "x402_cors_expose", "message": "Browser-based agents cannot read PAYMENT-REQUIRED unless Access-Control-Expose-Headers lists it." }],
  "summary": "Detected: x402."
}
```

`OUTPUT` in the key-value store lists every input URL with its status (including refused ones), plus totals, requests made and the stop reason.

### Pricing

Pay per event. The Pricing tab on the Actor page is authoritative.

| Event | Charged when | Price |
| --- | --- | --- |
| `url-check` | One URL fetched and reported in the dataset, including discovery for its site. Network errors count because the work was done. | $0.005 ($5 per 1,000 URLs) |
| `apify-actor-start` | Automatically by Apify once per run | Apify default |

Refused URLs are free. The Actor checks your run's maximum charge before every URL and stops cleanly when the budget is reached.

### Limits and behavior

- At most 1 request per second per host, or slower if robots.txt sets a Crawl-delay (capped at 30 s). Up to 4 different hosts are checked in parallel.
- robots.txt is respected for every path. Our user agent is `agentpay-checker-apify-actor`.
- Requests time out after 10 s. Bodies are read up to 256 KB. Redirects are followed up to 3 hops, each hop re-checked.
- SSRF protection: only http/https on ports 80 and 443, with no credentials in the URL. Hosts that resolve to private, loopback, link-local, CGNAT or reserved addresses are refused.
- Detection covers what a server publishes without payment. Flows that need a POST body or an MCP session, such as MCP `-32042` errors, are out of scope. ACP has no public discovery file, so it appears only as a hint.
- No data is stored beyond your run's dataset and OUTPUT.

### Local development

```bash
npm install && npm test   # offline tests with captured fixtures
LOCAL_FAKE_IP_DNS=1 npm run live   # live smoke; the env flag is only for sandboxes whose DNS proxy answers from 198.18.0.0/15
```

### FAQ

**Does it pay or try a test payment?** No. It never creates or sends a payment payload.

**Why is `amountUsd` null?** The asset is not in the built-in list of USD stablecoins (USDC on Base, Ethereum, Polygon, Arbitrum and Solana; USDC.e, OUSD and pathUSD on Tempo).

**Can it check sites behind a login?** No. It sends no credentials by design.

# Actor input Schema

## `urls` (type: `array`):

Up to 50 public http(s) URLs: a paid API endpoint, an MCP/HTTP route or a site homepage. A bare domain gets https://. Duplicates are removed. Private, local and non-default-port targets are refused and not charged. Empty uses two public demo endpoints.

## `checkDiscovery` (type: `boolean`):

Also read, once per site, /.well-known/x402, /.well-known/ucp, /.well-known/agent-card.json (or agent.json), /llms.txt and /.well-known/agents.json. Adds about 6 polite requests per site. Turn off to probe only the given URLs.

## Actor input object example

```json
{
  "urls": [
    "https://mpp.dev/api/ping/paid",
    "https://x402.payai.network/api/base/paid-content"
  ],
  "checkDiscovery": true
}
```

# Actor output Schema

## `results` (type: `string`):

Default dataset: one item per fetched URL with decoded x402, MPP, L402 and discovery results.

## `summary` (type: `string`):

OUTPUT: status per URL including refused ones, totals, requests made and stop reason.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://mpp.dev/api/ping/paid",
        "https://x402.payai.network/api/base/paid-content"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("samgov-tools/agentpay-checker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": [
        "https://mpp.dev/api/ping/paid",
        "https://x402.payai.network/api/base/paid-content",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("samgov-tools/agentpay-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://mpp.dev/api/ping/paid",
    "https://x402.payai.network/api/base/paid-content"
  ]
}' |
apify call samgov-tools/agentpay-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,samgov-tools/agentpay-checker"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/kmiHkcm1ew2om95Rl/builds/YSyP1Jh8dIvKjsFmD/openapi.json
