開発者向け

食品価格 API(x402)

ワンちゃんの手作りごはんの食材費を出すために集めている、日本の食品の小売価格データです。日本食品標準成分表(文部科学省)の食品番号をキーに引けます。アカウント登録も API キーも不要で、リクエストごとに少額の USDC を支払って使います。AI エージェントからそのまま呼べます。

できること

  • ・食品番号(例: 01001)を指定して、現在の価格(円)を取得する
  • ・最大 20 件の食品番号をまとめて取得する
  • ・食品名などの部分一致で検索し、100 g あたりの価格を一覧で受け取る
  • ・任意のグラム数での価格を受け取る

読み取り専用です。返すのは価格で、栄養成分値と価格の履歴は含みません。

x402 で支払う

x402 は、HTTP の 402 Payment Required を使ってリクエストごとに支払うプロトコルです。

  1. 有料のエンドポイントを呼ぶと、402 と PAYMENT-REQUIRED ヘッダ(価格・ネットワーク・受取先)が返ります。
  2. クライアントが USDC の支払いに署名し、PAYMENT-SIGNATURE ヘッダを付けて同じリクエストを送り直します。
  3. 決済が済むと 200 と結果が返り、PAYMENT-RESPONSE ヘッダに決済結果が入ります。
ベース URL
https://food-price.wanpak.uk
通貨
USDC
ネットワーク
Base(eip155:8453)
スキーム
exact
ファシリテーター
Coinbase CDP

エンドポイントと料金

  • GET/foods/{mext_code}$0.01

    食品番号を 1 つ指定して、価格を取得します。

    • ・amount_g(任意): 価格を出すグラム数。省略時は 100。0 より大きく 100,000 以下。
    • ・存在しない食品番号は、支払いの前に 404 を返します。
  • GET/foods?ids=01001,07012$0.01 × 件数(最大 $0.20)

    食品番号をカンマ区切りで 1〜20 件指定して、まとめて取得します。

    • ・amount_g(任意): 上と同じ。
    • ・見つからない番号は not_found に入り、課金の対象です。1 件も見つからなければ、支払いの前に 404 を返します。
  • POST/foods/search$0.05

    和名・英名・食品番号・別名・検索キーワードの部分一致で検索します。

    • ・JSON ボディ: query(1〜80 文字)と limit(1〜30 の整数)。どちらも必須。
    • ・価格は常に 100 g あたり。並び順は食品群、和名の順です。
    • ・0 件でも課金されます(count: 0 を返します)。
  • GET/無料

    サービスの説明、ネットワーク、ルートと料金を JSON(英語)で返します。

    • ・死活確認は GET /health(無料)。

レスポンス

GET /foods/{mext_code} の例です。円の値は形を示すための例です。

JSON
{
  "prices": [
    {
      "food_id": "01001",
      "name_ja": "アマランサス 玄穀",
      "name_en": "Amaranth, grain",
      "category_id": 1,
      "price_yen": 150,
      "amount_g": 100,
      "price_per_gram": 1.5,
      "confidence": 0.8,
      "is_estimate": false,
      "non_distributed": false
    }
  ]
}
food_id
日本食品標準成分表の食品番号
name_ja / name_en
食品名(英名は空のことがあります)
category_id
成分表の食品群番号
price_yen
amount_g グラムあたりの価格(円、0.1 円単位で丸め)
price_per_gram
1 g あたりの価格(円)
confidence
価格の確からしさ(0〜1)
is_estimate
推定値のとき true
non_distributed
市販されていない食品や、殻などの副産物のとき true

価格が登録されていない食品は price_yen と price_per_gram が 0 になります。無料という意味ではありません。

呼び出し例

curl で 402 を見る

shell
curl -i https://food-price.wanpak.uk/foods/01001

# HTTP/2 402
# content-type: application/json
# payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQYXltZW50IHJlcXVpcmVkIiwi...

PAYMENT-REQUIRED の中身は Base64 の JSON です。

shell
curl -s -D - -o /dev/null https://food-price.wanpak.uk/foods/01001 \
  | grep -i '^payment-required:' | cut -d' ' -f2 | tr -d '\r' \
  | base64 -d

実際に返ってくる中身です(説明文と extensions は省略)。amount は USDC の最小単位(6 桁)で、10000 が $0.01 です。

JSON
{
  "x402Version": 2,
  "error": "Payment required",
  "resource": {
    "url": "https://food-price.wanpak.uk/foods/01001",
    "description": "Current Japanese retail price in JPY for one active food. …",
    "mimeType": "application/json",
    "serviceName": "food-price-db",
    "tags": ["japan", "retail-price", "mext", "jpy", "food"]
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "amount": "10000",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "payTo": "0xCfB9c9608AF3E400954E15fFFbC5663436300Fd4",
      "maxTimeoutSeconds": 300,
      "extra": { "name": "USD Coin", "version": "2" }
    }
  ],
  "extensions": { "bazaar": { … } }
}

JavaScript(@x402/fetch)

402 を受けると、支払いと再リクエストを自動で行います。

shell
npm install @x402/fetch @x402/evm viem
TypeScript
import { wrapFetchWithPaymentFromConfig, decodePaymentResponseHeader } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";

const BASE = "https://food-price.wanpak.uk";

// Base 上の USDC を持つウォレット
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);

const fetchWithPayment = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:*", client: new ExactEvmScheme(account) }],
});

// 1 件: $0.01
const res = await fetchWithPayment(`${BASE}/foods/01001?amount_g=250`);
console.log(await res.json());

const receipt = res.headers.get("PAYMENT-RESPONSE");
if (receipt) console.log(decodePaymentResponseHeader(receipt));

// 検索: $0.05
const search = await fetchWithPayment(`${BASE}/foods/search`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ query: "鶏", limit: 10 }),
});
console.log(await search.json());

データについて

  • ・食品番号と食品群は、文部科学省「日本食品標準成分表」のものです。
  • ・価格は、国内の小売店で調べた店頭価格です。文部科学省が公表している値ではありません。
  • ・食品ごとに 1 か月・3 か月・1 年のいずれかの間隔で調べ直しています。
  • ・わんぱくキッチンのレシピの食材費と同じデータです。実際の価格は店や時期で変わるので、目安として使ってください。

関連リンク