概要
IndexNowは、Webサイトのページが追加、更新、削除された際に、検索エンジンに即座に通知できるプロトコルである。
通知を受けた検索エンジンは、他の参加検索エンジンと自動的に情報を共有する。
APIキーの準備
キーの要件
IndexNowで使用するAPIキーには、以下の要件がある。
- 文字数: 最小8文字、最大128文字
- 使用可能な文字:
- 小文字 (a-z)
- 大文字 (A-Z)
- 数字 (0-9)
- ハイフン (-)
- 形式: 16進数の文字列
キーの例を以下に示す。
31a0f3c4c69e46fda555417af06e6db3
キーの生成方法
IndexNowのAPIキーは、一般的なAPIのように申請して取得するものではなく、自分で生成する仕組みになっている。
Linuxコマンドで生成
UUIDベースの生成
# ハイフンを含む形式 (36文字) uuidgen # ハイフンなしの形式 (32文字) uuidgen | tr -d '-' # 小文字に変換 uuidgen | tr -d '-' | tr '[:upper:]' '[:lower:]'
# 実行例 uuidgen | tr -d '-' | tr '[:upper:]' '[:lower:]' # 出力例 31a0f3c4c69e46fda555417af06e6db3
OpenSSLを使った生成 (よりランダム)
# 16バイト (32文字の16進数) openssl rand -hex 16 # 32バイト (64文字の16進数) openssl rand -hex 32 # 64バイト (128文字の16進数) openssl rand -hex 64
/dev/urandomを使用した生成
# 32文字の16進数 cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 32 | head -n 1 # 64文字の16進数 cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 64 | head -n 1
Windowsで生成
PowerShellを使用
# GUIDベース (ハイフンなし)
([guid]::NewGuid().ToString() -replace '-',).ToLower()
# ランダム文字列 (32文字)
-join ((48..57) + (97..102) | Get-Random -Count 32 | ForEach-Object {[char]$_})
コマンドプロンプトを使用
rem PowerShellコマンドを実行 powershell -Command "([guid]::NewGuid().ToString() -replace '-',).ToLower()"
オンラインツールで生成
以下のようなオンラインツールを使用することもできる。
ただし、セキュリティを考慮する場合は、ローカルで生成することを推奨する。
プログラミング言語で生成
Python
import uuid
import secrets
# UUIDベース
key1 = uuid.uuid4().hex
print(key1)
# secretsモジュール使用 (より安全)
key2 = secrets.token_hex(32)
print(key2)
PHP
<?php
// 32文字の16進数
$key = bin2hex(random_bytes(16));
echo $key;
// またはMD5ベース
$key = md5(uniqid(rand(), true));
echo $key;
?>
JavaScript (Node.js)
const crypto = require('crypto');
// 32文字の16進数
const key = crypto.randomBytes(16).toString('hex');
console.log(key);
// 64文字の16進数
const key2 = crypto.randomBytes(32).toString('hex');
console.log(key2);
キーファイルの作成と配置
ステップ1 : キーを生成
# 例: OpenSSLで32文字のキーを生成 KEY=$(openssl rand -hex 16) echo "生成されたキー: $KEY"
# 出力例 生成されたキー: 31a0f3c4c69e46fda555417af06e6db3
ステップ2 : キーファイルを作成
Linuxの場合
# キーを変数に保存
KEY="31a0f3c4c69e46fda555417af06e6db3"
# キーファイルを作成
echo "$KEY" > "${KEY}.txt"
# 確認
cat "${KEY}.txt"
または、手動でファイルを作成する。
vi 31a0f3c4c69e46fda555417af06e6db3.txt
# ファイル内容 31a0f3c4c69e46fda555417af06e6db3
Windowsの場合
# PowerShellで作成 $key = "31a0f3c4c69e46fda555417af06e6db3" $key | Out-File -FilePath "$key.txt" -Encoding UTF8 -NoNewline
ステップ3 : ファイルをウェブサーバにアップロード
方法1 : SCPでアップロード
scp 31a0f3c4c69e46fda555417af06e6db3.txt <ユーザ名>@<IPアドレスまたはドメイン名>:/var/www/html/
方法2 : FTPクライアントを使用
FileZilla、WinSCP等でWebサイトのルートディレクトリにアップロードする。
方法C: サーバ上で直接作成
# サーバにSSH接続 ssh <ユーザ名>@<IPアドレスまたはドメイン名> # Webサイトのルートディレクトリに移動 cd /var/www/html # キーファイルを作成 echo "31a0f3c4c69e46fda555417af06e6db3" > 31a0f3c4c69e46fda555417af06e6db3.txt # パーミッションを設定 chmod 644 31a0f3c4c69e46fda555417af06e6db3.txt
ステップ4 : ファイルの配置場所を確認
Webサイトのルートディレクトリは、以下のような場所が一般的である。
- Apache2
- /var/www/html/
- /var/www/example.com/public_html/
- /usr/local/apache2/htdocs/
- Nginx
- /usr/share/nginx/html/
- /var/www/html/
- /var/www/example.com/
- 共用サーバ (cPanel等)
- ~/public_html/
- ~/www/
- ~/htdocs/
ステップ 5 : アクセス確認
ブラウザまたはcurlコマンドで確認する。
# curlで確認 curl https://www.example.com/31a0f3c4c69e46fda555417af06e6db3.txt # 期待される出力 31a0f3c4c69e46fda555417af06e6db3
Webブラウザで確認する。
https://www.example.com/31a0f3c4c69e46fda555417af06e6db3.txt
実装例 (シェルスクリプト)
#!/bin/bash
# 設定
WEB_ROOT="/var/www/html"
DOMAIN="www.example.com"
# キーを生成
KEY=$(openssl rand -hex 16)
echo "生成されたキー: $KEY"
# キーファイルを作成
echo "$KEY" > "${WEB_ROOT}/${KEY}.txt"
# パーミッション設定
chmod 644 "${WEB_ROOT}/${KEY}.txt"
# 確認
echo ""
echo "キーファイルが作成されました:"
echo "ファイルパス: ${WEB_ROOT}/${KEY}.txt"
echo "アクセスURL: https://${DOMAIN}/${KEY}.txt"
echo ""
echo "確認コマンド:"
echo "curl https://${DOMAIN}/${KEY}.txt"
echo ""
echo "このキーを使ってIndexNowにURLを送信できます:"
echo "curl \"https://api.indexnow.org/indexnow?url=https://${DOMAIN}/page.html&key=${KEY}\""
キー生成時の注意事項
- キーの保存
- 生成したキーは必ず安全な場所に保存する
- パスワード管理ツール等に記録することを推奨
- UTF-8エンコード
- キーファイルは必ずUTF-8エンコードで保存する
- BOM (Byte Order Mark)なしで保存する
- 改行コード
- ファイル内にキーのみを記述し、余分な改行を入れない
- Windowsで作成する場合、改行コードに注意する
- ファイルパーミッション
- 読み取り可能にする必要がある (644推奨)
- 実行権限は不要
- HTTPS
- HTTPSでアクセス可能にすることを推奨
- HTTPでも動作するが、セキュリティ上HTTPSが望ましい
所有権の確認
URLを送信する前に、サイトの所有権を証明する必要がある。
所有権の確認方法として、以下に示す2つの方法がある。
オプション1 : ルートディレクトリに配置 (推奨)
- テキストファイルを作成する。(UTF-8エンコード)
- ファイル名を
{あなたのキー}.txtにする- 例: 31a0f3c4c69e46fda555417af06e6db3.txt
- ファイル内にキーのみを記述する。
- Webサイトのルートディレクトリに配置する。
オプション2 : 任意の場所に配置
サイト内の任意の場所にキーファイルを配置することが可能である。
ただし、キーファイルの場所より下層のURLのみ送信可能である。
また、送信時において、keyLocation パラメータで場所を指定する必要がある。
以下の例では、http://example.com/catalog/key12457EDd.txt に配置している。
- 送信可能なURL:
- 送信不可能なURL:
URLの送信方法
単一URLの送信
HTTPリクエスト形式
https://<検索エンジン>/indexnow?url=<変更されたURL>&key=<あなたのキー> # 例: https://api.indexnow.org/indexnow?url=https://www.example.com/product.html&key=31a0f3c4c69e46fda555417af06e6db3
送信方法
以下の方法でURLを送信できる。
- ブラウザのアドレスバーに直接入力
curlコマンド:wgetコマンド- プログラムから送信
オプション2を使用する場合
https://api.indexnow.org/indexnow?url=https://www.example.com/product.html&key=31a0f3c4c69e46fda555417af06e6db3&keyLocation=https://www.example.com/mykey.txt
複数URLの一括送信
最大10,000個のURLを一度に送信できる。
JSON形式でPOSTリクエスト
POST /indexnow HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: api.indexnow.org
{
"host": "www.example.com",
"key": "31a0f3c4c69e46fda555417af06e6db3",
"urlList": [
"https://www.example.com/url1",
"https://www.example.com/folder/url2",
"https://www.example.com/url3"
]
}
curlコマンドの例
curl -X POST https://api.indexnow.org/indexnow \ -H "Content-Type: application/json" \ -d '{ "host": "www.example.com", "key": "31a0f3c4c69e46fda555417af06e6db3", "urlList": [ "https://www.example.com/page1", "https://www.example.com/page2" ] }'
オプション2を使用する場合
{
"host": "www.example.com",
"key": "31a0f3c4c69e46fda555417af06e6db3",
"keyLocation": "https://www.example.com/mykey.txt",
"urlList": [
"https://www.example.com/url1",
"https://www.example.com/url2"
]
}
複数のURLを送信する例
まず、サイトマップから送信するためのURLリストを作成する。
#!/usr/bin/env sh
SITEMAP_URL="https://www.example.com/sitemap.xml"
# サイトマップをダウンロードしてURLを抽出
curl -s "$SITEMAP_URL" | grep -oP '<loc>\K[^<]+' > urllist.txt
echo "URLリストを urllist.txt に保存しました"
wc -l urllist.txt
次に、IndexNowペイロードファイルを作成する。
#!/usr/bin/env sh
# IndexNow設定
API_KEY="<APIキー>"
HOST="<ドメイン名>"
KEY_LOCATION="https://${HOST}/${API_KEY}.txt"
URL_FILE="urllist.txt"
OUTPUT_FILE="indexnow_payload.json"
# URLファイルの存在確認
if [ ! -f "$URL_FILE" ]; then
echo "エラー: URLファイルが見つかりません: $URL_FILE"
exit 1
fi
# JSONファイルを作成
echo "IndexNow ペイロード作成"
cat > "$OUTPUT_FILE" <<EOF
{
"host": "${HOST}",
"key": "${API_KEY}",
"keyLocation": "${KEY_LOCATION}",
"urlList": [
EOF
# URLリストを追加
URLS=$(cat "$URL_FILE" | sed 's/^/ "/;s/$/",/' | sed '$ s/,$//')
echo "$URLS" >> "$OUTPUT_FILE"
# JSONを閉じる
cat >> "$OUTPUT_FILE" <<EOF
]
}
EOF
# URLの数をカウント
URL_COUNT=$(cat "$URL_FILE" | wc -l)
echo "ペイロード作成完了"
echo "統計情報:"
echo " URL数: $URL_COUNT"
echo " ファイルサイズ: $(du -h "$OUTPUT_FILE" | cut -f1)"
最後に、IndexNowにペイロードを送信する。
curl -X POST "https://api.indexnow.org/indexnow" \ -H "Content-Type: application/json; charset=utf-8" \ -d @indexnow_payload.json
レスポンスコード
| HTTPコード | レスポンス | 説明 |
|---|---|---|
| 200 | OK | URL送信成功 |
| 202 | Accepted | URL受信完了。キー検証待ち |
| 400 | Bad Request | 無効な形式 |
| 403 | Forbidden | キーが無効 (キーファイルが見つからない、またはファイル内にキーがない) |
| 422 | Unprocessable Entity | URLがホストに属していない、またはキーがスキーマと一致しない |
| 429 | Too Many Requests | リクエストが多すぎる (スパムの可能性) |
※注意
HTTP 200は検索エンジンがURLを受信したことを示すだけで、インデックスされることを保証するものではない。
主要な検索エンジンのエンドポイント
主要な検索エンジンのIndexNowエンドポイントを以下に示す。
| 検索エンジン | 対応状況 | エンドポイント |
|---|---|---|
| Bing | 完全対応 | https://www.bing.com/indexnow https://api.indexnow.org/indexnow |
| Yandex | 完全対応 | https://yandex.com/indexnow |
| Seznam.cz | 完全対応 | https://search.seznam.cz/indexnow |
| Naver | 完全対応 | - |
| 未対応 | - |
推奨される設定
- 自動化
- コンテンツの追加・更新・削除時に自動的にURLを送信する。
- タイミング
- 変更後、できるだけ早く送信する。
- 頻度制限
- スパムと見なされないよう、適切な間隔で送信する。
- HTTPとHTTPSの混在
- 同一リクエストで両方のURLを送信可能
- URLエンコード
- URLは適切にエンコードし、RFC-3986標準に準拠させる。
実装例
Python
import requests
import json
# 単一URL送信
def submit_single_url(url, key):
endpoint = "https://api.indexnow.org/indexnow"
params = {
"url": url,
"key": key
}
response = requests.get(endpoint, params=params)
return response.status_code
# 複数URL送信
def submit_multiple_urls(host, key, url_list):
endpoint = "https://api.indexnow.org/indexnow"
data = {
"host": host,
"key": key,
"urlList": url_list
}
headers = {"Content-Type": "application/json; charset=utf-8"}
response = requests.post(endpoint, json=data, headers=headers)
return response.status_code
# 使用例
key = "31a0f3c4c69e46fda555417af06e6db3"
status = submit_single_url("https://www.example.com/page1", key)
print(f"Status: {status}")
トラブルシューティング
403エラーが発生する場合
以下の項目を確認する必要がある。
- キーファイルが正しい場所に配置されているか確認
- ファイル名が
{キー}.txtの形式になっているか確認 - ファイル内にキーが正しく記述されているか確認
- UTF-8エンコードで保存されているか確認
429エラーが発生する場合
- 送信頻度が高すぎる可能性がある。
- 一定時間待ってから再送信する。
参加検索エンジンの要件
IndexNowプロトコルを採用する検索エンジンは、以下の要件に同意する必要がある。
- 送信されたURLは、参加している全ての検索エンジンと自動的に共有される。
- 少なくとも1つの市場で顕著な存在感を持つか、検索市場と密接に関連している必要がある。
- URL送信数に大きく貢献する必要がある。
関連リンク