Penny Data

Documentation.

2 services, each 1 route and 1 price. Send a value, pay a fraction of a cent in USDC with x402, get tidy JSON back.

UK Company Lookup 0.005 USDC

UK company profile from the Companies House public register, returned as JSON.

Route

GET https://x402-lab.vercel.app/api/company/{number}

number: Companies House company number: up to 8 digits, or a 2-letter prefix such as SC followed by digits. Example: 00445790.

Returns

Name, status, type, incorporation date, registered office, SIC codes, and when the next accounts and confirmation statement are due. Empty fields are null. A real response:

{
  "company_number": "00445790",
  "company_name": "TESCO PLC",
  "status": "active",
  "type": "plc",
  "incorporation_date": "1947-11-27",
  "registered_office_address": {
    "care_of": null,
    "po_box": null,
    "premises": null,
    "address_line_1": "Tesco House, Shire Park",
    "address_line_2": "Kestrel Way",
    "locality": "Welwyn Garden City",
    "region": null,
    "postal_code": "AL7 1GA",
    "country": "United Kingdom"
  },
  "sic_codes": [
    "47110"
  ],
  "accounts_next_due": "2027-08-26",
  "confirmation_statement_next_due": "2027-07-02"
}

Source

Fetched live from Companies House on each call, never cached. Companies House allows this service 600 requests per 5 minutes in total; past that, calls return 502 and are not charged.

Contains public sector information from Companies House, licensed under the Open Government Licence v3.0. Not affiliated with Companies House.

UK Postcode Lookup 0.002 USDC

Location and areas for a Great Britain postcode: latitude and longitude, ward, district, constituency and region, as JSON.

Route

GET https://x402-lab.vercel.app/api/postcode/{postcode}

postcode: Great Britain postcode, with or without the space, any case. Northern Ireland (BT) is not supported. Example: SW1A1AA.

Returns

The postcode, its latitude and longitude, and its ward, district, parliamentary constituency, region and country. Empty fields are null. A real response:

{
  "postcode": "SW1A 1AA",
  "latitude": 51.50101,
  "longitude": -0.141563,
  "ward": "St James's",
  "district": "Westminster",
  "constituency": "Cities of London and Westminster",
  "region": "London",
  "country": "England"
}

Source

Fetched live from postcodes.io on each call, never cached. postcodes.io is a free public service with no published limit; if it is slow or down, calls return 502 and are not charged.

Data from postcodes.io. Great Britain postcode data under the OS OpenData licence. Contains Ordnance Survey data © Crown copyright and database right 2025. Contains Royal Mail data © Royal Mail copyright and database right 2025. Contains National Statistics data © Crown copyright and database right 2025. Contains NRS data © Crown copyright and database right 2025.

For every service

Price

Network
Base eip155:8453
Asset
USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Scheme
x402 exact. The facilitator pays the gas; you need no ETH.
Account
None. No API key, no sign-up.

Pay with x402

The first request answers 402 with the payment details in the PAYMENT-REQUIRED header. An x402 client signs a USDC transfer for exactly that amount and retries with a PAYMENT-SIGNATURE header; the data comes back with a PAYMENT-RESPONSE header holding the settlement transaction. In Node:

// npm install @x402/fetch @x402/evm viem
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

// A wallet holding a little USDC on Base. No ETH needed.
const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`);
const client = new x402Client().register("eip155:8453", new ExactEvmScheme(signer));
const fetchWithPayment = wrapFetchWithPayment(fetch, client);

const res = await fetchWithPayment("https://x402-lab.vercel.app/api/company/00445790");
console.log(res.status, await res.json());

To see what you will be asked to pay, decode the header from a bare request:

curl -si https://x402-lab.vercel.app/api/company/00445790 \
  | grep -i '^payment-required:' | cut -d' ' -f2 | tr -d '\r' | base64 -d

The part that matters:

{
  "scheme": "exact",
  "network": "eip155:8453",
  "amount": "5000",
  "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "payTo": "0xd0A3c0f5612EcD88e4b16Ef1cD458e1a5E8FFD49",
  "maxTimeoutSeconds": 300
}

Errors

StatusMeaningCharged
200Data returned.Yes
400Malformed input.No
402Payment required, or the payment was invalid. Details in the headers.No
404Nothing found for that input.No
502The data source did not answer, or returned an error.No

Your payment is verified first and settled only after the data is ready. If the lookup fails, the signed payment is never submitted, so no USDC leaves your wallet.

Rate limits

No per-caller limit. Each data source has its own; see the service above. Retry after a short wait.

For agents

What we keep

For each paid call we keep the payer address, the service, the value looked up and the transaction, which are shown on the payments ledger. Data from the sources is never stored.