ソクミル商品検索APIの使い方|効く並び順・取れる値・PHPコード
- タグ
- API

ソクミルの商品検索API(Item)は、キーワード・カテゴリ・メーカーや出演者のIDで作品を探し、タイトル・価格・パッケージ画像・ダイジェスト画像・サンプル動画の埋め込みURLを返すAPIです。2026年10月17日に試すと、並び順で効いたのは新しい順と価格順だけで、作品の紹介文は今も返ってきませんでした。
試し直していちばん驚いたのは、配信日で絞る条件の名前の、たった1文字の違い。オーナーのコードの「gta_date」は、送っても無視されていました。正しくは gte_date。
このコードは、2023年11月にオーナーが商品検索APIを初めてさわったときに書いたもの。記事担当の伊緒が今のAPIで動かし、条件を1つずつ送り直して、この記事を書き直しています。応答に送ったAPIキーがそのまま入って返ってくることも分かったので、キーを漏らさない作りにしたコードを後半に載せました。
商品検索APIで取れる値
1件の作品につき、商品ID・タイトル・収録時間・作品ページとアフィリエイト用のURL・画像・価格・配信開始日と、メーカー・レーベル・ジャンル・シリーズ・出演者・監督の名前とIDが返ってきます。新しい順で20件取って、項目ごとに値が入っていた件数を数えました。
| 返ってくる値 | 項目名 | 入っていた件数(20件中) |
|---|---|---|
| 商品ID・タイトル・カテゴリ・収録時間 | id・title・category・volume | 20 |
| 作品ページのURL・アフィリエイト用のURL | URL・affiliateURL | 20 |
| パッケージ画像(3サイズ) | imageURL(list・small・large) | 20 |
| 価格と、配信の種類ごとの価格 | prices | 20 |
| 配信開始日 | date | 20 |
| メーカー・レーベル・ジャンル | iteminfo の maker・label・genre | 20 |
| サンプル動画の埋め込みURL | sampleMovieURL | 17 |
| ダイジェスト画像 | sampleImageURL | 16 |
| シリーズ | iteminfo の series | 15 |
| 出演者 | iteminfo の actor | 11 |
| 監督 | iteminfo の director | 5 |
作品の紹介文・レビュー・ランキングの順位は、項目そのものがありません。オーナーが当時「コンテンツは工夫して作らないといけない」と書いたとおり、今も文章は自分で書く前提のAPIです。
値の形にも、いくつかくせがあります。
- 価格(prices の price)は「500~」のように、いちばん安い配信の価格に「~」が付いた文字で返る
- 配信開始日(date)は「2026-10-16T01:00:00.000000Z」のような世界標準時の形。日本時間では、この例は10時
- 配信の種類は「sd-sell」「hd-sell」「hd-rental」のような英語の名前で返る
- メーカーのIDは「v_okuramovie」のように「v_」で始まり、出演者のIDは「tsubakirika」のような読みのローマ字
- 0円の作品などで、パッケージ画像のURLが「/img/…」のように、ドメインの付かない形で返ることがある
効く条件と、効かない条件
条件は、カテゴリ・キーワード・絞り込みの種類とID・配信日・並び順・件数の6つで指定します。2026年10月17日に1つずつ送って、件数と並びが変わるかを確かめました。
| 条件 | 送った値 | 結果 |
|---|---|---|
| カテゴリ(category) | av | 224,023件 |
| idol | 9,257件 | |
| anime | 0件 | |
| キーワード(keyword) | 温泉 | 5,017件 |
| 絞り込み(article と article_id) | maker と v_okuramovie | 479件 |
| actor と tsubakirika | 259件 | |
| 配信日(gte_date と lte_date) | 2024年1月1日〜31日 | 1,784件 |
| 並び順(sort) | date | 新しい順 |
| price | 安い順(0円・100円から) | |
| -price | 高い順 | |
| rank・review など | エラーにならず、新しい順と同じ並びで返った | |
| 件数(hits) | 省く | 30件 |
| 100 | 100件 | |
| 101以上 | 30件に戻った |
並び順に「人気順」や「売上順」が無いのが残念、とオーナーは書いていました。rank や review を送っても新しい順のままなので、今も人気順では並べられません。キーワードは、タイトル・ジャンル名・出演者名に効くようだとオーナーは見ていました。

絞り込みに使うメーカーや出演者のIDは、商品検索の結果の iteminfo に入っています。出演者を名前やプロフィールから探してIDを知りたいときは、出演者検索APIの出番です。
オーナーの2023年のコードを、今のAPIで動かした結果
オーナーのコードは、エンドポイント(APIを呼ぶURL)の転送をたどって動き、20件の作品が返ってきました。ただし、そのまま使うには直したいところがいくつかあります。
| 確かめたこと | 結果 |
|---|---|
| エンドポイント | 新しいURLへ転送された。転送をたどるので、コードは動く |
| 配信日の条件 | gta_date は無視された。gte_date に直すと効く |
| 項目の無い作品 | シリーズ・出演者・監督が無いと、PHP 8で警告が出る |
| アフィリエイト用のURL | www の無い形で返り、開くと「?affi=…」が二重に付いた |
| 応答の request | 送ったAPIキーが、そのままの文字で入って返ってくる |
| 届かないURL | PHPの警告に、APIキーの入ったURLがそのまま出た |
| 20件の速さ | 新しい順で1〜2.3秒。メーカーや出演者で絞ると0.2秒ほど |
表で縮めたところの、細かい数字とURLは次のとおりです。
- エンドポイントは、
https://sokmil-ad.com/api/v1/Itemからhttps://api.sokmil-ad.com/api/v1/Itemへ転送された。file_get_contents は転送をたどる - 配信日は、gta_date のままだと lte_date だけが効いて144,484件。gte_date に直すと1,784件に絞れた
- シリーズ・出演者・監督が無い作品は、項目ごと無いので、繰り返しの処理で警告が出る
- アフィリエイト用のURLは
https://sokmil.com/…の形。www 付きへ転送されるときに、「?affi=…」の部分が後ろに二重に付いた - 応答をまるごと保存すると、APIキーも一緒に残る
- 警告にURLが出たのは、file_get_contents が失敗したときに、警告を表示する設定のサーバー

オーナーは当時「20件取るのもちょっと重い」と書いていました。今も、条件を付けずに新しい順で取ると1秒以上かかります。見る人が開くたびにAPIを呼ばず、結果をためておく作りにしましょう。後半のコードで試すと、APIを呼んだ1回目は2.3秒かかり、ためた結果を読む2回目からは一瞬で表示できました。

キーの扱いは、特に気をつけたいところです。オーナーのコードは結果を保存しないので応答の request は残りませんが、結果をためる作りにするなら、保存する前に request を取り除きます。ためるファイルの置き場所も、共有サーバーの /tmp のような、ほかの人が読めるかもしれない場所は避けましょう。
ソクミルの作品ページはプログラムからのアクセスを止めているため、「?affi=…」が二重になったURLで作品ページがきちんと開くかまでは確かめられませんでした。最初から www 付きのURLにしておけば、転送そのものが起きません。
今のAPIで動くPHPのコード
オーナーのコードをもとに、わたしが手を入れたものです。2026年10月17日に動かして、20件の作品とクレジットが警告なしで表示されること、配信日の条件で件数が絞れることを確かめました。届かないURLに向けたときに画面へキーが出ないことと、ためたファイルにキーが入らないことも確かめています。
- エンドポイントを api.sokmil-ad.com にした
- 配信日の条件の名前を gte_date に直し、空の条件は送らないようにした
- APIに届かなかったときも警告を出さず、決まった文を出すようにした(警告にAPIキーの入ったURLが出るため)
- シリーズ・出演者・監督・ダイジェスト画像・サンプル動画は、無い作品では出さないようにした
- アフィリエイト用のURLを www 付きに直し、ドメインの無い画像のURLを補った
- 同じ条件の結果を1時間ためておくようにした。保存する前に request(送ったAPIキー入り)を取り除き、公開フォルダの外に、自分だけが読める設定(0600)で置く

<?php
// ソクミルの商品検索APIで、作品の一覧を表示する
$params = [
'api_key' => 'あなたのAPIキー',
'affiliate_id' => 'あなたのアフィリエイトID',
'output' => 'json',
'hits' => 20, // 1〜100件(省くと30件)
'offset' => 1,
'sort' => 'date', // date(新しい順)・price(安い順)・-price(高い順)
'category' => 'av', // av か idol
'keyword' => '',
'article' => '', // maker・label・genre・actor・series・director で絞るとき
'article_id' => '', // その ID(v_okuramovie など)
'gte_date' => '', // 配信日の始まり(2024-01-01T00:00:00 の形)
'lte_date' => '', // 配信日の終わり
];
$url = 'https://api.sokmil-ad.com/api/v1/Item?' . http_build_query(array_filter($params, fn($v) => $v !== ''));
// APIを呼ぶ。失敗しても警告は出さない(警告にはAPIキーの入ったURLが出るため)
function api_get($url) {
$ctx = stream_context_create(['http' => ['timeout' => 10, 'ignore_errors' => true]]);
$body = @file_get_contents($url, false, $ctx);
$data = $body === false ? null : json_decode($body, true);
return is_array($data) ? $data : null;
}
// 同じ条件の結果は1時間ためておく
// 置き場所は公開フォルダの外(このファイルを public_html の直下に置くなら、その1つ上)
$cacheDir = dirname(__DIR__) . '/api-cache';
$cache = $cacheDir . '/sokmil_item_' . md5($url) . '.json';
if (is_file($cache) && filemtime($cache) > time() - 3600) {
$data = json_decode((string) file_get_contents($cache), true);
} else {
$data = api_get($url);
if (isset($data['result']['items'])) {
unset($data['request']); // 応答には送ったAPIキーがそのまま入っているので、保存しない
if (!is_dir($cacheDir)) @mkdir($cacheDir, 0700, true);
if (@file_put_contents($cache, json_encode($data, JSON_UNESCAPED_UNICODE)) !== false) @chmod($cache, 0600);
}
}
$items = $data['result']['items'] ?? [];
function h($s) { return htmlspecialchars((string) $s, ENT_QUOTES, 'UTF-8'); }
// リンクは www 付きにする(www の無いURLは転送のときに後ろが二重になる)
function sokmil_link($u) { return preg_replace('#^https://sokmil\.com/#', 'https://www.sokmil.com/', $u); }
// 画像のURLが「/img/…」で返る作品がある
function sokmil_img($u) { return str_starts_with($u, '/') ? 'https://www.sokmil.com' . $u : $u; }
// 名前の一覧(シリーズ・出演者・監督は無い作品がある)
function names($list) { return implode('、', array_map(fn($x) => h($x['name']), $list ?? [])); }
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SOKMIL API ITEM</title>
</head>
<body>
<?php if (!isset($data['result']['items'])) : ?>
<p>作品を読み込めませんでした。時間をおいて開き直してください。</p>
<?php else : ?>
<p>全<?= number_format((int) $data['result']['total_count']) ?>件</p>
<?php endif; ?>
<?php foreach ($items as $row) : $info = $row['iteminfo']; ?>
<section>
<h2><a href="<?= h(sokmil_link($row['affiliateURL'])) ?>" rel="sponsored"><?= h($row['title']) ?></a></h2>
<p>収録時間 <?= h($row['volume']) ?> / 価格 <?= h(str_replace('~', '円〜', $row['prices']['price'])) ?> / 配信開始日 <?= h(substr($row['date'], 0, 10)) ?></p>
<p>メーカー <?= names($info['maker'] ?? null) ?> / レーベル <?= names($info['label'] ?? null) ?></p>
<?php if (!empty($info['series'])) : ?><p>シリーズ <?= names($info['series']) ?></p><?php endif; ?>
<?php if (!empty($info['actor'])) : ?><p>出演者 <?= names($info['actor']) ?></p><?php endif; ?>
<?php if (!empty($info['director'])) : ?><p>監督 <?= names($info['director']) ?></p><?php endif; ?>
<p>ジャンル <?= names($info['genre'] ?? null) ?></p>
<img src="<?= h(sokmil_img($row['imageURL']['large'])) ?>" alt="" loading="lazy">
<?php if (!empty($row['sampleImageURL']['image'])) : ?>
<div>
<?php foreach ($row['sampleImageURL']['image'] as $thumb) : ?>
<img src="<?= h($thumb) ?>" alt="" loading="lazy">
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (!empty($row['sampleMovieURL']['url'])) : ?>
<iframe src="<?= h($row['sampleMovieURL']['url']) ?>" style="border:0; width:100%; aspect-ratio:16/9;" loading="lazy"></iframe>
<?php endif; ?>
</section>
<hr>
<?php endforeach; ?>
<a href="https://sokmil-ad.com/" target="_blank" rel="nofollow"><img src="https://sokmil-ad.com/api/credit/88x31.gif" alt="WEB SERVICE BY SOKMIL" width="88" height="31"></a>
</body>
</html>
「あなたのAPIキー」「あなたのアフィリエイトID」を自分のものに書き換えて、PHP 8.0以上が動くサーバーに上げます。結果をためるフォルダ(api-cache)は、このファイルを置いたフォルダの1つ上にできるので、public_html より深い場所に置くときは $cacheDir を公開されない場所に書き換えてください。いちばん下のクレジット「WEB SERVICE BY SOKMIL」は、オーナーのコードにあったものをそのまま残しています。
よくある質問
作品の紹介文(あらすじ)は取れる?
取れません。2026年10月17日の応答にも、紹介文の項目はありませんでした。作品ページへのリンクに添える文章は、自分で書くことになります。
人気順やレビュー順で並べられる?
並べられません。rank・review などを送ってもエラーにはならず、新しい順と同じ並びで返ってきます。効いた並び順は、新しい順(date)・安い順(price)・高い順(-price)の3つだけでした。
アニメの作品は取れる?
category に anime を入れると、0件でした。カテゴリを省くと233,280件が返り、これはAVとアイドルの件数を足した数と同じです。AVのカテゴリの中でキーワードに「アニメ」と入れると、403件見つかりました。
100件より多く取るには?
offset を101、201……とずらして、何回かに分けて呼びます。offset に1と101を送ると、100件ずつ重なりなく続けて返ってきました。応答の first_position は、offset を省くと1ですが、offset を送ると送った値より1大きい数で返ってきました(1を送ると2、101を送ると102)。次のページの位置は、自分が送った値から計算します。
キーワードやメーカーで絞ったときに何が返ってくるかは、SOKMIL 商品検索のツールで、コードを書く前に試せます。
この記事で作ったAPIは、ツールで試せます
キーワードや条件を変えて、APIが返す実際のデータを確かめられます。



