Install guide
Requestway receives a report after each x402 payment outcome and turns it into earnings and per-route analytics. It is never part of the payment itself. Create a project to get a key, then follow the section for your stack.
Laravel
For apps that charge with requestway/laravel-x402 (Laravel 12 or 13).
- Install the package if you haven't:
composer require requestway/laravel-x402 - Add your project key to
.env:X402_PLATFORM_KEY=rw_live_… - Make sure a queue worker is running. The package queues one batch per request after the response is sent and posts it from the job.
- Make a paid request, or any request to a protected route with
X402_MODE=observe. Your project page flips from "waiting" to live as soon as the event lands.
Reporting is off unless X402_PLATFORM_KEY is set. X402_PLATFORM_URL defaults to https://api.requestway.com/x402/events, X402_PLATFORM_TIMEOUT to 5 seconds, and X402_PLATFORM_QUEUE and X402_PLATFORM_QUEUE_CONNECTION pick where the job runs.
Node
For apps using @x402/express, @x402/next or @x402/hono. @requestway/reporter is a zero-dependency reporter for Node 20+. It does not implement x402; it reports what your middleware decided.
npm install @requestway/reporter- Set
REQUESTWAY_KEY=rw_live_… - Create one reporter and call
rw.settled(),rw.failed()andrw.observed()from your x402 resource server's hooks. The README has full Express and Next.js examples.
Serverless (Vercel, Lambda, Cloudflare): the platform freezes your function once the response is sent, so pass waitUntil to reporter() or await rw.flush() before returning. Without it, events are lost silently.
Endpoint tester
Each project has a Test endpoint tab. Give it the URL of a paid route and it runs the exchange an agent would:
- Calls the URL without paying and expects
402 Payment Required. - Reads the payment requirements (the v2
PAYMENT-REQUIREDheader, or a v1 body) and checks a client could pay them: scheme, network, asset,payToand the EIP-712 domain inextra. - If your endpoint accepts a testnet the tester holds funds on (Base Sepolia), signs an EIP-3009 payment with test USDC from a Requestway wallet and retries with it.
- Reads the settlement receipt (
PAYMENT-RESPONSE) and links the transaction on the block explorer. - Waits up to 20 seconds for your app's own report to reach this project, which proves the key and queue are set up.
It never spends real money. If your endpoint only accepts mainnet, the tester checks the 402 and stops; its signer refuses any chain that is not a known testnet. To run the full paid test, point a staging copy at Base Sepolia with X402_NETWORK=eip155:84532 and a facilitator that supports it, such as https://x402.org/facilitator.
The tester only calls public https addresses, never follows redirects, gives up after 20 seconds, and identifies itself as RequestwayEndpointTester/1.0 (+https://requestway.com/docs#tester). Each test pays at most 1 test USDC, and you can run 10 an hour. Test only endpoints you operate or are allowed to test.
Mainnet and testnet
Every event is classified by its network. Testnet payments (Base Sepolia, Avalanche Fuji, Arbitrum Sepolia and the other x402 testnets) are kept in a separate Testnet view, so test traffic never inflates real earnings. The dashboard opens on whichever your app reported from most recently, so when you change X402_NETWORK from a testnet to mainnet it follows on its own. You can switch views at any time.
Live and test keys
Each project has a live key (rw_live_…) and a test key (rw_test_…). Use the test key in staging and local development; its events appear under Test on the dashboard and never in live figures. Keys are stored as SHA-256 hashes and shown once. Regenerating or revoking a key stops the old one immediately, and we email you whenever that happens.
Troubleshooting
- Nothing arrives from Laravel. Check a queue worker is running, run
php artisan config:clearif you cache config, and runphp artisan x402:doctorto check the rest of the package's configuration. - Nothing arrives from Node on serverless. Add
waitUntilorawait rw.flush(). PassonErrorto see delivery failures; the reporter logs nothing by default. - 401 responses. The key is mistyped, revoked or regenerated. Your app is unaffected; only reporting stops.
- 429 responses. You've hit the per-project rate limit. Events in that batch are dropped.
- Events in the wrong place. A
rw_test_key reports to the Test view.
Ingest API
Anything can report by posting the same JSON the packages send. The body is snake_case.
POST https://api.requestway.com/x402/events
Authorization: Bearer rw_live_xxx
Content-Type: application/json
{
"source": "my-sdk",
"events": [
{
"type": "payment.settled",
"at": "2026-10-11T12:34:56+00:00",
"payment": {
"route": "market-data",
"method": "GET",
"resource": "https://api.example.com/premium-data",
"mode": "enforce",
"price_usd": "0.01",
"amount_atomic": "10000",
"asset": "USDC",
"network": "eip155:8453",
"pay_to": "0xabc…",
"request_id": "req_123",
"transaction": "0xdef…",
"pending": false
}
}
]
}
| Field | Notes |
|---|---|
type | payment.settled (extras transaction, pending), payment.failed (extras stage, reason) or payment.observed. Other types are ignored. |
at | ISO 8601 with a timezone. Events more than 30 days old or a day in the future are skipped. |
price_usd, amount_atomic | Strings, never numbers. amount_atomic can exceed 64-bit integers. |
resource | Split into host and path on arrival. The query string and fragment are discarded and never stored. |
request_id | Strongly recommended. Duplicates are dropped on a hash of project, type, request id, time, route and amount, which makes retries safe. |
| Everything else | Optional. Omit nulls. Unknown fields, including any payer or wallet field, are discarded. |
A successful request returns 202 with received, accepted, duplicates and rejected counts. Totals update within a few seconds.
Limits
- 500 events and 1 MB per request. Larger batches get
413. - 3,000 requests per minute per project, then
429. - Raw events are kept 30 days; daily totals for the life of the project.