GET /v1/query の1本。resource パラメータで取得するデータを切り替えます。AI アプリにコードを書かせる場合は、まず /llms.txt(要約)を読ませ、詳しい仕様が要るときにこのページを読ませます。データ取得はすべてこの1つの形です。URL は1本、resource でデータの種類を選び、残りのパラメータで内容をコントロールします。
GET https://api.kwtool-ai.com/v1/query?resource=<リソース名>&<パラメータ...>
X-API-Key: kwk_あなたのキー
キーを発行したら(→ 2章)、まずこの 1 本で疎通を確認します。パラメータは不要で、最新の調査週が返れば成功です。市場名を渡す例は下の呼び出し例にあります。
curl -s "https://api.kwtool-ai.com/v1/query?resource=calendar.latestWeek" \
-H "X-API-Key: kwk_あなたのキー"
# → {"weekEnd": "YYYY-MM-DD"} (最新の調査週の終了日)
本ページのコード例・応答例に出てくる用語と ID の対応です。同じものが resource によって別の名前で返ることがあるので、迷ったらここに戻ってください。
| 用語 / フィールド | 意味 |
|---|---|
| 注目市場 | kwtool の My マーケットに登録した市場。一覧は myMarkets.groupMarkets で取得します。 ご契約区分によっては、市場の詳細を取得できるのはここに登録した市場だけです(→ 3.6 データ範囲) |
市場 IDsearchConditionId / scId / marketId | 市場を指す ID。market.search の id、myMarkets の searchConditionId、各 resource のパラメータ marketId はすべて同一の IDです(本ページの例では "sc-1001")。市場の調査世代で変わることがあるため、分析の依頼に使った値は結果とセットで保存します |
fileId | コンテンツ分析の結果 1 件の ID(contentAnalysis.status の fileId、contentAnalysis.files の contentsAnalysisFileId)。依頼時の市場 ID に紐づくので、結果は依頼に使った市場 ID で照会します。detail / keywords / linkAnalysis に渡します。型は resource で違います: status / files では数値(例 74420)、keywords / linkAnalysis / linkRequest の応答では文字列("74420")。パラメータにはどちらを渡しても同じです |
対策クエリ(query) | コンテンツ分析の対象にする検索クエリ。市場の全クエリ(market.queries)から検索ボリュームを見て選ぶのが定石です |
weekEnd | 調査週の終了日(YYYY-MM-DD)。データは週次更新で、省略すると最新の有効週になります。最新週は市場ごとに違うことがあり、calendar.latestWeek / market.validWeeks で確認できます |
economicRank | 経済規模の順位(金額ではありません。1 位 = 最大、数字が小さいほど経済規模が大きい)。市場単位は全市場中の順位、市場内クエリはその市場内の順位です。myMarkets の応答では marketScale という名前で同じ値が返ります。金額のフィールドは本 API にはありません |
estClicks | 推計流入数/月 = 検索ボリューム(volume)× 流入率(flowRate %)。実測のアクセス数ではありません。flowScore は同じ値の旧名(非推奨)、market.reach では estInflow です |
flowRate / shareRate | 流入率 % / シェア %(market.report・rankChart・urlChart)。market.reach では流入率が sharePercent という名前で返ります |
| 重要形態素 | 検索上位ページが多く含む、業界特有度の高いキーワード(業界特有度キーワード)。contentAnalysis.keywords で取得し、記事制作の対策語の選定に使います |
| コンテンツ分析 | 対策クエリの検索上位ページを分析し、コンテンツ力(スコア)と重要形態素を出す機能(= コンテンツ力分析)。単ページ分析(ページ単体のコンテンツ力。contentAnalysis.request で投入)と複ページ分析(内部リンクで繋がるページ群を合算。contentAnalysis.linkRequest で投入)の 2 種類があり、本ページで単に「コンテンツ分析」と書いた場合は単ページ分析を指します |
プロジェクト(projectId) | kwtool のプロジェクト。市場のブックマーク(projects.marketBookmark)・名前付きターゲット計画・プロジェクト単位のコンテンツ分析をまとめる単位で、参加しているプロジェクトだけが見えます。ID は projects.list の projects[].id |
| ご契約区分 | お客様の契約の種別で、KWTOOL 契約連動(connected)/ データ提供契約(managed)/ 体験版(trial)の 3 つです(区分ごとに使える範囲は 1 章の表)。区分によって変わるもの:
取得できる市場の範囲(→ 3.6 データ範囲)、
分析の投入上限(→ 3.6 分析投入の 1 日あたり上限)、
分析一覧(contentAnalysis.files)の可視範囲(データ提供契約では自分が依頼した分析だけ)。403 の role にはこのコードが入ります
|
| 項目 | 内容 |
|---|---|
| ベース URL | https://api.kwtool-ai.com。Python / Node の例では BASE と表記 |
| 形式 | JSON(UTF-8)。レスポンスの形は resource ごとに決まっています(→ 3.4) |
| 認証(これだけ) | 全リクエストにヘッダー X-API-Key: kwk_...(Authorization: Bearer kwk_... でも可)。キーはダッシュボードの API キー 画面で発行します(→ 2章) |
?key= と gwk_(原則使わない) | ?key=kwk_... は、ヘッダーを付けられない環境(スプレッドシートの IMPORTDATA 等)だけで使います(URL にキーが残る点に注意)。ヘッダーと ?key= などで異なるキーを同時に送ると 400(reason: credential_conflict)。ダッシュボードのログインセッション(gwk_)は画面用で、有効期限は 24 時間(初回ログインから最長 168 時間、ログアウトで失効)。プログラム連携には使いません |
| 使える URL | API キー(kwk_)で呼べるのは /v1/query(GET / POST)・/v1/query/resources・/v1/export/csv・/v1/usage です。それ以外の /v1/... を直接呼ぶと 403(→ 3.5) |
| POST 版 | 同じ内容を POST /v1/query に {"resource": "...", "params": {...}} として送ることもできます(パラメータが多い・ログに残したくない・状態を変える操作の場合向け)。key / token などの認証用の名前は params に入れられません(400) |
| 日本語パラメータ | 市場名などの日本語は URL エンコード必須。curl は自動エンコードしないため -G --data-urlencode を使う(例は各所に記載) |
| 件数パラメータ | limit / sites / weeks / queries(件数)などの件数系パラメータに固定の最大値はありません(下限は 1)。管理者が上限を設定している場合、上限を超えた値はエラーにならず上限まで切り詰められます。既定値は resource ごとに異なります(例: limit は resource により 20 または 100。各 resource の説明を参照) |
| データ範囲 | ご契約区分によっては、市場の詳細(ドリルダウン)を取得できるのが注目市場に登録した市場だけになります(一覧・検索・逆引きは制限なし)。対象 resource と挙動は 3.6 |
| データ更新 | 週次更新。同一週内は同じ結果が返るため、取得結果のキャッシュを推奨(キー例: 市場名 + weekEnd) |
| エラー形式 | {"detail": ...} + HTTP ステータス。detail は文字列が基本で、422 などでは配列・オブジェクトの場合もあります(→ 3.5) |
| 課金対象 | 成功したデータ取得コール(HTTP 2xx)のみ。/v1/query は 1 リクエスト = 1 コール(内部転送の二重計上なし)。エラー応答・contentAnalysis.status の照会・キーの発行と失効・使用量照会は非課金(→ 5章) |
# curl(日本語パラメータは -G + --data-urlencode でエンコードする)
curl -sG "https://api.kwtool-ai.com/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://api.kwtool-ai.com"
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://api.kwtool-ai.com";
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://api.kwtool-ai.com/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つで書けます。q() は、待ち時間が短い 429(Retry-After 付き)だけを 2 回まで待って再試行する最小形です。用語は 用語と ID、個々の resource の意味は 3.4 を参照してください。4.5 記事制作ツールに組み込むは、この骨格に実運用のエラー処理を足したものです。
import os, time, httpx
BASE = os.environ["KW_BASE_URL"] # 例: https://api.kwtool-ai.com
H = {"X-API-Key": os.environ["KW_API_KEY"]} # kwk_...
def q(resource, **params):
for attempt in range(3):
r = httpx.get(BASE + "/v1/query", params={"resource": resource, **params},
headers=H, timeout=60)
wait = int(r.headers.get("Retry-After", "0"))
if r.status_code == 429 and 0 < wait <= 60 and attempt < 2:
time.sleep(wait) # 分あたり上限・status の照会間隔 (短い待ち) は最大 2 回まで再試行
continue
r.raise_for_status() # 月間上限 (Retry-After なし) や長い待ちの 429 はここで止める
return r.json()
# ① 注目市場から対象の市場を選ぶ(市場 ID = searchConditionId。→ 用語と ID)
market = q("myMarkets.groupMarkets", groupId=-1)["markets"][0]
sc_id, name = market["searchConditionId"], market["name"]
# ② 市場の全クエリ(検索ボリューム降順)から対策クエリを選ぶ。ここでは最上位を使う
query = q("market.queries", name=name)["queries"][0]["query"]
# ③ 分析の有無を確認 → 無ければ開始(1 日の投入上限あり → 3.6)
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(30)
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=name)["sites"]
| 項目 | 内容 |
|---|---|
| 市場 ID の世代 | 分析データは依頼時の市場 ID(searchConditionId)に紐づきます。市場の ID は調査世代で変わるため、request に使った ID を分析結果とセットで保存し、status 照会は必ず同じ ID で行ってください。過去に分析済みのクエリは、分析済み一覧(contentAnalysis.files)の各行の searchConditionId で照合できます |
| 投入の上限 | 分析の投入(③)には 1 日あたりの上限があります(上流の分析基盤の上限のほか、ご契約ごとの上限)。上限の種類・応答・対処は 3.6 の一覧表にまとめています。参照系(status / detail / keywords 等)は上限の対象外です |
| 所要時間とポーリング | 分析は非同期で通常 10〜20 分(空いていれば 1 分程度)。同期待ちにせず、ポーリングで待ってください。API キーでは同じ(marketId, query)への status 照会は 10 秒以上の間隔が必要で、早すぎると 429(Retry-After 付き)になります。目安は 20〜30 秒間隔です |
| 表示期限 | 分析結果には期限があります(validUntil ≒ 分析日 + 28 日)。期限後は再分析が必要です |
| 対策クエリの選び方 | ②は最上位のクエリを使っていますが、実際は検索ボリュームと自社の狙いを見て選びます(query は自由入力です) |
| request と GET | contentAnalysis.request は分析を開始する状態変更の操作です。上の例のように GET でも実行されますが、意図しない再実行を避けたい場合は POST /v1/query を使ってください |
機械可読の一覧は GET /v1/query/resources(認証不要。resource 名の一覧)で取得できます。3.4 では市場 / 注目市場・プロジェクト・アカウント / コンテンツ分析の 3 ブロックで説明します(この表のグループはその細分です)。
この表はサーバーの定義から自動生成しています。「取得」はデータを読むだけの resource、「操作 (POST 推奨)」は保存・削除・依頼など状態を変える resource です。「データ範囲」列の「注目市場のみ ※」は、ご契約区分が「KWTOOL 契約連動」「体験版」のキーでは注目市場に登録した市場だけ取得できる resource です (「─」は制限なし)。
| resource | 内容 | 主なパラメータ | 種別 | データ範囲 | 必要スコープ |
|---|---|---|---|---|---|
| 市場データ | |||||
| calendar.latestWeek | 最新の有効調査週。疎通確認にも使う | ─ | 取得 | ─ | markets:read |
| market.search | キーワード (完全一致) から市場を検索 | queries, weekEnd? | 取得 | ─ | markets:read |
| market.searchPartial | 市場名の部分一致検索 (上位 limit 件) | query, sort?, limit?, weekEnd? | 取得 | ─ | markets:read |
| market.top | 全市場の上位一覧 (既定は経済規模順) | sort?, limit?, weekEnd? | 取得 | ─ | markets:read |
| market.report | マーケットレポート一括取得 (全クエリ + 上位サイト + クエリ別順位) | name, weekEnd?, sites? | 取得 | 注目市場のみ ※ | markets:read |
| market.queries | 市場の全クエリと検索ボリューム (軽量版) | name, weekEnd? | 取得 | 注目市場のみ ※ | markets:read |
| market.reach | ドメイン逆引き (リーチしている検索市場) | target, limit?, weekEnd? | 取得 | ─ | markets:read |
| market.related | 語に関連する市場 (部分一致で拾えない周辺市場) | query, sort?, limit?, weekEnd? | 取得 | ─ | markets:read |
| market.relatedById | 既知の市場と相関の高い市場 (起点は除外) | marketId, limit?, weekEnd? | 取得 | ─ | markets:read |
| market.validWeeks | 市場のデータがある調査週 (新しい順) | marketId | 取得 | ─ | markets:read |
| market.portalScores | 市場内ドメインのポータル度 (0-1) | marketId, limit? | 取得 | 注目市場のみ ※ | markets:read |
| market.segments | カテゴリ別のクエリ内訳 (セグメント) | marketId, plan? | 取得 | 注目市場のみ ※ | markets:read |
| market.rankChart | ドメインの週次の流入・順位推移 | name, domain, weeks?, query?, weekEnd? | 取得 | 注目市場のみ ※ | markets:read |
| market.urlChart | ドメインの下層ページ一覧 (調査済みドメインのみ) | name, domain, limit?, weekEnd? | 取得 | 注目市場のみ ※ | markets:read |
| market.urlRankChart | URL 単位のクエリ別順位推移 | name, url, weeks?, queries?, query?, weekEnd? | 取得 | 注目市場のみ ※ | markets:read |
| market.researchedDomains | 下層ページ調査済みのドメイン一覧 | name, weekEnd? | 取得 | 注目市場のみ ※ | markets:read |
| セグメント計画・ターゲット計画 | |||||
| market.segmentPlans | セグメント計画の一覧 (カスタム分類を含む) | marketId, projectId? | 取得 | 注目市場のみ ※ | markets:read |
| market.segmentPlanDetail | セグメント計画1件 (形態素グループ付き) | marketId, planId, includeMicro? | 取得 | 注目市場のみ ※ | markets:read |
| market.microSegments | ミクロセグメント | marketId, planId, parentTagId? | 取得 | 注目市場のみ ※ | markets:read |
| market.segmentPlanSave | セグメント計画の作成・更新 | marketId, 計画 | 操作 (POST 推奨) | 注目市場のみ ※ | segments:write |
| market.segmentPlanDelete | セグメント計画の削除 | marketId, planId | 操作 (POST 推奨) | ─ | segments:write |
| market.microSegmentDelete | ミクロセグメントの削除 | marketId, planId, parentTagId | 操作 (POST 推奨) | ─ | segments:write |
| market.targetPlan | ターゲット計画 (クエリ別の受注確度) の取得 | marketId | 取得 | 注目市場のみ ※ | markets:read |
| market.targetPlans | ターゲット計画の一覧 | marketId, projectId? | 取得 | 注目市場のみ ※ | markets:read |
| market.targetPlanDetail | 保存済みターゲット計画1件の全内容 | marketId, planId, projectId? | 取得 | 注目市場のみ ※ | markets:read |
| market.targetPlanSave | ターゲット計画の保存 | marketId, 計画 | 操作 (POST 推奨) | 注目市場のみ ※ | targeting:write |
| market.targetPlanNamedSave | 名前付きターゲット計画の保存 (新規・更新) | marketId, projectId, planName, sensitivities | 操作 (POST 推奨) | 注目市場のみ ※ | targeting:write |
| market.targetPlanDelete | 保存済みターゲット計画の削除 | marketId, planId, projectId | 操作 (POST 推奨) | 注目市場のみ ※ | targeting:write |
| 調査・更新の依頼 | |||||
| market.urlResearchRequest | ドメインの下層ページ調査を依頼 (次回調査で反映) | name, domain | 操作 (POST 推奨) | 注目市場のみ ※ | url_research:write |
| market.refreshRequest | 最新週でない市場のデータ更新を依頼 | name | 操作 (POST 推奨) | 注目市場のみ ※ | market_refresh:write |
| market.refreshStatus | 市場の更新依頼が受付中かを確認 | marketId | 取得 | ─ | markets:read |
| market.discoveryRequest | 未登録キーワードの新規市場探索を依頼 | queries | 操作 (POST 推奨) | ─ | market_discovery:write |
| 注目市場・注目サイト・プロジェクト | |||||
| myMarkets.groups | 注目市場のグループ一覧 | ─ | 取得 | ─ | markets:read |
| myMarkets.groupMarkets | グループ内の市場一覧 (groupId=-1 で全グループ) | groupId, weekEnd? | 取得 | ─ | markets:read |
| myMarkets.home | ホームに設定された注目市場 | ─ | 取得 | ─ | markets:read |
| mySites.list | 注目サイトの一覧 | ─ | 取得 | ─ | markets:read |
| mySites.tags | 注目サイトのタグセット | ─ | 取得 | ─ | markets:read |
| projects.list | 参加プロジェクトの一覧 | ─ | 取得 | ─ | markets:read |
| projects.detail | プロジェクトの詳細 | projectId | 取得 | ─ | markets:read |
| projects.markets | プロジェクトに所属する市場 | projectId | 取得 | ─ | markets:read |
| projects.marketBookmark | プロジェクトに市場をブックマーク | projectId, marketId | 操作 (POST 推奨) | 注目市場のみ ※ | project_markets:write |
| projects.marketUnbookmark | プロジェクトの市場ブックマークを解除 | projectId, marketId | 操作 (POST 推奨) | 注目市場のみ ※ | project_markets:write |
| コンテンツ分析 | |||||
| contentAnalysis.files | コンテンツ分析済みファイルの一覧 | marketId?, projectId? | 取得 | ─ | content_analysis:read |
| contentAnalysis.status | 分析の有無・進行状態 | marketId, query, projectId? | 取得 | ─ | content_analysis:read |
| contentAnalysis.request | コンテンツ分析 (単ページ) の開始 | marketId, query, ほか任意 | 操作 (POST 推奨) | 注目市場のみ ※ | content_analysis:write |
| contentAnalysis.detail | 分析詳細 (上位ページの競合情報) | fileId, projectId? | 取得 | ─ | content_analysis:read |
| contentAnalysis.characters | ページ特性 (見出し構造等) | fileId, projectId? | 取得 | ─ | content_analysis:read |
| contentAnalysis.keywords | 業界特有度キーワード (重要形態素) | fileId, minSites?, minIndustryScore?, limit?, mode? | 取得 | ─ | content_analysis:read |
| contentAnalysis.linkAnalysis | 複ページ分析 (リンク分析) の詳細 | fileId, projectId? | 取得 | ─ | content_analysis:read |
| contentAnalysis.linkPage | 複ページ分析のページ別詳細 | fileId, rank | 取得 | ─ | content_analysis:read |
| contentAnalysis.linkRequest | 複ページ分析の開始 | fileId | 操作 (POST 推奨) | ─ | content_analysis:write |
| アカウント | |||||
| gateway.me | 認証中のアカウント情報 | ─ | 取得 | ─ | ─ |
resource 化されていない補助エンドポイント(疎通確認 /health、使用量 /v1/usage、CSV 出力 /v1/export/csv)は 3.7 にまとめています。
resource は用途で 3 つのブロックに分けて並べています: 市場(市場を探す・中身を見る・計画を保存する)、注目市場・プロジェクト・アカウント(自分のアカウントに紐づく情報)、コンテンツ分析(対策クエリごとの上位ページ分析)。見出しの 取得 はデータを読むだけの resource、操作 (POST 推奨) は保存・削除・分析や調査の依頼など状態を変える resource です。どの resource も、キーに必要スコープが無い場合は 403(requiredScope に必要なスコープ)です。
操作系 resource の共通ルール: POST /v1/query の body に resource とパラメータを入れて呼びます(GET でも実行されますが、意図しない再実行を避けるため POST を推奨)。保存は kwtool アカウント単位のため、同じ kwtool アカウントのキー・画面(kwtool 本体を含む)と保存内容を共有します。操作系のスコープ(下表)は閲覧用のスコープ(markets:read 等)には含まれず、個別に許可されている場合だけ使えます(無い場合は 403、requiredScope 参照)。分析の投入(contentAnalysis.request / contentAnalysis.linkRequest)も状態を変える操作です。注目市場・注目サイトそのものの追加・削除は API では提供していません(kwtool 画面から操作してください)。
例(market.refreshRequest):
curl -s -X POST "https://api.kwtool-ai.com/v1/query" \
-H "X-API-Key: $KW_API_KEY" -H "Content-Type: application/json" \
-d '{"resource": "market.refreshRequest", "params": {"name": "ハワイ旅行"}}'
この表はサーバーの定義 (スコープと resource の対応) から自動生成しています。
| スコープ | 機能 | 説明 | 対象の resource |
|---|---|---|---|
markets:read | 市場データの閲覧 | 検索市場の規模・ボリューム・流入サイト・逆引きなどの参照 | market.report, market.queries, market.search, market.reach, market.related, market.relatedById, market.validWeeks, market.portalScores, market.top, market.searchPartial, market.segments, market.segmentPlans, market.segmentPlanDetail, market.microSegments, market.rankChart, market.urlChart, market.urlRankChart, market.researchedDomains, calendar.latestWeek, myMarkets.groups, myMarkets.home, myMarkets.groupMarkets, mySites.list, mySites.tags, projects.list, projects.detail, projects.markets, market.refreshStatus, market.targetPlan, market.targetPlans, market.targetPlanDetail |
content_analysis:read | コンテンツ分析結果の閲覧 | 投入済みコンテンツ分析の結果・抽出キーワードの取得 | contentAnalysis.files, contentAnalysis.detail, contentAnalysis.characters, contentAnalysis.status, contentAnalysis.keywords, contentAnalysis.linkAnalysis, contentAnalysis.linkPage |
content_analysis:write | コンテンツ分析の依頼 | 対策クエリのコンテンツ分析の投入 (単ページ・複ページ) | contentAnalysis.request, contentAnalysis.linkRequest |
url_research:write | URL 調査の依頼 | ドメインの下層ページ調査の依頼 (次回調査で反映) | market.urlResearchRequest |
market_refresh:write | 市場データ更新の依頼 | 最新週でない市場の再調査(データ更新)を上流に依頼。翌営業日以降に反映 | market.refreshRequest |
market_discovery:write | 検索市場の新規探索の依頼 | 未登録キーワードのビッグデータ調査(新規市場探索)を上流に依頼。検索ニーズが一定数あれば新市場として登録される(既存市場の再調査 market_refresh とは別枠) | market.discoveryRequest |
segments:write | セグメントの編集 | セグメント定義プランの保存・削除 | market.segmentPlanSave, market.segmentPlanDelete, market.microSegmentDelete |
targeting:write | ターゲティングの編集 | ターゲット計画の保存 | market.targetPlanSave, market.targetPlanNamedSave, market.targetPlanDelete |
project_markets:write | プロジェクトの市場ブックマーク | プロジェクトへの市場の紐づけ (ブックマーク) の追加・解除 | projects.marketBookmark, projects.marketUnbookmark |
最新週の確認(calendar.latestWeek)→ 市場を探す・全体像を見る(search / report / queries / searchPartial・top / reach / related / portalScores)→ 市場が無い・古いときの依頼(discoveryRequest / refreshRequest)→ 順位推移と下層ページ(rankChart / urlChart / urlResearchRequest)→ セグメント計画(segments 〜 segmentPlanDelete)→ ターゲット計画(targetPlan 〜 targetPlanDelete)の順に並べています。市場名は完全一致、市場 ID は 用語と ID を参照。
データが存在する最新の調査週を返します。weekEnd を明示指定したい場合や、週が切り替わったかの判定に使います。キー発行後の疎通確認にも最適です。パラメータなし。
q("calendar.latestWeek")
# → {"weekEnd": "YYYY-MM-DD"} (最新の調査週の終了日)
キーワード(完全一致)から市場を検索し、市場の基本情報と 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, // 検索ボリューム
"economicRank": 3, // 経済規模の順位(全市場中。→ 用語と ID)
"queryCount": 321, // 構成クエリ数
"weekEnd": "2026-07-04"
}
]
}
ヒットしない場合は {"markets": []}(404 にはなりません)。kwtool 画面の「経済規模」欄には 926位 のように順位が出ます。API の economicRank と同じ値です(→ 用語と ID)。母数(全市場数)は API からは取得できません。
市場名から構成クエリ(検索ボリューム付き)・上位サイトの流入ランクと推計流入数・サイトごとのクエリ別順位をまとめて返します。「市場名を入れたら全部返ってくる」用途はまずこれを使ってください。
| パラメータ | 必須 | 説明 |
|---|---|---|
| name | ✅ | 市場名(完全一致・日本語は URL エンコード) |
| weekEnd | - | 調査週 YYYY-MM-DD。省略時は最新週 |
| sites | - | 上位サイト数(既定 20) |
q("market.report", name="旅行")
{
"market": { "id": "sc-1001", "name": "旅行", ... }, // market.search と同形
"weekEnd": "2026-07-04",
"queries": [ // 市場の全クエリ。ボリューム降順・重複なし
{"query": "ハワイ旅行", "volume": 12000, "economicRank": 1},
{"query": "ハワイ旅行 費用", "volume": 6600, "economicRank": 2}
], // economicRank = 市場内の経済規模順位 (単純連番。
// セグメント計画のデータが取れなかった場合は null。→ 用語と ID)
"sites": [ // 上位サイト。流入ランク順(rank は 1 始まり)
{
"rank": 1,
"domain": "tabi-navi.jp",
"title": "たびナビ | ハワイ旅行・ツアー",
"flowRate": 24.1, // 流入率 %
"estClicks": 2975.1, // 推計流入数/月 = market.volume × flowRate%
// (例: 12345 × 24.1% ≈ 2975.1)
"shareRate": 18.2, // シェア %
"flowScore": 2975.1, // 非推奨: estClicks と同値(後方互換)
"queryRanks": [ // このサイトのクエリ別順位(rank 昇順)
{"query": "ハワイ旅行", "rank": 1, "estClicks": 1980.0}
]
}
],
"totalSites": 1284, // 市場内の総サイト数(sites の絞り込み前)
"warnings": [] // 部分成功時に理由が入る(エラーではない)
}
totalSites は sites パラメータで絞り込む前の全ドメイン数です。「37位 / 1,284サイト中」の母数に使えます。チャートデータが取得できなかった部分成功時は null(サイト 0 件の市場とは区別されます)queryRanks に圏外のクエリは含まれません。順位データが存在するのはランキングチャート掲載クエリのみですqueryRanks には、そのクエリで順位が付いたサイトだけが載ります(サイトごとの件数はサイトによって違います)queries はチャート掲載分のみに縮退し warnings に理由が入ります{"detail": "market not found: {name}"}市場の全クエリと検索ボリュームだけを返す軽量版。対策キーワードの選定に使います。パラメータは name(必須・完全一致)と weekEnd(任意)。
q("market.queries", name="旅行")
# → {"market": {...}, "weekEnd": "2026-07-04",
# "queries": [{"query": "...", "volume": 12000,
# "economicRank": 1}, ...]} // economicRank=市場内の経済規模順位 (report と同じ。→ 用語と ID)
queries の母集合は market.report の queries と同一(重複なし・ボリューム降順)。該当なしは同じく 404。
市場名の部分一致検索(market.searchPartial)と、全市場の上位一覧(market.top)。どちらも sort の降順で上位 limit 件を返します。
| パラメータ | 必須 | 説明 |
|---|---|---|
| query | searchPartial のみ ✅ | 市場名に含まれる語(部分一致) |
| sort | - | economicScale(経済規模・既定) / volume(検索ボリューム) / queryCount(検索クエリ数)。それ以外の値は 422 |
| limit | - | 返す件数(既定 20) |
| weekEnd | - | 調査週。省略時は最新週 |
q("market.searchPartial", query="リフォーム") # 名前に「リフォーム」を含む市場
q("market.top", sort="volume", limit=50) # 検索ボリューム上位50市場
# → {"markets": [{"id": "sc-1001", "name": "...", "volume": 12345, ...}], "hasMore": true}
limit 件のみで、総ヒット数・総市場数は返りません。hasMore: true は「limit で切り詰めた、または上流に続きが残っている可能性がある」の意です(残件数までは分かりません)ドメイン(または URL)の逆引き。そのドメインがリーチしている検索市場を、対象ドメインの流入数降順で返します。「このサイトはどの市場で戦っているか」を見る用途です。パラメータは target(必須・ドメインまたは URL)、limit(既定 20)、weekEnd。
q("market.reach", target="tabi-navi.jp")
# → {"input": "tabi-navi.jp", "domain": "tabi-navi.jp",
# "code": "ok", // リーチ市場なしは "no_reach_detected"
# "weekEnd": "2026-07-04",
# "markets": [
# {"id": "sc-1001", "name": "ハワイ旅行", "volume": 12345,
# "inflowRank": 3, // 市場内の流入ランク (1位=最大)
# "sharePercent": 4.2, // 流入率 %
# "estInflow": 518, ...} // 想定流入数/月 (volume × 流入率)
# ],
# "warnings": [],
# "hasMore": false} // true = limit で切り詰め (続きあり)
limit 件のみで、リーチ市場の総数は返りません。並びは常に流入数降順です(sort を渡しても並びは変わりません)inflowRank 等が欠落し warnings に理由が入りますkingoftime.jp)で 0 件のときは、内部でドメイン候補検索を使い実在ホスト(www.kingoftime.jp やサブドメイン)へ解決して再照合します。解決時は domain に解決後のホスト、warnings にその旨が入り、input は元の入力を保持します関連市場の発見と有効週の一覧。market.searchPartial(名前の部分一致)では拾えない周辺市場(業種別・課題別など)を見つける用途です。
| resource | パラメータ | 内容 |
|---|---|---|
| market.related | query(必須), sort?, limit?(既定 20), weekEnd? | 語に関連する市場。先頭は語に最も近い市場(完全一致があればそれ)、以降が関連市場。sort は searchPartial と同じ値 |
| market.relatedById | marketId(必須), limit?(既定 20), weekEnd? | 既知市場と相関の高い市場(起点市場自身は除外) |
| market.validWeeks | marketId(必須) | 市場のデータがある調査週を新しい順で返す。時系列取得や weekEnd 指定の候補に使う |
q("market.related", query="DX") # 語に関連する市場
# → {"query": "DX", "weekEnd": "2026-08-03",
# "markets": [{"id": "sc-1001", "name": "dx", "economicRank": 12, ...}], "warnings": []}
# // economicRank=全市場中の経済規模順位 (→ 用語と ID)
q("market.relatedById", marketId="sc-1001")
# → {"marketId": "sc-1001", "weekEnd": "...", "markets": [...], "warnings": []}
q("market.validWeeks", marketId="sc-1001")
# → {"marketId": "sc-1001", "weeks": ["2026-08-03", "2026-07-27", ...]}
関連市場が無い場合も markets: [] で返ります(エラーにはなりません。warnings に理由が入ることがあります)。
市場内ドメインのポータル度(0〜1)。高いほど汎用プラットフォーム(SEO で置き換えにくい相手)、低いほど特化した攻略対象です。競合の絞り込みに使います。パラメータは marketId(必須)と limit(既定 20)。
q("market.portalScores", marketId="sc-1001")
# → {"marketId": "sc-1001",
# "domains": [{"domain": "www.amazon.co.jp", "portalScore": 0.31, "measuredDate": "2026-05-21"}, ...]}
キーワードを完全一致で照合し、登録済みの市場はそのまま返し(registered)、未登録のキーワードだけを上流のビッグデータ調査(新規市場探索)へ依頼します(非同期・翌営業日以降に反映。検索ニーズがあれば新市場として登録され、無ければ登録されません)。登録されたかは後で market.search で確認します。必要スコープ market_discovery:write。
| パラメータ | 必須 | 説明 |
|---|---|---|
| queries | ✅ | キーワードの配列(空白のみ・重複は除外。有効なキーワードが1つも無ければ 422) |
| weekEnd | - | 照合する調査週 |
# POST /v1/query body: {"resource": "market.discoveryRequest", "params": {"queries": ["ハワイ旅行", "グアム旅行"]}}
# → {"registered": [市場...], "submitted": ["..."],
# "alreadyExists": [], "alreadyRequested": [], "rejected": [], "tooNew": [], "tooSmall": [],
# "weekEnd": "2026-07-04", "result": {...}}
submitted = 上流が受理したキーワードだけです。受け付けられなかった語は rejected / tooNew / tooSmall / alreadyRequested / alreadyExists に分かれます最新週でない市場のデータ更新(再調査)を依頼します(非同期・翌営業日以降に反映)。反映後の週は market.validWeeks / calendar.latestWeek で確認します。
| resource | パラメータ | 応答 | スコープ |
|---|---|---|---|
| market.refreshRequest | name(必須・完全一致), weekEnd? | {market, requested, already_requested, result}。requested: true = 上流が受け付けた。既に受付中なら二重に依頼せず requested: false, already_requested: true(冪等) | market_refresh:write |
| market.refreshStatus | marketId(必須) | {market_id, requested, raw}。requested: true = 更新依頼が受付中。読み取り専用 | markets:read |
この 2 つの応答のキーは snake_case(market_id / already_requested)です(他の resource の camelCase と違います)。
ドメイン(サイト)の週次順位・流入推移。市場内でのサイトの伸び・衰退を時系列で見る用途です。パラメータは name(必須・市場名の完全一致)、domain(必須)、weeks(既定 26)、query(任意)、weekEnd。
q("market.rankChart", name="ハワイ旅行", domain="tabi-navi.jp", query="ハワイ旅行")
# → {"market": {...}, "domain": "tabi-navi.jp",
# "weekEnd": "2026-07-04", "firstDate": "2020-01-01", // firstDate = データ開始週
# "weekly": [ // 新しい週順に weeks 件
# {"weekEnd": "2026-07-04", "flowRate": 24.1,
# "estClicks": 2975.1, // 推計流入数/月 = volume × flowRate%
# "shareRate": 18.2, "flowScore": 2975.1}, ... // flowScore は非推奨 (estClicks と同値)
# ],
# "queryHistory": {"query": "ハワイ旅行", "volume": 12000, // query 指定時のみ
# "history": [{"weekEnd": "2026-07-04", "rank": 1}, ...]}}
queryHistory.history の圏外週は rank: null。クエリが市場に無い場合は 404(query not found in this market)ドメインの下層ページ(URL)単位の分析。対象は下層ページ調査が済んでいるドメインのみです — market.researchedDomains で確認でき、未調査ドメインは market.urlResearchRequest で調査を依頼できます。
| resource | パラメータ |
|---|---|
| market.researchedDomains | name(必須), weekEnd? |
| market.urlChart | name(必須), domain(必須), limit?(既定 100), weekEnd? |
| market.urlRankChart | name(必須), url(必須・完全一致), weeks?(既定 26), queries?(返すクエリ数・既定 10), query?(指定時はそのクエリだけ), weekEnd? |
q("market.researchedDomains", name="ハワイ旅行")
# → {"market": {...}, "weekEnd": "2026-07-04", "domains": ["tabi-navi.jp"]}
q("market.urlChart", name="ハワイ旅行", domain="tabi-navi.jp")
# → {"market": {...}, "domain": "tabi-navi.jp", "weekEnd": "2026-07-04",
# "urls": [ // 流入数降順に limit 件
# {"url": "https://tabi-navi.jp/hawaii", "title": "ハワイ特集", "rank": 2,
# "flowRate": 1.0, "estClicks": 123.5, // 推計流入数/月 = volume × flowRate%
# "shareRate": 0.5,
# "flowScore": 123.5}, ... // flowScore は非推奨 (estClicks と同値)
# ],
# "totalUrls": 342} // limit 絞り込み前の総URL数
q("market.urlRankChart", name="ハワイ旅行", url="https://tabi-navi.jp/hawaii")
# → {"market": {...}, "page": {"url": "...", "title": "ハワイ特集"},
# "weekEnd": "2026-07-04",
# "queries": [ // ボリューム降順に queries 件
# {"query": "ハワイ旅行", "volume": 12000,
# "history": [{"weekEnd": "2026-07-04", "rank": 1}, ...]}
# ],
# "totalQueries": 25} // 順位データを持つクエリ総数 (絞り込み前)
totalUrls / totalQueries は絞り込み前の総数です(market.report の totalSites と同じ流儀)。rank: null は現週で圏外url chart data not found ... / url rank chart data not found ...)ドメインの下層ページ調査を依頼します(非同期・次回調査で反映)。調査済みかは market.researchedDomains、結果は market.urlChart で確認します。必要スコープ url_research:write。
| パラメータ | 必須 | 説明 |
|---|---|---|
| name | ✅ | 市場名(完全一致。該当なしは 404) |
| domain | ✅ | 調査対象ドメイン |
| weekEnd | - | 市場を解決する調査週 |
# POST /v1/query body: {"resource": "market.urlResearchRequest", "params": {"name": "ハワイ旅行", "domain": "tabi-navi.jp"}}
# → {"market": {...}, "domain": "tabi-navi.jp", "result": {...}} // result は上流の受付結果
市場内のクエリをカテゴリ(例: ブランド、エリア)別に集計して返します。「この市場はどんな関心で構成されているか」を見る用途です。
| パラメータ | 必須 | 説明 |
|---|---|---|
| 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(必須)と projectId(任意。指定するとそのプロジェクトの計画一覧)。得た planId を market.segments の plan や market.segmentPlanDetail に渡します。応答は kwtool の形式のまま(公開フィールドのみ)返します。
q("market.segmentPlans", marketId="sc-1001")
# → [{"planId": 12, "planName": "エリア別"}, ...] // planId が計画 ID (segments の plan / segmentPlanDetail の planId に渡す)
# 自動分類は planId / planName が null の要素で入る (market.segments では plan=machine)
セグメント計画 1 件を、分類と検索クエリの間にある形態素(word)の層を保ったまま返します(market.segments は分類とクエリだけを返します)。market.microSegments は計画のミクロセグメント(分類の下の細分類)だけを返します。
| resource | パラメータ | 応答 |
|---|---|---|
| market.segmentPlanDetail | marketId(必須), planId(必須。machine で自動分類), includeMicro?(既定 true。machine では無視) | {marketId, planId, planName, type, status, tags: [{tagId, name, type, hasChildren, wordBlocks: [{word, queries: [クエリ]}], microTags: [{tagId, name, type, wordBlocks: [...]}]}]} |
| market.microSegments | marketId(必須), planId(必須), parentTagId? | parentTagId 指定時は {marketId, planId, parentTagId, microTags: [...]}、省略時は計画全体を {marketId, planId, microTags: {親タグID: [...]}} |
q("market.segmentPlanDetail", marketId="sc-1001", planId="machine")
microTags が空になります)wordBlocks[].queries ・ microTags を保存形式へ変換する処理はありません。保存するときは、読んだ分類名と形態素を簡易形式(categories[].name / words / micro)に組み直して送ってくださいupstream business error for resource ...)セグメント計画を作成します。planId を付けるとその計画を更新します(更新できるのは自分の計画だけ。ゲートウェイが所有を確認し、他アカウントの計画は 403)。クエリの割り当ては形態素から自動で決まるため、指定するのは形態素です。必要スコープ segments:write。
| 形式 | 必須項目 | 説明 |
|---|---|---|
簡易形式(推奨。categories があればこちら) | marketId、planName、categories(1件以上)、各分類の name と words(形態素1件以上)。micro を付ける場合は各ミクロの name と words | {"marketId": "...", "planName": "...", "categories": [{"name": "エリア", "words": ["ハワイ", "グアム"], "micro": [{"name": "島", "words": ["オアフ"]}]}]}。任意: planId(更新)、projectId(新規作成時にプロジェクトへ紐づけ)、type、status、分類・ミクロの tagId / type |
| 生形式(kwtool の計画オブジェクト) | marketId、planName、tags(1件以上)、各 tag の name、各 wordBlocks[].word | allMicroTags を付ける場合は tags と同じ長さ・同じ並びの配列。値の組み立ては利用者の責任になるため、通常は簡易形式を使ってください |
値の制約: 計画の type は machine / initial / user(簡易形式の既定 user)、status は private / public(既定 private)、分類・ミクロの type は user / system / exclusion(既定 user)。
planId を含む)。projectId を付けた場合は projectId が付き、プロジェクトへの紐づけに失敗したときは計画自体は作成済みのまま projectLinkFailed: true が付きますdetail はオブジェクト。reason と、値の誤りでは value / allowed、位置の誤りでは index / name、hint)| reason | HTTP | 意味 |
|---|---|---|
empty_plan_name | 422 | planName が空 |
empty_categories | 422 | 簡易形式で categories が空 |
invalid_category | 422 | categories の要素がオブジェクトでない(index) |
empty_words | 422 | 分類の words が空(形態素を1件以上。クエリではありません) |
invalid_micro | 422 | micro の要素がオブジェクトでない |
empty_micro_words | 422 | ミクロの words が空 |
empty_tags | 422 | 生形式で tags が空 |
invalid_tag | 422 | tags の要素がオブジェクトでない |
empty_tag_name | 422 | 分類(tag / category)の name が空 |
invalid_tag_type | 422 | 分類・ミクロの type が user / system / exclusion 以外 |
invalid_word_block | 422 | 生形式で wordBlocks[].word が空 |
empty_micro_tag_name | 422 | ミクロの name が空 |
micro_tags_length_mismatch | 422 | 生形式で allMicroTags が tags と同じ長さの配列でない |
invalid_plan_type | 422 | 計画の type が許可値以外 |
invalid_plan_status | 422 | 計画の status が許可値以外 |
segment_plan_not_owned | 403 | 更新しようとした planId が自分の計画ではない(その市場の計画一覧に自分の計画として無い) |
segment_plan_ownership_unverifiable | 403 | 計画一覧を取得できず所有を確認できないため拒否した。時間を置いて再試行 |
セグメント計画 / ミクロセグメントを削除します。必要スコープ segments:write。応答は上流の応答をそのまま返します。
| resource | パラメータ | 内容 |
|---|---|---|
| market.segmentPlanDelete | planId(必須), marketId(必須) | セグメント計画の削除。削除できるのは自分の計画だけです(ゲートウェイが marketId の計画一覧で所有を確認。自分の計画でなければ 403 segment_plan_not_owned、確認できなければ 403 segment_plan_ownership_unverifiable)。marketId が無い場合は 422 |
| market.microSegmentDelete | parentTagId(必須), marketId(必須), planId(必須) | 親タグ配下のミクロセグメントの削除。削除できるのは自分の計画のミクロセグメントだけです(ゲートウェイが marketId の計画一覧で planId の所有を確認し、さらに parentTagId がその計画のミクロセグメントの親タグかを確認)。marketId / planId は market.microSegments で親タグを調べたときと同じ値です。どちらかが無い場合は 422 |
# POST /v1/query body: {"resource": "market.segmentPlanDelete", "params": {"marketId": "sc-1001", "planId": 12}}
# POST /v1/query body: {"resource": "market.microSegmentDelete", "params": {"marketId": "sc-1001", "planId": 12, "parentTagId": 34}}
| reason | HTTP | 意味 |
|---|---|---|
segment_plan_not_owned | 403 | planId が自分の計画ではない(機械作成・初期計画・他アカウントの計画を含む) |
micro_segment_not_in_plan | 403 | (microSegmentDelete)指定した自分の計画に、parentTagId を親に持つミクロセグメントが無い(別の計画の親タグ・存在しない ID・ミクロセグメントの無い親タグ) |
segment_plan_ownership_unverifiable | 403 | 計画一覧またはミクロセグメント一覧を取得できず、所有を確認できないため拒否した(削除は行っていない)。時間を置いて再試行 |
ターゲット計画(検索クエリごとの受注確度)の取得(読み取り)。応答は kwtool の形式のまま(公開フィールドのみ)返します。
| resource | パラメータ | 応答 |
|---|---|---|
| market.targetPlan | marketId(必須) | 市場レベルの計画。orderSensitivities({"<クエリ>": 確度}、確度は 0〜5、-1 = 未設定)。orderSensitivities は応答の直下または data の下に入ります |
| market.targetPlans | marketId(必須), projectId? | 名前付き計画の一覧 {plans: [{id, name, projectId, searchConditionId, description, createdDatetime, updatedDatetime, ...}]}(上流が返す範囲で)。id が planId |
保存済みの名前付きターゲット計画 1 件の全内容と確度別件数を返します(読み取り、markets:read)。
| パラメータ | 必須 | 説明 |
|---|---|---|
| marketId | ✅ | 市場 ID |
| planId | ✅ | 計画 ID(market.targetPlans の id) |
| projectId | - | 指定するとそのプロジェクトの計画一覧から探す |
# → {"detail": {"id": 123, "name": "...", "projectId": "...", "searchConditionId": "...",
# "description": "...", "cvrs": [0.0, 0.01, 0.05, 0.1, 0.5, 1.5], // 確度 0〜5 ごとの想定 CVR
# "orderSensitivities": {"<クエリ>": 3, ...}, ...},
# "counts": {"5": 3, ..., "unset": 205}, "totalQueries": 218, "entries": 284,
# "outOfWeek": {"count": 1, "queries": ["<画面に出ないクエリ>"]},
# "countBasis": "screenQueries",
# "levels": {"5": ["<クエリ>", ...], ..., "0": [...], "unset": [...]}}
件数(counts / totalQueries)と levels は、market.targetPlanNamedSave の応答と同じく、kwtool 画面に出るクエリで数えます。計画には過去の週にしか無いクエリも保存されているため、entries(保存されている件数)は画面の件数より多くなることがあります。画面に出ないクエリに付いた確度は outOfWeek に分けて返します。countBasis は数えた基準で、画面のクエリ一覧を取得できなかったときは marketPlanMap または planEntries になります。
planId がその (市場, プロジェクト) の一覧に無い場合は 404 plan_not_found_in_project(他の市場・プロジェクトの計画は ID を指定しても読めません)。
ターゲット計画オブジェクトを kwtool の形式のまま保存します。必要スコープ targeting:write。名前・冪等性・保存後の照合が必要な場合は market.targetPlanNamedSave を使ってください。
| パラメータ | 必須 | 説明 |
|---|---|---|
| marketId | ✅ | 市場 ID(計画の searchConditionId はこの値で上書き) |
| name | 上流で必須 | 計画名。無いと上流が失敗し 502(upstream business error for resource 'market.targetPlanSave') |
| orderSensitivities | - | {"<クエリ>": 確度}(確度は 0〜5、-1 = 未設定)。値の範囲やクエリが市場に存在するかはゲートウェイで検査せず、そのまま上流へ渡します |
| description ほか | - | 計画オブジェクトの他のフィールドはそのまま上流へ渡します |
# POST /v1/query body: {"resource": "market.targetPlanSave", "params": {"marketId": "sc-1001", "name": "重点クエリ", "orderSensitivities": {"ハワイ旅行": 5, "ハワイ旅行 費用": 3}}}
上流へ送る前に検査するのは件数と長さだけです(超過は 422、detail はオブジェクト):
| reason | 条件 |
|---|---|
too_many_sensitivities | orderSensitivities が 5000 件を超える(count / max) |
query_key_too_long | クエリ(キー)が 140 文字を超える |
description_too_long | description が 2000 文字を超える(length / max) |
プロジェクトに名前付きのターゲット計画を保存します。planId 無しは新規作成、有りはその計画の更新です。値の検査・冪等性・保存直後の読み戻し照合をゲートウェイが行います。必要スコープ targeting:write。
| パラメータ | 必須 | 説明 |
|---|---|---|
| marketId | ✅ | 市場 ID |
| projectId | ✅ | 自アカウントのプロジェクト ID(projects.list で確認) |
| planName | ✅ | 計画名(100 文字以内。空白だけは不可) |
| sensitivities | ✅ | {"<クエリ>": 0〜5 の整数 | null}(null = 未設定)。1 件以上・5000 件以内、クエリは 140 文字以内で、市場のクエリと完全一致させる(market.queries で確認)。省略したクエリは未設定で埋めて全量を保存します |
| planId | - | 更新する計画(market.targetPlans の id)。その (市場, プロジェクト) の一覧にある計画に限る |
| description | - | 説明(2000 文字以内)。更新時に省略すると既存の説明を保つ |
| verify | - | 保存直後に読み戻して照合するか(既定 true) |
# POST /v1/query body:
{"resource": "market.targetPlanNamedSave",
"params": {"marketId": "sc-1001", "projectId": "378", "planName": "重点クエリ 2026Q4",
"sensitivities": {"ハワイ旅行": 5, "ハワイ旅行 費用": 3}}}
{"action": "created", // created / updated / unchanged
"plan": {"id": 123, "name": "...", "projectId": "...", "marketId": "...", "description": null,
"createdDatetime": "...", "updatedDatetime": "..."},
"counts": {"5": 3, "4": 0, "3": 10, "2": 0, "1": 0, "0": 0, "unset": 271}, // 画面と同じ母数
"totalQueries": 284, // 市場のクエリ数 (画面に出る集合)
"entries": 290, // 保存したキーの総数
"outOfWeek": {"count": 2, "queries": ["..."]}, // 画面の週に出ないクエリに付けた確度
"verified": true, // verify=false なら null
"mismatches": []} // 照合で食い違ったクエリ {query, sent, saved} (最大20件)
planId 無しで同じ名前の計画が 1 件あり内容も同じなら、保存せず action: "unchanged" を返します。同じ名前で内容が違う場合は 409 plan_name_exists(更新するなら planId を指定、別の計画なら別名)outOfWeek: 過去の週にしか無いクエリに付けた確度は保存されますが、画面の列には出ません。件数を分けて示しますplanId 指定)では、既存計画の確度別の想定 CVR(cvrs)を引き継ぎます| HTTP | reason / detail | 意味と対処 |
|---|---|---|
| 422 | (配列) | 必須項目の欠落、planName が 100 文字超、description が 2000 文字超、sensitivities が空・5000 件超、クエリが 140 文字超(FastAPI 標準の検証エラー。loc / msg を確認) |
| 422 | invalid_sensitivity | 確度が 0〜5 の整数でも null でもない(keys / count) |
| 422 | empty_plan_name | planName が空白だけ |
| 422 | unknown_queries | 市場のクエリに無いキーがある(queries に最大10件、count) |
| 422 | market_has_no_queries | その市場に有効なクエリが無い |
| 404 | project_not_found | projectId が自アカウントのプロジェクトではない |
| 404 | plan_not_found_in_project | planId がその (市場, プロジェクト) の計画一覧に無い |
| 409 | plan_name_exists | 同名で内容が違う計画がある(planId / differences) |
| 409 | duplicate_plan_names | 同名の計画が複数ある(planIds)。更新する計画の planId を指定する |
| 503 | market_query_set_unverifiable | 市場のクエリ集合を確認できないため保存を拒否した(sources)。時間を置いて再試行 |
| 502 | upstream business error ... / upstream did not return plan.id ... | 上流が保存に失敗した |
保存済みの名前付きターゲット計画を削除します。REST(/v1/query)限定で、MCP(AI アプリ連携)には公開していません。必要スコープ targeting:write。
| パラメータ | 必須 | 説明 |
|---|---|---|
| marketId | ✅ | 市場 ID |
| planId | ✅ | 削除する計画 ID |
| projectId | ✅ | 計画が属するプロジェクト ID(無い場合は 422) |
# POST /v1/query body: {"resource": "market.targetPlanDelete", "params": {"marketId": "sc-1001", "projectId": "378", "planId": 123}}
# → {"marketId": "...", "projectId": "...", "planId": "123", "name": "...",
# "deleted": true, // 削除後の一覧に残っていなければ true
# "remaining": 4} // 削除後の計画数
その (市場, プロジェクト) の一覧に無い計画は削除せず 404 plan_not_found_in_project。上流が失敗した場合は 502。
自分の kwtool アカウントに紐づく情報です。常に認証アカウント自身のデータが返ります(他人のデータは見えません)。
ログインアカウントの「注目市場」(kwtool の My マーケット)。応答は kwtool の形式のまま(公開フィールドのみ)返します。
| resource | 内容 | パラメータ |
|---|---|---|
| myMarkets.groups | 注目市場グループ一覧 | ─ |
| myMarkets.groupMarkets | グループ内の市場一覧。groupId=-1 で全グループ横断 | groupId(必須), weekEnd? |
| myMarkets.home | ホームに設定された注目市場 | ─ |
q("myMarkets.groupMarkets", groupId=-1)["markets"]
# 各要素: {"name": "ハワイ旅行", "searchConditionId": "sc-1001", // 市場 ID (market.search の id と同一)
# "volume": 12345, "wordCount": 321, "searchConditionType": ...,
# "date": "2026-07-04", "marketScale": 3} // marketScale = economicRank と同じ順位
# searchConditionId はコンテンツ分析の marketId に使う(標準フロー①・用語と ID)
kwtool の「注目サイト」(登録済みの監視ドメイン)とそのタグセット。自社・競合として登録したドメインを取り出し、market.reach(逆引き)や market.rankChart の domain に渡す用途です。
| resource | 内容 | パラメータ |
|---|---|---|
| mySites.list | 注目サイト(登録済み監視ドメイン)一覧 | ─ |
| mySites.tags | 注目サイトのタグセット | ─ |
レスポンスは現状 kwtool 内部の形式のまま返しています(パススルー)。フィールド構成を整える改訂を予定しており、変更時は事前に告知します。
kwtool のプロジェクト(→ 用語と ID)。参加しているプロジェクトだけが返ります。projects[].id は、プロジェクトへの市場ブックマーク・名前付きターゲット計画・プロジェクト単位のコンテンツ分析の projectId に使います。
| resource | 内容 | パラメータ |
|---|---|---|
| projects.list | 参加プロジェクト一覧(projects[].id / name 等) | ─ |
| projects.detail | プロジェクト詳細 | projectId(必須) |
| projects.markets | プロジェクトにブックマークされた市場。{searchConditionIds: [市場ID...], markets: [{searchConditionId, name}]}(市場名を引けなかった分は name: null) | projectId(必須) |
権限の無いプロジェクトを指定した場合、現状は 403 ではなく 502(upstream kw-cms error (HTTP 403) ...)が返ります。projects.list で参加プロジェクトの ID を確認してから呼んでください。
市場をプロジェクトにブックマーク(紐づけ)/ 解除します。kwtool 画面のブックマークアイコンと同じ操作です。必要スコープ project_markets:write。
| パラメータ | 必須 | 説明 |
|---|---|---|
| projectId | ✅ | 自アカウントの参加プロジェクト ID(それ以外は 404 project_not_found) |
| marketId | ✅ | 市場 ID |
# POST /v1/query body: {"resource": "projects.marketBookmark", "params": {"projectId": "378", "marketId": "sc-1001"}}
# → {"projectId": "...", "marketId": "...",
# "bookmarked": true, // 操作後にブックマークされているか
# "changed": true, // 今回の操作で状態が変わったか
# "already": false, // 既に目的の状態だった (上流を呼ばない = 冪等)
# "count": 5} // 操作後のブックマーク数
上流が業務エラーを返した場合は 502(upstream business error for resource ...)。
いま認証しているアカウントの情報(loginId・userName・role・isAdmin・mode など)。キーがどのアカウントとして動いているかの確認に使います。パラメータなし・スコープ不要。
対策クエリの検索上位ページを分析し、重要形態素と競合情報を返します。流れは 3.2 の標準フローのとおり、status で有無を確認 → request で依頼 → 完了後に detail / keywords です。結果(fileId)は依頼時の市場 ID に紐づきます(→ 用語と ID)。
コンテンツ分析済みファイルの一覧。過去に分析したクエリの 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 | ✅ | 対策キーワード |
| projectId | - | プロジェクト単位で分析した場合に指定 |
q("contentAnalysis.status", marketId=sc_id, query="ハワイ旅行")
# 分析済み:
# {"marketId": "sc-1001", "query": "ハワイ旅行", "status": "researched",
# "fileId": 74420, "requestDate": "2026-07-10", "researchDate": "2026-07-10 14:07:49",
# "validUntil": "2026-08-07", "searchLocation": "日本全域",
# "linkAnalysisStatus": ..., "linkResearchedDate": ..., "hasLinkAnalysisResult": ...}
# 未分析:
# {"marketId": "sc-1001", "query": "未分析ワード", "status": "not_analyzed", "fileId": null}
| status | 意味 |
|---|---|
| not_analyzed | 分析データなし(→ contentAnalysis.request で開始できる) |
| rank_researching 等 | 分析実行中(→ ポーリング継続) |
| researched | 完了。fileId を詳細・キーワード取得に使える |
API キーでは、同じ(marketId, query)を 10 秒未満で再照会すると 429 status polled too frequently for this analysis; retry after Ns(Retry-After 付き)になります。Retry-After の秒数だけ待ってから照会してください。
未分析クエリのコンテンツ分析を開始します(kwtool 画面の「調査リクエスト」と同一の処理)。非同期・状態変更の操作で、完了は contentAnalysis.status のポーリングで確認します。必要スコープ content_analysis:write。
| パラメータ | 必須 | 説明 |
|---|---|---|
| marketId | ✅ | 市場 ID(scId)。この値を分析結果とセットで保存する |
| query | ✅ | 対策キーワード |
| targetPagesCount | - | 参照する上位ページ数(1〜30、既定 10) |
| locationId | - | 検索地域(既定 1 = 日本全域) |
| optionalTargets | - | 自サイト等の追加 URL 配列 |
| projectId | - | プロジェクト単位で分析する場合に指定 |
| originalText | - | 自前原稿の本文。指定すると上位ページと合わせて分析対象に含まれ、公開前原稿のコンテンツ力計測に使える |
| originalTextFileName | - | originalText に付けるファイル名ラベル(例: draft.txt) |
# GET でも実行できるが、状態変更なので POST 版を推奨
curl -s -X POST "https://api.kwtool-ai.com/v1/query" \
-H "X-API-Key: $KW_API_KEY" -H "Content-Type: application/json" \
-d '{"resource": "contentAnalysis.request",
"params": {"marketId": "sc-1001", "query": "ハワイ旅行"}}'
{"marketId": "...", "query": "...", "accepted": true, "result": "ok"}
{"marketId": "...", "query": "...", "accepted": false, "result": "over_limit"}
over_limit = 上流の分析基盤の 1 日あたり上限を超過。翌日以降に再実行してください。このほかにご契約ごとの 1 日あたり投入上限があり、到達すると HTTP 429 です。上限の種類・応答・対処は 3.6 の一覧表validUntil(≒ 分析日 + 28 日)。期限後は再分析が必要です分析詳細。pages に検索上位ページ(既定10件)の競合情報が入ります。パラメータは fileId(必須)と projectId(任意)。データ提供契約のキーで自分が依頼していない分析の fileId は 404(analysis file not found)です。
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 | 上位ページのうち何サイト以上に出現する語に絞るか(1〜30。推奨: 必須語=6、推奨語=3) |
| minIndustryScore | 0 | 業界特有度の下限 |
| limit | 100 | 返す語数 |
| mode | single | link で複ページ分析側の重要語(未実施なら status が not_analyzed で keywords は空) |
| projectId | - | プロジェクト単位の分析の場合に指定 |
q("contentAnalysis.keywords", fileId=file_id, minSites=6, limit=100)
# → {"fileId": "74420", "mode": "single", "status": "researched",
# "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} // 上位ページ全体での総出現回数
# ]}
コンテンツ分析には単ページ分析と複ページ分析(リンク分析)があります。複ページ分析は単ページ分析と同じ fileId に対する別ジョブで、内部リンクで繋がるページ群を合算したコンテンツ力を返します(単ページは、そのページ単体のコンテンツ力)。
| resource | パラメータ | スコープ |
|---|---|---|
| contentAnalysis.linkAnalysis | fileId(必須), projectId? | content_analysis:read |
| contentAnalysis.linkPage | fileId(必須), rank(必須。pages[].seq), projectId? | content_analysis:read |
| contentAnalysis.linkRequest | fileId(必須。単ページ分析が完了したもの) | content_analysis:write |
link = q("contentAnalysis.linkAnalysis", fileId=file_id)
link["status"] # researched / not_analyzed / analyzing / over_limit / not_enabled
for page in link["pages"]:
# singleContentsScore … 単ページのコンテンツ力
# contentsScore … 複ページ(リンク先合算)のコンテンツ力
print(page["url"], page["singleContentsScore"], "→", page["contentsScore"])
| status | 意味 |
|---|---|
| not_analyzed | 複ページ分析は未実施(→ contentAnalysis.linkRequest で開始)。応答の remaining に当日の残り依頼可能数が入ります(上流が返さないときは null) |
| analyzing | 実行中(通常 10〜30 分) |
| researched | 完了。pages と重要語が入る |
| over_limit / not_enabled | 1 日の依頼上限超過 / アカウントで複ページ分析が無効 |
inboundLinks / outboundLinks / crossLinks は [内部リンクか, コンテンツ, ポータル度, 独自性] の配列contentAnalysis.linkPage(rank は pages[].seq)。上流のパススルーですmode=link を付けて取得しますcontentAnalysis.linkRequest(POST /v1/query body: {"resource": "contentAnalysis.linkRequest", "params": {"fileId": 74420}})の応答は {"fileId": "74420", "accepted": true, "result": "ok", "remaining": 1}(remaining は linkAnalysis と同じ当日の残り依頼可能数)。result が over_limit / not_enabled なら accepted: falsecontentAnalysis.linkRequest(投入)は単ページ分析とは別枠の 1 日あたり投入上限を持ちます(→ 3.6 の一覧表)。参照(linkAnalysis / linkPage)は数えませんエラーは {"detail": ...} 形式で返ります。機械判定には HTTP ステータスと、付いている場合は reason を使ってください。detail の形は次の 3 通りです。必須パラメータの不足は 400 missing required params: [...](不足した名前の配列付き)または 422(配列。loc に名前)のどちらかで返ります(どちらになるかは resource とパラメータで異なります)。値の型・範囲・長さの誤りは常に 422(配列)です。
| detail の形 | 例 | 主な発生箇所 |
|---|---|---|
| 文字列 | {"detail": "market not found: 旅行"} | ほとんどのエラー。reason 等の追加キーが並ぶ場合あり(例: 429 upstream login throttled、503 guard_unavailable) |
| 配列(FastAPI 標準の検証エラー) | {"detail": [{"loc": [...], "msg": "...", "type": "..."}]} | 422: 必須パラメータの欠落・型や長さの誤り |
| オブジェクト | {"detail": {"reason": "invalid_tag_type", "value": "...", "allowed": [...]}} | 422 / 403 / 404 / 409 / 503: 書き込み系(segmentPlanSave・targetPlanSave・targetPlanNamedSave ほか)。detail.reason で判定 |
| ステータス | 代表的な detail / reason | 意味と対処 |
|---|---|---|
| 400 | unknown resource: ◯◯ | resource 名の誤り。レスポンスの available に正しい一覧が入っている |
| 400 | missing required params: [...] | その resource の必須パラメータ(marketId, fileId 等)が不足 |
| 400 | authentication fields are not accepted as request parameters: [...] | key / token 等の認証用の名前を params に入れた。キーはヘッダーで送る |
| 400 | conflicting credentials: ...(reason: credential_conflict) | ヘッダーと ?key= など、異なるキーを同時に送った。キーは 1 本だけ送る |
| 400 | ダッシュボードキー (gwk_) を URL の ?key= で送ることはできません… | gwk_ を URL に載せた。プログラム連携には API キー(kwk_)を使う |
| 400 | unsupported resource/table: ... | /v1/export/csv で resource と table の組み合わせが未対応(resource=market.queries では table=queries だけ。→ 3.7) |
| 401 | missing api key | キーが送られていない |
| 401 | invalid api key | キーの値が誤っている。コピー漏れ・別環境のキーでないか確認 |
| 401 | api key revoked / api key expired | 失効済み / 有効期限切れのキー。API キー 画面で新しいキーを発行して差し替える |
| 401 | api key is not activated | 管理者から受け取った招待キーが未有効化。ログイン画面の招待キーの初回有効化を行う(→ 2章) |
| 401 | invalid gateway key / gateway session revoked; please log in again | ダッシュボードのセッション(gwk_)が期限切れ・ログアウト済み。ダッシュボードに再ログインする(キーの再発行ではない) |
| 401 | upstream login failed: ... | kwtool のパスワード変更等でキー内の認証情報が古い。ダッシュボードに再ログイン → 新しいキーを発行 → 古いキーを失効 |
| 403 | api key plan does not permit resource '...' | キーのスコープにその resource が無い(requiredScope に必要スコープ)。サポートチームに相談 |
| 403 | role '...' does not permit resource '...' | ご契約区分(役割)の上限でその resource が使えない(requiredScope / role)。キーを発行し直しても変わらない。サポートチームに相談 |
| 403 | account permissions do not permit resource '...' | ダッシュボードのセッションで、アカウントの利用許可にその resource が無い |
| 403 | API の利用には管理者による利用許可が必要です… | アカウントに API 利用許可が未登録。サポートチームに問い合わせ |
| 403 | external api keys must use the single endpoint /v1/query ... | API キーで /v1/query 以外の /v1/... を直接呼んだ。/v1/query?resource=... を使う |
| 403 | reason: outside_my_markets | 注目市場に登録していない市場の詳細を取得しようとした(→ 3.6 データ範囲) |
| 403 | ご契約では…をご利用いただけません | ご契約区分に単ページ分析(文言では「コンテンツ力分析」)/ 複ページ分析の投入が含まれていない。翌日も同じなのでリトライ不要 |
| 403 | segment_plan_not_owned / segment_plan_ownership_unverifiable | 自分の計画ではないセグメント計画を更新・削除しようとした / 所有を確認できなかった(→ segmentPlanSave) |
| 403 | micro_segment_not_in_plan | 指定した自分のセグメント計画に、parentTagId を親に持つミクロセグメントが無い(→ microSegmentDelete) |
| 404 | market not found: ◯◯ | 市場名の完全一致に該当なし。表記(スペース・カタカナ)を確認 |
| 404 | query not found in this market: ◯◯ / url chart data not found ... | 指定クエリが市場に無い / 下層ページのデータが無い(未調査ドメイン等) |
| 404 | analysis file not found | データ提供契約のキーで、自分が依頼していない分析の fileId を指定した |
| 404 | project_not_found / plan_not_found_in_project | 自アカウントのプロジェクトではない / その (市場, プロジェクト) に計画が無い |
| 409 | plan_name_exists / duplicate_plan_names | 名前付きターゲット計画の同名衝突(→ targetPlanNamedSave) |
| 422 | (配列) | パラメータ不足・型や長さの誤り。detail の loc / msg を確認 |
| 422 | unknown sort key: ... / could not extract a domain from: ... / queries must contain at least one non-empty keyword | 値の誤り(文字列の detail)。sort の値・target のドメイン・探索キーワードを確認 |
| 422 | reason 付きオブジェクト | 書き込み系の入力検査。各 resource の表を参照(unknown_queries・invalid_sensitivity・market_has_no_queries・too_many_sensitivities・query_key_too_long・description_too_long・empty_plan_name ほか) |
| 429 | rate limit exceeded | キーの分あたり上限を超過。Retry-After: 1 を待ってから再試行し、直列・低頻度アクセスにする |
| 429 | monthly quota exceeded | アカウント全体の当月コール数が月間上限に到達(Retry-After なし)。翌月まで待つかサポートチームに相談。キーを分けても枠は分かれない |
| 429 | リクエストが集中しています。少し時間をおいて再試行してください(上限 N 回/分) | ダッシュボード操作など API キー以外の経路のアカウント単位上限。Retry-After を待つ |
| 429 | status polled too frequently for this analysis; retry after Ns | contentAnalysis.status を同じ(marketId, query)で 10 秒未満に再照会した。Retry-After を待つ |
| 429 | 1日あたりの…の上限に達しました(上限 N 回/日)… | ご契約区分の 1 日あたり分析投入回数に到達(Retry-After: 3600)。日付が変わると再投入できる |
| 429 | daily analysis request limit reached | データ提供契約で管理者が設定した 1 日あたりの分析依頼数に到達(Retry-After: 3600) |
| 429 | upstream login throttled(reason: upstream_login_throttled) | kwtool 側でログインが一時的に制限されている。キーの再発行は不要。Retry-After(既定 900 秒)待ってから再試行する。待たずに再試行・再ログイン・再発行を繰り返すと制限が延びる。401 upstream login failed とは別物 |
| 429 | too many login attempts; retry after N seconds | ダッシュボードのログイン試行がアカウントあたり 5 回/分、または IP あたり 20 回/分を超えた。Retry-After を待つ |
| 502 | upstream kw-cms error (HTTP N) at ... | kwtool 側のエラー。多くは「その市場・週にデータが無い」。週を変えるか時間を置いて再試行。権限の無いプロジェクト(projects.detail / projects.markets)も現状は (HTTP 403) の 502 になる |
| 502 | upstream business error for resource '...': ... | kwtool が HTTP 200 のまま失敗を返した(データが無い・権限が無い等。理由は区別できない)。非課金。パラメータ(ID・名前)を確認 |
| 503 | 現在データ転送を一時停止しています。管理者にお問い合わせください(killSwitch: true) | 管理者による緊急停止中。全データ取得が止まっている。サポートチームに問い合わせ |
| 503 | reason: guard_unavailable | 認可の確認基盤の一時障害のため拒否した。時間を置いて再試行 |
| 503 | reason: data_range_unverifiable | 注目市場の一覧を確認できないため拒否した。時間を置いて再試行 |
| 503 | reason: market_query_set_unverifiable | 名前付きターゲット計画の保存で、市場のクエリ集合を確認できないため拒否した。時間を置いて再試行 |
上限と制約を一覧表にまとめます。データ範囲(注目市場の制限)の詳細は、表の下のデータ範囲にあります。ご契約区分ごとの分析投入の回数は、表の下の分析投入の 1 日あたり上限にあります。429 のうち Retry-After が付くものは待てば回復し、付かないもの(月間上限)は再試行しても回復しません。エラー文言の一覧は 3.5 です。
| 種類 | 対象 | 超過したときの応答 | 対処 |
|---|---|---|---|
| 分あたり上限 | API キーごと(全ご契約区分) | 429 rate limit exceeded(Retry-After: 1) | 1 秒待って再試行。直列・低頻度アクセスにする |
| 月間上限 | アカウント全体(そのアカウントの全キーとダッシュボード操作の合計) | 429 monthly quota exceeded(Retry-After なし) | 再試行しない。翌月まで待つかサポートチームに相談。キーを分けても枠は分かれない |
| API キー以外の経路の集中 | アカウント単位(ダッシュボード操作など) | 429「リクエストが集中しています…(上限 N 回/分)」(Retry-After 付き) | Retry-After を待つ |
| 1 日上限(上流の分析基盤) | 全ご契約区分。contentAnalysis.request / contentAnalysis.linkRequest | HTTP 200 のまま accepted: false、result: "over_limit" | 翌日以降に再実行。投入回数は消費しない |
| 1 日上限(ご契約区分の投入回数) | KWTOOL 契約連動・体験版。単ページ分析(contentAnalysis.request)と複ページ分析(contentAnalysis.linkRequest)は別枠 | 429「1日あたりの…の上限に達しました(上限 N 回/日)…」(Retry-After: 3600)。ご契約に含まれない場合は 403「ご契約では…をご利用いただけません」 | 429 は日付が変わると再び投入できる。403 は翌日も同じなので再試行不要。回数は下表 |
| 1 日上限(管理者が設定した分析依頼数) | データ提供契約。contentAnalysis.request(同じ市場・クエリの再依頼は数えない) | 429 daily analysis request limit reached(Retry-After: 3600) | 翌日以降に再実行 |
| 分析状態のポーリング間隔 | API キー。同じ(marketId, query)への contentAnalysis.status | 429 status polled too frequently for this analysis; retry after Ns(Retry-After 付き) | 10 秒以上あける(目安 20〜30 秒)。照会は非課金 |
| ログイン試行 | ダッシュボード。アカウントあたり 5 回/分・IP あたり 20 回/分 | 429 too many login attempts; retry after N seconds | Retry-After を待つ |
| kwtool 側のログイン制限 | 全ご契約区分 | 429 upstream login throttled(reason: upstream_login_throttled) | Retry-After(既定 15 分)待つ。キーの再発行は不要。待たずに繰り返すと制限が延びる |
| データ範囲 | KWTOOL 契約連動・体験版。市場の詳細を返す resource | 403(reason: outside_my_markets) | kwtool で注目市場に登録する(→ 下記) |
weekEnd に無効な週を指定した場合の挙動は上流依存です。calendar.latestWeek / market.validWeeks で有効週を確認してくださいご契約区分が「KWTOOL 契約連動」「体験版」のアカウントでは、市場の詳細(ドリルダウン)を取得できるのは注目市場(kwtool の My マーケット)に登録した市場だけです。全市場の一覧・検索・逆引き・関連市場(market.top / market.search / market.searchPartial / market.reach / market.related 等)は制限されません。
制限がかかる resource:
対象: KWTOOL 契約連動 (connected) / 体験版 (trial) の API キーと、ダッシュボードのログインセッション。この表はサーバーの定義から自動生成しています。
| resource | 内容 | 判定に使う値 |
|---|---|---|
| market.report | マーケットレポート一括取得 (全クエリ + 上位サイト + クエリ別順位) | 市場名 (name) |
| market.queries | 市場の全クエリと検索ボリューム (軽量版) | 市場名 (name) |
| market.rankChart | ドメインの週次の流入・順位推移 | 市場名 (name) |
| market.urlChart | ドメインの下層ページ一覧 (調査済みドメインのみ) | 市場名 (name) |
| market.urlRankChart | URL 単位のクエリ別順位推移 | 市場名 (name) |
| market.researchedDomains | 下層ページ調査済みのドメイン一覧 | 市場名 (name) |
| market.urlResearchRequest | ドメインの下層ページ調査を依頼 (次回調査で反映) | 市場名 (name) |
| market.refreshRequest | 最新週でない市場のデータ更新を依頼 | 市場名 (name) |
| market.segments | カテゴリ別のクエリ内訳 (セグメント) | 市場 ID (marketId) |
| market.segmentPlans | セグメント計画の一覧 (カスタム分類を含む) | 市場 ID (marketId) |
| market.segmentPlanDetail | セグメント計画1件 (形態素グループ付き) | 市場 ID (marketId) |
| market.microSegments | ミクロセグメント | 市場 ID (marketId) |
| market.segmentPlanSave | セグメント計画の作成・更新 | 市場 ID (marketId) |
| market.portalScores | 市場内ドメインのポータル度 (0-1) | 市場 ID (marketId) |
| market.targetPlan | ターゲット計画 (クエリ別の受注確度) の取得 | 市場 ID (marketId) |
| market.targetPlans | ターゲット計画の一覧 | 市場 ID (marketId) |
| market.targetPlanSave | ターゲット計画の保存 | 市場 ID (marketId) |
| market.targetPlanDetail | 保存済みターゲット計画1件の全内容 | 市場 ID (marketId) |
| market.targetPlanNamedSave | 名前付きターゲット計画の保存 (新規・更新) | 市場 ID (marketId) |
| market.targetPlanDelete | 保存済みターゲット計画の削除 | 市場 ID (marketId) |
| projects.marketBookmark | プロジェクトに市場をブックマーク | 市場 ID (marketId) |
| projects.marketUnbookmark | プロジェクトの市場ブックマークを解除 | 市場 ID (marketId) |
| contentAnalysis.request | コンテンツ分析 (単ページ) の開始 | 市場 ID (marketId) |
reason: outside_my_markets)。kwtool で注目市場に登録すると取得できるようになります(反映まで最大 300 秒)。登録できる市場の数には上限(ご契約の市場数)があり、登録数と残り枠はダッシュボードの「ご契約」または「API キー」画面で確認できますmyMarkets.groupMarkets の name / searchConditionId をそのまま使ってくださいreason: data_range_unverifiable)。時間を置いて再試行してくださいコンテンツ分析(単ページ。contentAnalysis.request)と複ページ分析(contentAnalysis.linkRequest)の投入には、ご契約区分ごとに別枠の 1 日あたり上限があります。参照系(status / detail / keywords / linkAnalysis 等)は数えません。
| ご契約区分 | コンテンツ分析(単ページ) | 複ページ分析 |
|---|---|---|
| KWTOOL 契約連動 | 5 回/日 | 2 回/日 |
| 体験版 | 0 回/日 | 0 回/日 |
| データ提供契約 | 管理者が設定した回数/日(未設定なら制限なし。同じ市場・クエリの再依頼は数えない)。到達すると 429 daily analysis request limit reached | ゲートウェイ側の上限なし(上流の 1 日上限のみ) |
Retry-After: 3600)。日付が変わると再び投入できますover_limit / not_enabled の応答だけです認証不要。死活監視用。
curl -s "https://api.kwtool-ai.com/health"
# → {"status": "ok", "version": "0.1.0"}
| パラメータ | 既定 | 説明 |
|---|---|---|
| granularity | day | day / week / month(推移の単位) |
| limit | - | 返すバケット数 |
| from / to | - | 期間 YYYY-MM-DD(to は含む) |
curl -sG "https://api.kwtool-ai.com/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": {...}}
currentMonth.billing は参考値で、ダッシュボードの表示と一致しない場合があります。請求額の確定値としては使わないでください(請求は管理者からご案内します)。
スプレッドシート(IMPORTDATA)・BI ツール向けの CSV 出力。resource の指定方法は /v1/query と同じで、スコープ・データ範囲の判定も同じです。
| パラメータ | 説明 |
|---|---|
| resource | データ種別。market.report(既定) / market.queries |
| table | 出力表。sites(上位サイト・既定) / queries(全クエリ) / queryRanks(サイト×クエリ順位の縦持ち)。resource=market.queries で使えるのは table=queries だけなので必ず明示する(既定の sites のままだと 400 unsupported resource/table) |
| name 等 | resource のパラメータをそのまま渡す |
| key | ヘッダーを付けられない場合(IMPORTDATA 等)だけのキー指定(?key=kwk_...)。URL にキーが残る点に注意。gwk_ は URL で送れません |
# プログラムから(ヘッダー推奨)
curl -sG "https://api.kwtool-ai.com/v1/export/csv" -H "X-API-Key: $KW_API_KEY" \
--data-urlencode "resource=market.queries" --data-urlencode "table=queries" \
--data-urlencode "name=市場名"
# ヘッダーを付けられない IMPORTDATA などの場合のみ
https://api.kwtool-ai.com/v1/export/csv?resource=market.report&name=市場名&table=sites&key=kwk_...
' について(数式注入対策): 市場名・検索語・サイトのタイトルなど外部由来の文字列が = + - @(全角含む)やタブ・制御文字で始まる場合、表計算ソフトが数式として実行しないよう先頭に '(単一引用符)を付けて出力します。Excel や Google スプレッドシートで開いた場合は ' は表示されず文字列として扱われます。数値列(順位・流入数・ボリューム等)はそのまま数値です。pandas 等でプログラムから読む場合は ' がそのまま届くので、必要なら先頭 1 文字を取り除いてください(→ 4.4 pandas)。/llms.txt ↗(別タブで開きます)は、この API の仕様をプレーンテキスト 1 枚に要約したファイルです。AI アプリにコードを書かせるときに URL を渡して読ませる用途です(→ 4.6 指示文の例)。より詳しい仕様が必要な場合は本ページを読ませてください。AI アプリで会話して使う(MCP コネクタで接続する場合や、REST API を直接呼ぶ設定に指示文を貼る場合)ときの手引きは /llms-chat.txt ↗ です(コードではなくデータの読み方・作法。→ 6. AIアプリ連携)。
/docs は、OpenAPI 定義から自動生成される API 一覧画面(Swagger UI)です。公開エンドポイント(/v1/query と補助エンドポイント)のパラメータ・レスポンス型を機械的に確認できます。resource ごとのパラメータは本ページの 3.4 を参照してください。
本文は現在の仕様だけを書いています。以前の挙動に合わせた処理を書いていた場合は、ここで差分を確認してください。
| 日付 | resource | 変更 |
|---|---|---|
| 2026-09-17 | market.targetPlanDetail | counts / totalQueries を保存時の応答と同じ「画面に出るクエリ」で数えるようになりました。以前は計画に保存された全件で数えていたため、過去の週のクエリが混ざり、保存時の応答や画面の件数より多くなっていました。保存されている全件数が必要な場合は entries を使ってください |
| 2026-09-17 | market.microSegmentDelete | 以前は parentTagId だけで呼べましたが、所有の確認のため marketId と planId が必須になりました。パラメータを追加してください |
| 2026-09-16 | market.segmentPlanDelete | 以前は planId だけで呼べましたが、所有の確認のため marketId が必須になりました。パラメータを追加してください |
| 2026-09-16 | market.segmentPlanSave | 不正な値は送信前に検査し、422 で理由を返すようになりました。以前は上流エラー(502「データが存在しない可能性」)になっていました |
| 2026-09-16 | market.discoveryRequest | submitted は上流が受理したキーワードだけになりました。以前は未登録だったキーワード全部を submitted として返していました。「依頼できた語」を数える用途は submitted のままで正しくなります |
| 2026-09-16 | market.urlChart / market.urlRankChart | 下層ページの順位と順位推移が画面と同じ 1 始まりになりました(以前は 0 始まり)。自前で +1 していた場合は外してください |
| 2026-09-16 | market.rankChart | 順位が画面と同じ 1 始まりになりました(以前は 0 始まりで、1 位が 0 でした)。自前で +1 していた場合は外してください |
| 2026-09-16 | market.searchPartial / market.top | sort=queryCount が効くようになりました(以前は指定しても経済規模順のままでした)。検索クエリ数の降順に並びが変わります |
| 2026-09-16 | market.report | queryRanks の順位が画面と同じ値になりました。以前は順位が別サイトの値にずれ、各クエリの 1 位が抜け、全サイトがほぼ同数のクエリを持っていました。現在はそのクエリで順位が付いたサイトだけに載るため、サイトごとの件数はサイトによって違い、以前より減ります(仕様です。順位の値はそのまま使えます) |
問い合わせ: サポートチームまで。 ← ダッシュボードへ戻る