Inspiration
A judge gets about ten minutes per submission, and most of it goes to a mechanical question: which parts of this description are actually backed by something, and which are just asserted? That sorting is the wrong thing for a human to spend ten minutes on, and it is exactly the kind of work that can be checked rather than guessed.
The x402 track wanted a real pay-per-call business model, and submission screening turned out to fit it precisely. Organizers, accelerators and grant programs need to process submissions in batch, they need it a few times a year, and nothing about that justifies an account, an API key or a subscription. With x402 the HTTP call is the transaction. An AI review agent can pay for an analysis with no human in the loop.
What it does

A project submission goes in: description, README, demo link, and optionally a rubric. What comes back is a Signal Packet that separates the claims someone verified from the claims someone merely made:
- Documented claims, each with a verbatim excerpt from a fetched artifact
- Requires video review, because this API reads text and repositories and does not watch videos
- Not documented, turned into reviewer questions rather than into verdicts
- Gaps, including the demo video recorded as an artifact nobody checked
- A receipt, so the caller has the on-chain proof of what they paid for
The rule the whole product rests on is evidence integrity enforced in code. Every "supported" verdict has to cite an excerpt that verbatim occurs in a fetched artifact. When the model invents a citation, and it routinely does, the server catches it, drops the citation, and downgrades the claim to unclear. Those corrections are reported back to the caller instead of being hidden, because they are the product.
Video evidence is deliberately out of scope here and handled by a separate project, Signal Review Reel. The judgment stays with the human. This API only establishes what the evidence actually supports.
Price is $0.05 per POST /v1/analyze, in USDC on Base. GET /healthz, /v1/rubrics/default and /v1/schema stay free.
How we built it

A Hono server on Node with x402 middleware wrapped around one route. The rounded nodes in the diagram are the only things outside the repo: the x402 facilitator, the fetched artifacts, and the Gemini API.
The paid path, left to right in the diagram:
- The client posts to
/v1/analyzeand gets a 402 back carrying the payment requirements in thePAYMENT-REQUIREDheader (x402 protocol v2). - It signs an EIP-712 USDC payment payload and retries with
PAYMENT-SIGNATURE. - The server verifies with the facilitator, then runs the pipeline: fetch artifacts (
sources.ts), extract claims through Gemini structured output (analyze.ts), enforce integrity (integrity.ts), and only then settle on chain. - The response carries the receipt twice, in the JSON body and in the
PAYMENT-RESPONSEheader, mirrored asX-PAYMENT-RESPONSEfor v1 clients.
Three details the boxes hide. Only POST /v1/analyze is gated; the free endpoints register before the middleware. Settlement happens after the analysis succeeds, so a failed analysis is never charged. And the browser holds no key: /viewer posts to /demo/run and the server runs src/paid-client.ts, the same payer code the terminal demo uses, so both surfaces exercise one payment implementation.
The model is never trusted with anything structural. It only ever references source ids it was handed. Ids, locators and timestamps are all assigned server-side.
Challenges we ran into
Models fabricate citations. Not occasionally, routinely. The fix was to stop treating the model's output as findings and treat it as a proposal: every cited excerpt is checked verbatim against the fetched source, failures are dropped, and the claim falls back to unclear. This turned into the most valuable thing the API returns.
instanceof Request is unreliable inside the payment client. @hono/node-server replaces the global Request and Response, and the x402 SDK builds its retry request from a different copy of that class. The code duck-types instead. In-process tests cannot catch this at all; it only shows up over a real socket, which is why test/loopback.test.ts exists.
Getting settlement ordering right. Charging on the way in is easier to implement and wrong. Verify before the pipeline, settle after it succeeds.
Making the demo runnable without a wallet. Reviewers should not need testnet USDC to understand the product. Leaving X402_PAY_TO unset makes the endpoint free and the receipt null while everything else, claims, evidence, integrity checks, gaps and questions, still runs. Setting it turns the full 402 to sign to retry to settle sequence back on.
Keeping the companion review video out of the request body. The viewer links a Signal Review Reel video for context, and it must never reach this API as evidence. That separation is structural: the URL lives in the sample's _meta block, which is stripped before the request body is built, and a test asserts it never appears in what goes over the wire.
Accomplishments that we're proud of
make setup && make test verifies the build in two commands, with no API key, no wallet and no network. 55 tests, including the whole x402 round trip against a mock facilitator with real client-side signing.
Integrity enforcement is the headline feature rather than a footnote. The API reports what it corrected, which is an unusual thing for a product to volunteer and the reason a judge could trust it.
One payment implementation. The browser viewer and the terminal demo share src/paid-client.ts, so there is no second code path pretending to be the first.
Mainnet readiness is configuration, not a rewrite. Network, facilitator and payee are all environment variables, and pricing stays in USD while the SDK converts to atomic units per network.
What we learned
x402 changes what an API can be sold as. No account, no key issuance, no onboarding, no minimum. That makes small, occasional, high-value calls viable in a way a subscription never would, and it makes the service machine-payable by default.
Structured output is not truthful output. Schema conformance tells you the shape is right and nothing about whether the content is real. Verification has to live in code, on the server, after the model has spoken.
Non-determinism is fine as long as the shape is stable. Exact counts shift run to run because the model is non-deterministic and the README is re-fetched live. What stays stable is the useful part: written claims supported with real excerpts, video and impact claims unclear, gaps and questions raised.
"Unclear" is a correct answer. Early on it felt like a failure mode. It is the honest output when nothing available settles a claim, and saying so is more useful to a judge than a confident guess.
What's next for Signal Packet API
Base mainnet with an authenticated facilitator, which is a one-line change at the auth-header hook. A batch endpoint priced per submission, because organizer-scale screening means hundreds of calls in one sitting.
More artifact types beyond READMEs and docs: deployed URLs, test runs, pull requests, so more claims move out of unclear on their own merits.
Closing the video gap by consuming Signal Review Reel output as evidence, and publishing finished packets into Signal Evidence Graph so every conclusion keeps its lineage.
Built With
- base
- base-sepolia
- css
- eip-712
- ethereum
- gemini-3.5-flash
- google-gemini
- google-genai
- hono
- html
- json-schema
- make
- node-test-runner
- node.js
- rest-api
- server-sent-events
- structured-output
- tsx
- typescript
- usdc
- vanilla-javascript
- viem
- x402

Log in or sign up for Devpost to join the conversation.