H&M API:hm.com 日本の商品データを価格の種類ごとに分けて JSON に
H&M はオンラインストアの商品データを外部向けの API として公開していません。この API は hm.com の日本サイト(ja_jp)を、ログインしていない買い物客と同じ画面から読み取り、JSON で返します。商品名、色名、説明文は日本語、価格は円です。価格は 3 つに分かれています。メンバーでなくても支払う価格(`price`)、セール中だけ入る元の価格(`regular_price`)、そして H&M メンバー限定価格(`member_price`)です。2026年10月28日に「ワンピース」で検索したところ、最初の 10 件のうち 9 件にメンバー限定価格が付いていました。商品詳細には、サイトに出ている送料の案内(「メンバーは、3,499 円以上のお買い物で送料無料」)もそのまま入ります。取引先や出店者向けの仕組みではなく、注文もログインもせず、H&M に何かを送ることもありません。各呼び出しに `"country": "jp"` が必要です。
エンドポイント
| endpoint | 返ってくるもの | 必須 |
|---|---|---|
| search | キーワードで日本サイトの商品を検索します(1 ページ最大 72 件)。各商品に、支払う価格、セール中の元の価格と割引率、メンバー限定価格、表示用の価格(`¥1,999`)、色の一覧、サイズごとの在庫の有無が付きます。新着順・価格順の並び替えと、部門、セール品のみ(`sale_only`)、色、素材での絞り込みができます。 | query |
| product/detail | 商品番号(10 桁)、商品コード(7 桁)または商品ページの URL で 1 商品を取得します。日本語の説明文、部位ごとの素材と混率、環境に配慮した素材の割合、お手入れ方法、サイズごとの在庫と「残りわずか」、色違いの一覧とそれぞれの価格、評価とレビュー件数、送料の案内(`delivery_note`)が入ります。 | article_code |
| category | カテゴリページ 1 つ分の商品を、検索と同じ形で返します。カテゴリページの URL かパス、または前の呼び出しで返った `category_id` と `page_id` で指定します。 | すべて任意 |
| search/suggest | 検索窓に出る候補です。「ニット」なら「ニット帽」「ニットパンツ」「ニット レディース」などが返ります。 | query |
| product/availability | 1 商品の全色について、注文できるサイズと残りわずかのサイズだけを返す軽い呼び出しです。在庫の監視に向いています。 | article_code |
呼び出しごとにクレジットを消費します。失敗した呼び出しとブロックされた呼び出しは無料です。
動作する例
2026年10月28日の「ワンピース」の検索結果は 1,491 件でした。最初の 10 件のうち 9 件にメンバー限定価格があり、通常価格との差は 300 円から 1,200 円です。同じワンピース(商品コード 1358371)が色ごとに別の行になっていて、ライトピンクとダークグレーのメンバー限定価格は 1,399 円、ホワイトは 1,699 円と、色によって値段が違います。ダークグレーは 120/130 サイズだけ在庫切れでした。
curl -X POST https://api.reefapi.com/hm/v1/search \
-H "x-api-key: あなたのキー" \
-H "content-type: application/json" \
-d '{"query": "ワンピース", "country": "jp", "page_size": 10}'{
"ok": true,
"data": {
"results": [
{
"article_code": "1358371007",
"product_code": "1358371",
"name": "チュールスカート スウェットワンピース",
"url": "https://www2.hm.com/ja_jp/productpage.1358371007.html",
"price": 1999.0,
"regular_price": null,
"on_sale": false,
"member_price": 1399.0,
"price_formatted": "¥1,999",
"currency": "JPY",
"color_name": "ライトピンク/ユニコーン",
"color_count": 3,
"sizes": [
{ "size_code": "006", "label": "90", "in_stock": true },
{ "size_code": "007", "label": "100/105", "in_stock": true },
...
],
"sizes_in_stock": 5,
"availability": "Available",
...
},
...
{
"article_code": "1358371005",
"name": "チュールスカート スウェットワンピース",
"price": 1999.0,
"member_price": 1399.0,
"color_name": "ダークグレー/スター",
"sizes": [
...
{ "size_code": "009", "label": "120/130", "in_stock": false },
{ "size_code": "010", "label": "135/140", "in_stock": true }
],
"sizes_in_stock": 4,
...
},
...
{
"article_code": "1358371009",
"name": "チュールスカート スウェットワンピース",
"price": 1999.0,
"member_price": 1699.0,
"color_name": "ホワイト/La Vie Est Belle",
...
},
...
],
"count": 10,
"total_results": 1491,
"total_pages": 150,
"has_more": true,
"sort_applied": "relevance",
"country": "jp",
"language": "ja",
"locale": "ja_jp",
"currency": "JPY"
},
"meta": { "record_count": 10, "country": "jp", "charged_credits": 1, "cache_hit": false, "mode": "live" }
}H&M を自前でスクレイピングすると価格を取り違えるところ
検索結果の商品には、価格が最大 3 つ付いています。通常価格、セール価格、メンバー価格です。いちばん安い数字を「価格」として拾うと、メンバーでない人には払えない金額が販売価格として記録されます。2026年9月にこの API を作ったとき、フランスのサイトで「jean」を検索した 36 件のうち 15 件で、その取り違えが起きる計算でした。そのため `price` にはセール価格があればそれを、なければ通常価格を入れ、メンバー価格は必ず `member_price` に分けています。
色ごとに別の商品番号(10 桁 = 商品コード 7 桁 + 色 3 桁)があり、価格も色ごとに違うことがあります。上の例でも同じワンピースのメンバー限定価格が 1,399 円と 1,699 円に分かれていました。商品コード単位で価格を一つにまとめてしまうと、この差は消えます。
H&M は、ないものを頼まれてもエラーを返しません。存在しない商品番号のページは HTTP 200 で約 2.1 MB のトップページになり、最終ページより先のページ番号を指定すると、1 ページ目など、頼んだのとは別のページの商品が返ってきます。ステータスコードと件数だけを見ているスクリプトには、どちらも成功に見えます。この API では前者を NOT_FOUND に、後者を空の結果と `page_out_of_range: true` にしています。
素材も一つのリストにはなっていません。今回読んだワンピースは「アッパー: コットン 80%, ポリエステル 20%」「下部: ポリエステル 100%」のように部位ごとに書かれていて、`composition` も部位ごとに返します。素材名だけを平らに集めると、どこがコットンなのかがわからなくなります。
制限と正直な注記
- この API は H&M のものではなく、H&M の許可を得て運営しているものでもありません。H&M との間に契約や業務上の関係はありません。
- `country` の既定値は `us` です。`"country": "jp"` がないと、米国サイトの商品がドルで返ります。
- メンバー限定価格は H&M メンバー向けの価格で、会員でない人の支払額ではありません。「ワンピース」をセール品だけ(`sale_only: true`)に絞った最初の 10 件では、メンバー限定価格の付いた商品は 0 件でした。
- `sale_only` は日本サイトで効いています。「ワンピース」では 586 件で、返った 10 件はすべて `on_sale: true`、「コート」では 6 件でした。
- 原産国(`country_of_production`)は、今回読んだ 2 商品ともに null でした。2026年9月の構築時に調べた 24 商品でも、この項目が入っていたのはフランスのページの 2 商品だけでした。モデルの身長と着用サイズも 2 商品とも null でした。
- 日本語で返るのは、商品名、色名、説明文、素材、お手入れ方法、`product_type` などです。一方、`category`(例: 「Jumper dress」)や検索結果の部門名(「Women」「Men」「Kids」)、パンくずの最上位(「Kids」)は英語のまま返りました。
- 日本サイトの検索は大人向けと子ども向けを分けずに返します。「ワンピース」の最初の 10 件は 1 件を除いてキッズ商品で(`main_category` が `kids_` で始まる)、大人向けだけを追うなら部門で絞り込むか、`main_category` で振り分ける必要があります。
- 在庫は数量ではなく、サイズごとの在庫の有無(`in_stock`)と「残りわずか」(`few_left`)だけです。店舗ごとの在庫はわかりません。
- JAN コードは返りません。H&M のページにあるのは H&M 独自の 13 桁のサイズコードだけで、それを `sizes[].size_code` として返しています。
- レビューはページに載っている最大 10 件の抜粋(`reviews_sample`)だけです。本文は投稿者が書いたままの文章です。
- `category` に存在しないパスを渡すと NOT_FOUND になります。商品詳細の `breadcrumb` にある URL を使うのが確実です。
- 料金:search、search/suggest、product/availability は 1 回 1 クレジット、product/detail と category は 1 回 2 クレジットです。失敗した呼び出しは課金されません。