GET /v1/query の1本。resource パラメータで取得するデータを切り替えます。このページを AI コーディングエージェントに読ませれば、そのまま組み込み実装に使えます。データ取得はすべてこの1つの形です。URL は1本、resource でデータの種類を選び、残りのパラメータで内容をコントロールします。
GET https://<BASE_URL>/v1/query?resource=<リソース名>&<パラメータ...>
X-API-Key: kwk_あなたのキー
| 項目 | 内容 |
|---|---|
| ベース URL | https://<BASE_URL>(ブラウザでこのページを開いていれば実 URL に置換済み)。以下、コード例では BASE と表記 |
| 形式 | JSON(UTF-8)。レスポンスの形は resource ごとに決まっています(→ 3.4) |
| 認証 | 全リクエストにヘッダー X-API-Key: kwk_...(発行手順は 2章。ダッシュボード用の gwk_ キーも同じヘッダーで使用可)。ヘッダーを付けられない環境のみ ?key=kwk_... でも可(URL にキーが残る点に注意) |
| POST 版 | 同じ内容を POST /v1/query に {"resource": "...", "params": {...}} として送ることもできます(パラメータが多い・ログに残したくない場合向け) |
| 日本語パラメータ | 市場名などの日本語は URL エンコード必須。curl は自動エンコードしないため -G --data-urlencode を使う(例は各所に記載) |
| データ更新 | 週次更新。同一週内は同じ結果が返るため、取得結果のキャッシュを推奨(キー例: 市場名 + weekEnd) |
| エラー形式 | {"detail": "..."} + HTTP ステータス(→ 3.5) |
| 課金対象 | 成功したデータ取得コール(HTTP 2xx)のみ。/v1/query は 1 リクエスト = 1 コール(内部転送の二重計上なし)。エラー応答・キー管理・使用量照会は非課金(→ 5章) |
# curl(日本語パラメータは -G + --data-urlencode でエンコードする)
curl -sG "https://<BASE_URL>/v1/query" \
-H "X-API-Key: $KW_API_KEY" \
--data-urlencode "resource=market.report" \
--data-urlencode "name=旅行"
# Python(httpx。requests でも同じ書き方)
import os, httpx
BASE = "https://<BASE_URL>"
H = {"X-API-Key": os.environ["KW_API_KEY"]}
def q(resource, **params):
r = httpx.get(BASE + "/v1/query", params={"resource": resource, **params},
headers=H, timeout=60)
r.raise_for_status()
return r.json()
report = q("market.report", name="旅行")
// Node.js(追加ライブラリ不要の fetch)
const BASE = "https://<BASE_URL>";
const H = { "X-API-Key": process.env.KW_API_KEY };
const q = async (resource, params = {}) => {
const url = new URL(BASE + "/v1/query");
url.searchParams.set("resource", resource);
Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
const r = await fetch(url, { headers: H });
if (!r.ok) throw new Error(`${r.status} ${await r.text()}`);
return r.json();
};
const report = await q("market.report", { name: "旅行" });
// Google Apps Script(UrlFetchApp)
function kwQuery(resource, params) {
const KEY = PropertiesService.getScriptProperties().getProperty("KW_API_KEY");
const qs = Object.entries(Object.assign({ resource: resource }, params || {}))
.map(([k, v]) => k + "=" + encodeURIComponent(v)).join("&");
const r = UrlFetchApp.fetch("https://<BASE_URL>/v1/query?" + qs,
{ headers: { "X-API-Key": KEY }, muteHttpExceptions: true });
if (r.getResponseCode() !== 200) throw new Error(r.getContentText());
return JSON.parse(r.getContentText());
}
以降の resource 詳細では、この q() ヘルパー(Python 版)を使った1行例を併記します。
この API の代表的な使い方(記事制作・SEO 対策への組み込み)を1本のコードにした標準フローです。すべて q() 1つで書けます。個々の resource の意味はこの後の詳細を参照してください。
import os, time, httpx
BASE = os.environ["KW_BASE_URL"] # 例: https://<BASE_URL>
H = {"X-API-Key": os.environ["KW_API_KEY"]} # kwk_...
def q(resource, **params):
r = httpx.get(BASE + "/v1/query", params={"resource": resource, **params},
headers=H, timeout=60)
r.raise_for_status()
return r.json()
# ① 注目市場を取り込む(searchConditionId は分析結果とセットで保存する)
market = q("myMarkets.groupMarkets", groupId=-1)["markets"][0]
sc_id, query = market["searchConditionId"], "ハワイ旅行"
# ② 分析の有無を確認 → 無ければ開始(1日の回数上限あり: over_limit)
st = q("contentAnalysis.status", marketId=sc_id, query=query)
if st["status"] == "not_analyzed":
res = q("contentAnalysis.request", marketId=sc_id, query=query) # 分析開始
if not res["accepted"]:
raise RuntimeError(f"analysis not accepted: {res['result']}")
while st["status"] != "researched": # 完了まで通常10〜20分(空いていれば1分程度)
time.sleep(20)
st = q("contentAnalysis.status", marketId=sc_id, query=query)
# ③ 重要形態素(業界特有度キーワード)
kw = q("contentAnalysis.keywords", fileId=st["fileId"], minSites=6, limit=100)
# ④ 競合情報(上位ページのスコア・見出し / 市場レベルの順位・推定流入)
pages = q("contentAnalysis.detail", fileId=st["fileId"])["pages"]
sites = q("market.report", name=market["name"])["sites"]
| 項目 | 内容 |
|---|---|
| scId の世代 | 分析データはリクエスト時の searchConditionId(scId = marketId)に紐づきます。市場の scId は調査世代で変わるため、request に使った scId を分析結果とセットで保存し、status 照会は必ず同じ scId で行ってください。過去に分析済みのクエリは、分析済み一覧(contentAnalysis.files)の各行の searchConditionId で照合できます |
| 回数上限 | 分析リクエストには1日あたりの回数上限があります。result: "over_limit" をハンドリングし、翌日リトライやキュー化を推奨 |
| 所要時間 | 分析は非同期で通常10〜20分(空いていれば1分程度)。同期待ちにせず、10〜30秒間隔のポーリングで待ってください |
| 表示期限 | 分析結果には期限があります(validUntil ≒ 分析日 + 28日)。期限後は再分析が必要です |
| 対策キーワードの選び方 | ②の query は自由入力です。市場の全クエリ(market.queries)から検索ボリュームを見て選ぶのが定石です |
| request と GET | contentAnalysis.request は分析を開始する状態変更の操作です。上の例のように GET でも実行されますが、意図しない再実行を避けたい場合は POST /v1/query を使ってください |
機械可読の一覧は GET /v1/query/resources(認証不要)で取得できます。
| resource | 内容 | 主なパラメータ |
|---|---|---|
| calendar.latestWeek | 最新の有効調査週 | ─ |
| market.search | キーワード(完全一致)から市場を検索 | queries, weekEnd? |
| market.report | マーケットレポート一括取得(全クエリ + 上位サイト + クエリ別順位) | name, weekEnd?, sites? |
| market.queries | 市場の全クエリと検索ボリューム(軽量版) | name, weekEnd? |
| market.segments | カテゴリ別クエリ内訳(セグメント) | marketId, plan? |
| market.segmentPlans | セグメント計画一覧(カスタム分類含む) | marketId |
| myMarkets.groups | 注目市場グループ一覧 | ─ |
| myMarkets.groupMarkets | グループ内の市場一覧(groupId=-1 で全グループ横断) | groupId, weekEnd? |
| myMarkets.home | ホームに設定された注目市場 | ─ |
| mySites.list / mySites.tags | 注目サイト一覧 / タグセット | ─ |
| projects.list / projects.detail / projects.markets | プロジェクト一覧 / 詳細 / 所属市場 | projectId(detail, markets) |
| contentAnalysis.files | コンテンツ分析済み一覧 | marketId?, projectId? |
| contentAnalysis.status | 分析の有無・進行状態 | marketId, query |
| contentAnalysis.request | コンテンツ分析の開始(非同期・状態変更) | marketId, query, ほか任意 |
| contentAnalysis.detail | 分析詳細(上位ページの競合情報) | fileId, projectId? |
| contentAnalysis.characters | ページ特性(見出し構造等) | fileId, projectId? |
| contentAnalysis.keywords | 業界特有度キーワード(重要形態素) | fileId, minSites?, minIndustryScore?, limit? |
| insights.weekly | 週次インサイト(前週比較 + AI 日本語要約) | name, weekEnd?, sites? |
| gateway.me | ログイン中アカウントの情報 | ─ |
resource 化されていない補助エンドポイント(疎通確認 /health、使用量 /v1/usage、CSV 出力 /v1/export/csv)は 3.4 末尾と 3.7 にまとめています。
データが存在する最新の調査週を返します。weekEnd を明示指定したい場合や、週が切り替わったかの判定に使います。キー発行後の疎通確認にも最適です。
q("calendar.latestWeek")
# → {"weekEnd": "2026-07-04"}
キーワード(完全一致)から市場を検索し、市場の基本情報と ID を返します。
| パラメータ | 必須 | 説明 |
|---|---|---|
| queries | ✅ | 検索語(完全一致)。複数指定可(queries=A&queries=B のように同名パラメータを繰り返す) |
| weekEnd | - | 調査週の終了日 YYYY-MM-DD。省略時は最新の有効調査週 |
q("market.search", queries="旅行")
{
"markets": [
{
"id": "sc-1001", // 市場ID。segments 等の marketId に使う
"name": "旅行",
"type": "generated", // generated=自動生成 / user_defined=ユーザー定義
"volume": 12345, // 検索ボリューム
"economicScale": 99, // 経済規模スコア
"economicRank": 3, // 経済規模ランク
"queryCount": 321, // 構成クエリ数
"weekEnd": "2026-07-04"
}
]
}
ヒットしない場合は {"markets": []}(404 にはなりません)。
市場名から構成クエリ(検索ボリューム付き)・上位サイトの流入ランクと推計流入数・サイトごとのクエリ別順位をまとめて返します。「市場名を入れたら全部返ってくる」用途はまずこれを使ってください。
| パラメータ | 必須 | 説明 |
|---|---|---|
| name | ✅ | 市場名(完全一致・日本語は URL エンコード) |
| weekEnd | - | 調査週 YYYY-MM-DD。省略時は最新週 |
| sites | - | 上位サイト数(1〜100、デフォルト 20) |
q("market.report", name="旅行")
{
"market": { "id": "sc-1001", "name": "旅行", ... }, // market.search と同形
"weekEnd": "2026-07-04",
"queries": [ // 市場の全クエリ。ボリューム降順・重複なし
{"query": "ハワイ旅行", "volume": 12000, "economicScale": 42.0},
{"query": "ハワイ旅行 費用", "volume": 6600, "economicScale": 30.5}
],
"sites": [ // 上位サイト。流入ランク順(rank は 1 始まり)
{
"rank": 1,
"domain": "tabi-navi.jp",
"title": "たびナビ | ハワイ旅行・ツアー",
"flowScore": 88.5,
"flowRate": 24.1, // 流入率 %
"estClicks": 5200.0, // 推計流入数(クリック数)
"shareRate": 18.2, // シェア %
"queryRanks": [ // このサイトのクエリ別順位(rank 昇順)
{"query": "ハワイ旅行", "rank": 1, "estClicks": 3840.0}
]
}
],
"warnings": [] // 部分成功時に理由が入る(エラーではない)
}
queryRanks に圏外のクエリは含まれません。順位データが存在するのはランキングチャート掲載クエリのみですqueries はチャート掲載分のみに縮退し warnings に理由が入ります{"detail": "market not found: {name}"}市場の全クエリと検索ボリュームだけを返す軽量版。対策キーワードの選定に使います。パラメータは name(必須)と weekEnd(任意)。
q("market.queries", name="旅行")
# → {"market": {...}, "weekEnd": "2026-07-04",
# "queries": [{"query": "...", "volume": 12000, "economicScale": 42.0}, ...]}
queries の母集合は market.report の queries と同一(重複なし・ボリューム降順)。該当なしは同じく 404。
市場内のクエリをカテゴリ(例: ブランド、エリア)別に集計して返します。「この市場はどんな関心で構成されているか」を見る用途です。
| パラメータ | 必須 | 説明 |
|---|---|---|
| marketId | ✅ | 市場 ID(market.search の id) |
| plan | - | セグメントプランのキー。デフォルト machine(自動分類)。カスタム分類は market.segmentPlans で取得した planId を渡す |
q("market.segments", marketId="sc-1001")
# → {"categories": [
# {"name": "エリア", "alias": "area", "queryCount": 2, "volume": 2300,
# "share": 60.5, // 市場全体ボリュームに対する %
# "topQueries": ["ハワイ旅行", ...], // 上位5クエリ
# "allQueries": [{"query": "...", "volume": 2000}, ...]} // 全クエリ(降順)
# ],
# "totalVolume": 3800}
市場のセグメント計画一覧(カスタム分類を含む)。パラメータは marketId(必須)。得た planId を market.segments の plan に渡します。
ログインアカウントの「注目市場」。常に認証アカウント自身のデータが返ります(他人のデータは見えません)。
| resource | 内容 | パラメータ |
|---|---|---|
| myMarkets.groups | 注目市場グループ一覧 | ─ |
| myMarkets.groupMarkets | グループ内の市場一覧。groupId=-1 で全グループ横断 | groupId(必須), weekEnd? |
| myMarkets.home | ホームに設定された注目市場 | ─ |
q("myMarkets.groupMarkets", groupId=-1)["markets"]
# 各要素: {"name": 市場名, "searchConditionId": 市場ID(scId), "volume": ..., "wordCount": ...}
# searchConditionId はコンテンツ分析の marketId に使う(標準フロー①参照)
| resource | 内容 | パラメータ |
|---|---|---|
| mySites.list | 注目サイト(登録済み監視ドメイン)一覧 | ─ |
| mySites.tags | 注目サイトのタグセット | ─ |
| projects.list | 参加プロジェクト一覧 | ─ |
| projects.detail / projects.markets | プロジェクト詳細 / 所属市場(権限外は 403) | projectId(必須) |
これらのレスポンスは現状 kwtool 内部の形式のまま返しています(パススルー)。フィールド構成を整える改訂を予定しており、変更時は事前に告知します。
コンテンツ分析済みファイルの一覧。過去に分析したクエリの fileId と scId の照合に使います。marketId / projectId(いずれも任意)で絞り込み可能。
q("contentAnalysis.files")
# → {"files": [...], "result": "ok"} ※配列は files キーの中
# 各行の主なフィールド:
# searchWord 対策キーワード
# searchConditionId その分析に使われた市場ID(scId)
# contentsAnalysisFileId fileId(詳細・キーワード取得に使う)
# status "researched"=完了 / "rank_researching"=調査中
# researchDate, validUntil(表示期限)
linkAnalysisStatus は別機能「複ページ分析(リンク分析)」の状態で、コンテンツ分析の完了とは無関係です("未分析" でも status が researched ならコンテンツ分析は使えます)。市場ID + クエリで分析データの有無を確認します。未分析でもエラーにならず 200 で返ります。
| パラメータ | 必須 | 説明 |
|---|---|---|
| marketId | ✅ | 市場 ID(scId)。分析リクエスト時に使った scId と同じものを指定する |
| query | ✅ | 対策キーワード |
q("contentAnalysis.status", marketId=sc_id, query="ハワイ旅行")
# 分析済み:
# {"marketId": "62ac...", "query": "ハワイ旅行", "status": "researched",
# "fileId": 74420, "requestDate": "2026-07-10", "researchDate": "2026-07-10 14:07:49",
# "validUntil": "2026-08-07", "searchLocation": "日本全域"}
# 未分析:
# {"marketId": "62ac...", "query": "未分析ワード", "status": "not_analyzed", "fileId": null}
| status | 意味 |
|---|---|
| not_analyzed | 分析データなし(→ contentAnalysis.request で開始できる) |
| rank_researching 等 | 分析実行中(→ ポーリング継続) |
| researched | 完了。fileId を詳細・キーワード取得に使える |
未分析クエリのコンテンツ分析を開始します(kwtool 画面の「調査リクエスト」と同一の処理)。非同期・状態変更の操作で、完了は contentAnalysis.status のポーリングで確認します。
| パラメータ | 必須 | 説明 |
|---|---|---|
| marketId | ✅ | 市場 ID(scId)。この値を分析結果とセットで保存する |
| query | ✅ | 対策キーワード |
| targetPagesCount | - | 参照する上位ページ数(既定 10) |
| locationId | - | 検索地域(既定 1 = 日本全域) |
| optionalTargets | - | 自サイト等の追加 URL 配列 |
| projectId | - | プロジェクト単位で分析する場合に指定 |
| originalText | - | 自前原稿の本文。指定すると上位ページと合わせて分析対象に含まれ、公開前原稿のコンテンツ力計測に使える |
| originalTextFileName | - | originalText に付けるファイル名ラベル(例: draft.txt) |
# GET でも実行できるが、状態変更なので POST 版を推奨
curl -s -X POST "https://<BASE_URL>/v1/query" \
-H "X-API-Key: $KW_API_KEY" -H "Content-Type: application/json" \
-d '{"resource": "contentAnalysis.request",
"params": {"marketId": "62ac...", "query": "ハワイ旅行"}}'
{"marketId": "...", "query": "...", "accepted": true, "result": "ok"}
{"marketId": "...", "query": "...", "accepted": false, "result": "over_limit"}
over_limit = 1日の分析リクエスト回数上限を超過。翌日以降に再実行してくださいvalidUntil(≒ 分析日 + 28日)。期限後は再分析が必要です分析詳細。pages に検索上位ページ(既定10件)の競合情報が入ります。パラメータは fileId(必須)と projectId(任意)。
detail = q("contentAnalysis.detail", fileId=file_id)
for page in detail["pages"]:
# url, contentsScore(コンテンツ), portalScore(ポータル度), uniqueScore(独自性),
# purity, contents(見出し・本文構造) など
print(page["url"], page["contentsScore"], page["portalScore"], page["uniqueScore"])
ページ特性(見出し構造・形態素など)の分析結果。パラメータは fileId(必須)と projectId(任意)。detail と同じくパススルーのため、同様の注意が当てはまります。
分析結果から「検索上位ページが多く含む、業界特有度の高いキーワード(重要形態素)」を特有度降順で返します。記事制作の対策語選定に使います。
| パラメータ | 既定 | 説明 |
|---|---|---|
| fileId | 必須 | 分析済みファイルの ID |
| minSites | 1 | 上位ページのうち何サイト以上に出現する語に絞るか(推奨: 必須語=6、推奨語=3) |
| minIndustryScore | 0 | 業界特有度の下限 |
| limit | 100 | 返す語数の上限(最大3000) |
q("contentAnalysis.keywords", fileId=file_id, minSites=6, limit=100)
# → {"fileId": "74420", "query": "ハワイ旅行", "researchedDate": "2026-07-10 14:07:49",
# "pageCount": 10, "totalTerms": 2322, "matchedTerms": 136,
# "keywords": [
# {"term": "オアフ島",
# "industryScore": 3.861, // 業界特有度(高いほど対策価値が高い)
# "generalScore": 0.013, // 一般度(日常語ほど高い。専門語・ブランド名はほぼ0)
# "siteCount": 9, // 上位 pageCount ページ中、何サイトに出現したか
# "occurrences": 109} // 上位ページ全体での総出現回数
# ]}
市場の週次インサイト。今週と前週のマーケットレポート差分をサーバー側で集計し、AI(Claude)が3〜5行の日本語要約を生成します。
| パラメータ | 必須 | 説明 |
|---|---|---|
| name | ✅ | 市場名(完全一致) |
| weekEnd | - | 省略で最新週 |
| sites | - | 上位サイト数(1〜100、既定 20) |
q("insights.weekly", name="旅行")
# → {"summary": "AI による日本語要約(3〜5行)",
# "changes": {...}, // 差分の生データ(順位変動・新規参入・ボリューム変化)
# "warnings": [...]} // 前週データが無い週はスナップショット要約に縮退
AI には集計済みダイジェストのみが送信されます(全クエリ順位等の生データは送りません)。
いま認証しているアカウントの情報(アカウント名・権限など)。キーがどのアカウントとして動いているかの確認に使います。
認証不要。死活監視用。
curl -s "https://<BASE_URL>/health"
# → {"status": "ok", "version": "0.1.0"}
| パラメータ | 既定 | 説明 |
|---|---|---|
| granularity | day | day / week / month(推移の単位) |
| limit | - | 返すバケット数(1〜120) |
| from / to | - | 期間 YYYY-MM-DD(to は含む) |
curl -sG "https://<BASE_URL>/v1/usage" -H "X-API-Key: $KW_API_KEY" \
--data-urlencode "granularity=month"
# → {"account": "...", "buckets": [...], "today": 12, "thisWeek": 80, "thisMonth": 300,
# "todayMb": 1.2, "thisWeekMb": 8.0, "thisMonthMb": 30.5,
# "currentMonth": {"period": "2026-07", "billing": {...}}, // 定額+超過従量の内訳
# "pricing": {...}}
スプレッドシート(IMPORTDATA)・BI ツール向けの CSV 出力。resource の指定方法は /v1/query と同じです。
| パラメータ | 説明 |
|---|---|
| resource | データ種別。market.report(既定) / market.queries |
| table | 出力表。sites(上位サイト・既定) / queries(全クエリ) / queryRanks(サイト×クエリ順位の縦持ち) |
| name 等 | resource のパラメータをそのまま渡す |
| key | ヘッダーを付けられない場合のキー指定(?key=kwk_...)。URL にキーが残る点に注意 |
https://<BASE_URL>/v1/export/csv?resource=market.report&name=市場名&table=sites&key=kwk_...
エラーは {"detail": "..."} 形式(FastAPI 標準)で返ります。バリデーションエラー(422)のみ detail が配列になり、不正フィールドの位置と理由が入ります。
| ステータス | 代表的な detail | 意味と対処 |
|---|---|---|
| 400 | unknown resource: ◯◯ | resource 名の誤り。レスポンスの available に正しい一覧が入っている |
| 400 | missing required params: [...] | その resource の必須パラメータ(marketId, fileId 等)が不足 |
| 401 | invalid api key / invalid gateway key | キーの値が誤っているか失効済み。ダッシュボードで再発行 |
| 401 | upstream login failed | kwtool のパスワード変更等でキー内の認証情報が古い。再ログインしてキーを再発行 |
| 403 | api key plan does not permit resource '...' | キーのプランにその resource の権限が無い(requiredScope に必要スコープ)。管理者にプラン変更を相談 |
| 403 | API の利用には管理者による利用許可が必要です | アカウントに API 利用許可が未登録。サポートチームに問い合わせ |
| 403 | (プロジェクト等) | そのデータへの権限がアカウントに無い |
| 404 | market not found: ◯◯ | 市場名の完全一致に該当なし。表記(スペース・カタカナ)を確認 |
| 422 | (配列) | パラメータ不足・形式誤り。detail の loc / msg を確認 |
| 429 | rate limit exceeded | 分単位のレート制限超過。Retry-After ヘッダーを尊重して待つ |
| 429 | monthly quota exceeded | キーの月間上限に到達。翌月まで待つか管理者に上限変更を相談 |
| 502 | upstream kw-cms error | kwtool 側のエラー。多くは「その市場・週にデータが無い」。週を変えるか時間を置いて再試行 |
Retry-After を尊重し、直列・低頻度アクセスにしてくださいweekEnd に無効な週を指定した場合の挙動は上流依存です。calendar.latestWeek で有効週を確認してください/llms.txt ↗(別タブで開きます)は、この API の仕様をプレーンテキスト1枚に要約したファイルです。Claude Code 等の AI コーディングツールに URL を渡して読ませる用途です(→ 具体的な指示例)。より詳しい仕様が必要な場合は本ページを読ませてください。
/docs は、OpenAPI 定義から自動生成される API 一覧画面(Swagger UI)です。公開エンドポイント(/v1/query と補助エンドポイント)のパラメータ・レスポンス型を機械的に確認できます。ブラウザから実行を試す場合は、認証ヘッダーの設定が不要なダッシュボードの方が簡単です。
POST /v1/agent body: {"message": "日本語の要望", "allowActions": false}
# → {"answer": "...", "actions": [...], "needsConfirmation": ..., "llm": {...}}
サーバー側の AI が適切な resource を組み立てて実行し、日本語で回答します。分析開始などの状態変更は allowActions=true のときのみ実行され、省略時は提案として返ります。
問い合わせ: kw-platform-api 管理者まで。 ← ダッシュボードへ戻る