2026年8月14日 金曜日
AI時短ラボ
活用· 約34

Search Console APIのsites.addはエラーを返さないのにデータは1件も読めない──permissionLevelがsiteUnverifiedUserで止まる二段構え

Search Console APIのsites.addは成功時に空のレスポンスを返す仕様で、追加できたこと以上は何も伝えない。2026年8月14日3時53分(日本時間)にwwwとsc-domainの2プロパティを追加したところ、同じスクリプトの直後のsites.listはどちらもpermissionLevelがsiteUnverifiedUserで、同日16時09分に再取得してもsc-domainはsiteUnverifiedUserのまま、検索パフォーマンスもURL検査も403で1件も読めなかった。所有権確認をAPIで済ませようとすると、今度はGCPプロジェクトでSite Verification APIが未有効なためaccessNotConfiguredの403が返り、そのエラー本文に有効化用URLが入っている。

執筆・編集:
目次

Search Console APIのsites.addは、成功しても本文の無い空のレスポンスを返す。だから「エラーが出なかった=使えるようになった」ではない。プロパティの追加所有権の確認は別の工程で、追加しただけの状態はsites.listpermissionLevel: siteUnverifiedUserと表示され、この状態ではsearchAnalytics.queryもURL Inspectionも403で弾かれる。判定に使うべきなのはaddの戻り値ではなく、**直後に叩いたsites.listpermissionLevel**である。そして所有権確認までAPIで済ませようとすると、今度は別のAPI(Site Verification API)がGCPプロジェクトで有効化されていないという403に当たる。この記事は当サイトが2026年8月14日の未明に踏んだ、その二段構えの記録である。

  1. sites.addは成功時に空レスポンスを返す。 公式リファレンスの記載は「If successful, this method returns an empty response body.」だけで、所有権については何も返さない(2024年7月23日UTC最終更新・2026年8月14日確認)
  2. 追加直後のpermissionLevelsiteUnverifiedUserだった。 2026年8月14日3時53分(日本時間)にhttps://www.ai-jitan-hub.com/sc-domain:ai-jitan-hub.comを追加し、同じスクリプト内のsites.listで2件ともsiteUnverifiedUserを確認。同日16時09分に再取得してもsc-domain側はsiteUnverifiedUserのままで、検索パフォーマンスもURL検査も403だった
  3. 所有権確認をAPIでやろうとすると、GCPプロジェクト側の403に当たる。 Site Verification APIのgetTokenは3時50分と16時10分の2回とも403で、16時10分の本文はreason: accessNotConfigured、そこに有効化用のコンソールURLがそのまま入っていた(3時50分の記録は400字で切って保存していたため、突き合わせできたのはメッセージ前半のみ)

症状1:sites.addは何も言わずに通る

実際に流したコードはこれである(2026年8月14日3時53分38秒・日本時間、サービスアカウントのキーで実行)。実行時はpython3 -cの1行に潰していたので改行を入れ直し、importとキーのパス指定、見出しを出すprint(出力側の「■ …」の行)は省いた。API呼び出しの部分は原文のままである。

creds = service_account.Credentials.from_service_account_file(
    KEY, scopes=['https://www.googleapis.com/auth/webmasters'])
sc = build('searchconsole', 'v1', credentials=creds, cache_discovery=False)

for s in sc.sites().list().execute().get('siteEntry', []):
    print('  ', s['siteUrl'], '/', s['permissionLevel'])

for target in ['https://www.ai-jitan-hub.com/', 'sc-domain:ai-jitan-hub.com']:
    try:
        sc.sites().add(siteUrl=target).execute()
        print('追加を実行:', target, '→ エラーなし')
    except Exception as e:
        print('追加 失敗:', target, '→', type(e).__name__, str(e)[:180])

for s in sc.sites().list().execute().get('siteEntry', []):
    print('  ', s['siteUrl'], '/', s['permissionLevel'])

返ってきた出力をそのまま貼る。

■ 現在のプロパティと権限
   https://ai-jitan-hub.com/ / siteOwner

追加を実行: https://www.ai-jitan-hub.com/ → エラーなし
追加を実行: sc-domain:ai-jitan-hub.com → エラーなし

■ 追加後のプロパティ一覧
   https://ai-jitan-hub.com/ / siteOwner
   sc-domain:ai-jitan-hub.com / siteUnverifiedUser
   https://www.ai-jitan-hub.com/ / siteUnverifiedUser

例外は飛ばない。戻り値も空である。try/exceptで囲っているだけのコードは、この状態を「成功」と判定して次の処理へ進む。 実際に区別できたのは、直後のsites.listに出たpermissionLevelだけだった。

症状2:siteUnverifiedUserのプロパティは検索パフォーマンスもURL検査も403で弾かれる

追加から約12時間後の2026年8月14日16時09分(日本時間)、まだsiteUnverifiedUserのまま残っているsc-domain:ai-jitan-hub.comに対して、検索パフォーマンスとURL検査を投げ直した。返ってきた本文をそのまま貼る。

検索パフォーマンス(searchAnalytics.query):

<HttpError 403 when requesting
https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain%3Aai-jitan-hub.com/searchAnalytics/query?alt=json
returned "User does not have sufficient permission for site 'sc-domain:ai-jitan-hub.com'.
See also: https://support.google.com/webmasters/answer/2451999.".
Details: "[{'message': "User does not have sufficient permission for site
'sc-domain:ai-jitan-hub.com'. See also: https://support.google.com/webmasters/answer/2451999.",
'domain': 'global', 'reason': 'forbidden'}]">

(この検索パフォーマンス側の本文は、同じ呼び出しを22秒後の16時10分04秒に投げ直して採ったものである。16時09分42秒に走らせたスクリプトはマスク用の正規表現を\d{6,}にしていたため、末尾の2451999まで伏せた形でしか記録が残っていない。URL検査の本文は16時09分42秒のものをそのまま貼っている。)

URL検査(urlInspection.index.inspectinspectionUrlhttps://www.ai-jitan-hub.com/news/ai-glossary):

<HttpError 403 when requesting
https://searchconsole.googleapis.com/v1/urlInspection/index:inspect?alt=json
returned "You do not own this site, or the inspected URL is not part of this property.".
Details: "You do not own this site, or the inspected URL is not part of this property.">

ここが読み違えやすい。URL検査の403は「You do not own this site(このサイトを所有していない), or the inspected URL is not part of this property(または検査対象URLがこのプロパティに含まれていない)」と2つの原因をorで並べた1種類のメッセージで、今回はorの前半(所有していない)に当たっている。ドメインプロパティsc-domain:ai-jitan-hub.comについて公式ヘルプは「A Domain property aggregates data for all subdomains, protocols, and subpaths of the property.(ドメインプロパティは、そのプロパティのすべてのサブドメイン・プロトコル・サブパスのデータを集約する)」と書いている(2026年8月14日確認)ので、www.ai-jitan-hub.com配下のURLは範囲内である。範囲は合っていて、権限だけが無い。

当サイトは以前、同じ403メッセージのorの後半(プロパティ範囲外)に当たった記録を書いている。同じ文字列が、権限の話とホスト名の話の両方で返る。 どちらなのかは、メッセージではなくsites.listpermissionLevelを見ないと分からない。

なお、検索パフォーマンス側のエラーが案内しているhttps://support.google.com/webmasters/answer/2451999は、2026年8月14日時点でhttps://support.google.com/webmasters/answer/7687615(Managing owners, users, and permissions)へリダイレクトされる。

症状3:所有権確認をAPIでやろうとすると、別のAPIの403に当たる

「ならAPIで所有権確認まで済ませよう」と考えて、Google Site Verification APIのwebResource.getTokenを叩いた。2026年8月14日3時50分37秒(FILE方式)と、同日16時10分04秒(DNS_TXT方式)の2回、403で弾かれている。以下は16時10分のもので、GCPのプロジェクト番号だけ<プロジェクト番号>に置き換えてある(それ以外は原文のまま)。なお3時50分の記録はstr(e)[:400]で切って保存していたためDetailsまで残っておらず、突き合わせできたのはwait a few minutes for the actまでの範囲である(その範囲は一字一句一致した)。

<HttpError 403 when requesting https://www.googleapis.com/siteVerification/v1/token?alt=json
returned "Site Verification API has not been used in project <プロジェクト番号> before or it is
disabled. Enable it by visiting
https://console.developers.google.com/apis/api/siteverification.googleapis.com/overview?project=<プロジェクト番号>
then retry. If you enabled this API recently, wait a few minutes for the action to propagate
to our systems and retry.".
Details: "[{'message': '(直前と同じ本文が繰り返されるため省略)', 'domain': 'usageLimits',
'reason': 'accessNotConfigured', 'extendedHelp': 'https://console.developers.google.com'}]">

(「このプロジェクトではSite Verification APIがまだ使われていないか、無効になっている。次のURLを開いて有効化してから再試行すること。最近有効化したのであれば、反映まで数分待ってから再試行すること」)

このエラーは、直し方のURLを本文に含めて返してくる。 検索して回る前に、まずエラー本文を最後まで読む価値がある。Search Console APIの「Standard Error Messages」(2025年8月28日UTC最終更新・2026年8月14日確認)もaccessNotConfiguredをこう定義している。

Your project is not configured to access this API. Please use the Google Developers Console to activate the API for your project.

(あなたのプロジェクトはこのAPIにアクセスする設定になっていない。Google Developers Consoleでプロジェクトに対しAPIを有効化すること)

つまりこの403は、権限の話でもプロパティの話でもなく、GCPプロジェクトでAPIが有効化されていないという3つ目の層である。Search Console APIとSite Verification APIは別のAPIなので、片方が動いていても、もう片方は別途有効化が要る。

原因:公式リファレンスは「追加した」以上のことを書いていない

sites.addのリファレンス(2024年7月23日UTC最終更新・2026年8月14日確認)の記述は、要素としてはこれだけである。

Adds a site to the set of the user's sites in Search Console.

(Search Consoleにおける、そのユーザーのサイト集合にサイトを追加する)

Request body: Do not supply a request body with this method.

Response: If successful, this method returns an empty response body.

(リクエストボディ:このメソッドにリクエストボディを与えてはならない/レスポンス:成功した場合、このメソッドは空のレスポンスボディを返す)

このページ本文にはverifyverifiedownershippermissionという語が1つも出てこない(2026年8月14日にHTMLを取得して全文検索。ownerはサイト共通フッターの"connect with other website owners"に1回あるだけで、リファレンス本文には無い)。返るのは空のボディなので、呼び出し側はpermissionLevelを知りようがない。

permissionLevelが定義されているのはSitesリソースのページ(同じく2024年7月23日UTC最終更新)で、取り得る値は4つと書かれている。

permissionLevel: The user's permission level for the site.

Acceptable values are: "siteFullUser" / "siteOwner" / "siteRestrictedUser" / "siteUnverifiedUser"

(permissionLevel:そのサイトに対するユーザーの権限レベル。取り得る値は siteFullUser / siteOwner / siteRestrictedUser / siteUnverifiedUser)

ただしこのページは、それぞれが何を意味するかを説明せず、「Permissions in Search Console」というヘルプへのリンクだけを置いている。そのリンク先(Managing owners, users, and permissions・2026年8月14日確認)に、所有者の2種類が書かれている。

Verified owner: Someone who verified ownership of the property using a token to prove ownership (such as an HTML file uploaded to the website). To add or remove a verified owner, you must add or remove a token on the site.

Delegated owner: Someone granted ownership status by a verified owner without the use of a verification token (such as an HTML file or tag). To add or remove a delegated owner, an owner of any type simply adds or removes the new owner using the Search Console user management screen.

(確認済みオーナー:所有権を証明するトークン(ウェブサイトにアップロードしたHTMLファイルなど)を使ってプロパティの所有権を確認した人。確認済みオーナーを追加・削除するには、サイト上のトークンを追加・削除しなければならない/委任オーナー:確認済みオーナーによって、確認トークン(HTMLファイルやタグなど)を使わずに所有者の地位を与えられた人。委任オーナーの追加・削除は、いずれの種類のオーナーでもSearch Consoleのユーザー管理画面から行える)

トークンを置く経路と、画面から委任する経路の2本がある。 APIのsites.addはそのどちらでもない。

もう1つ、Site Verification APIの「Getting Started」(2025年8月28日UTC最終更新・2026年8月14日確認)に、APIで確認できる範囲がはっきり書かれている。

Verification for authenticated user only: The API can only verify ownership of sites or domains for the currently authenticated account. However, the authenticated user can delegate ownership to other users after their ownership of a site has been verified. Note that all owners are notified by email whenever changes are made to the ownership list.

(認証済みユーザーのみの確認:このAPIは、現在認証されているアカウントについてのみ、サイトやドメインの所有権を確認できる。ただし認証済みユーザーは、サイトの所有権が確認された後であれば、他のユーザーに所有権を委任できる。所有者リストに変更があると、すべての所有者にメールで通知される)

同ページは冒頭でも「All API calls need to be authorized by an authenticated user, and all API calls are executed in the context of the authenticated user's account.(すべてのAPI呼び出しは認証済みユーザーによる認可を必要とし、すべての呼び出しは認証済みユーザーのアカウントのコンテキストで実行される)」と書いている。

ここから、当サイトが実際にやらかした派生の罠が1つ出てくる。サービスアカウントのキーでAPIを叩いて追加したプロパティは、サービスアカウントというアカウントのリストに入る。運営者本人のGoogleアカウントでSearch Consoleを開いても、その画面には出てこない。 当サイトは2026年8月14日3時56分に「GSCを開けば未確認のプロパティが並んでいるはず」という手順書を書き、4時02分に「APIで追加したのはサービスアカウント側のリストで、別人格だった」と訂正している。sites.addのリファレンスの「the user's sites」の"the user"は、APIを叩いたアカウントのことである。

対処

  1. sites.addの戻り値を成功判定に使わない。 例外が飛ばないことと、そのプロパティが使えることは別である。追加した直後にsites.listを叩き、permissionLevelを出力する
  2. permissionLevelsiteUnverifiedUserなら、データ系APIは403になる前提で組む。 当サイトが実際に403を確認したのはsearchAnalytics.queryとURL Inspectionの2つで、sitemapsなど他のメソッドは試していない
  3. 403の本文を最後まで読んでから検索する。 accessNotConfiguredはGCPプロジェクトでAPIが無効という意味で、有効化用URLがエラー本文に入っている
  4. 所有権確認をAPIでやるなら、確認できるのは「APIを叩いているアカウント自身」の所有権だけ。 サービスアカウントに独自の確認トークンを置く必要がある
  5. 人間側がすでに確認済みなら、UIの「設定 > ユーザーと権限」からサービスアカウントを委任オーナーとして足す経路がある。 公式の定義では、委任オーナーは確認トークンを置かずに付与される
  6. UIで作業する人に「APIで追加したから画面に出ているはず」と案内しない。 出るのはAPIを叩いたアカウントのリストで、人間のアカウントのリストではない
  7. ドメインプロパティ(sc-domain:)はDNSの作業が終わるまでsiteUnverifiedUserのまま止まる。 公式ヘルプは「A Domain property requires you to verify ownership using DNS record verification, unless the property is on a Google product such as Blogger or Google Sites.(ドメインプロパティはDNSレコードによる所有権確認を必要とする。ただしBloggerやGoogle サイトのようなGoogle製品上のプロパティは除く)」と書いている。Site Verification公式は「Because domain ownership is more broadly applicable than site ownership, we recommend that you verify with domains whenever feasible.(ドメインの所有権はサイトの所有権より広く適用されるので、可能な限りドメインで確認することを推奨する)」と書くが、推奨されているからといって工程が消えるわけではない

観測条件(2026年8月14日・当サイト1件)

対象はai-jitan-hub.com(Next.js+Vercel)。Google Cloudのサービスアカウントのキーを使い、google-api-python-client経由で叩いた。時刻はすべて日本時間。

時刻 何をしたか 返ってきたもの
03:50:37 Site Verification API getTokenFILE方式) 403(本文は「Site Verification API has not been used in project …」。str(e)[:400]で切って保存したためreasonの記録は残っていない)
03:53:38 sites.addhttps://www.ai-jitan-hub.com/sc-domain:ai-jitan-hub.com 例外なし・空レスポンス
03:53:45 同じスクリプト内のsites.list www・sc-domainともsiteUnverifiedUser
04:02:28 「GSCの画面に未確認プロパティが出ているはず」という案内を撤回 (APIで追加した先はサービスアカウントのリストだった、と当サイトが訂正)
04:06:13 sites.listを再取得 www がsiteOwnerに変わっていた
16:09:42 sites.list+各プロパティにクエリ apex/www=siteOwner、sc-domain=siteUnverifiedUser。sc-domainは検索パフォーマンス・URL検査とも403
16:10:04 getTokenDNS_TXT方式)を再試行 403 accessNotConfigured(今回はDetailsまで全文取得)
16:13:15 両プロパティに日付次元で2026-01-01〜08-14を投げる www=2026-08-12の1日のみ(表示71・クリック1)/apex=2026-06-14〜08-12の60日(表示526・クリック19)

wwwプロパティは、作成した日(8月14日)より前の8月12日のデータを返している。 プロパティは後から作った箱で、データそのものはプロパティの作成を待っていない。ただし当サイトのwww側で返ったのは1日分だけで、7月10日のwww化以降を遡って埋めてはくれなかった。その理由は特定できていない。

なお、旧ホスト側のプロパティが308恒久リダイレクト後も集計を続けていた件、および同じプロパティ・同じ期間でも集計単位で表示回数が526/556/80と変わる件は、URLプレフィックス型の集計範囲の記事に分けて書いた。この記事は「追加と所有権確認が別工程である」ことだけを扱っている。

正直な但し書き

siteUnverifiedUserからsiteOwnerに変わった約12分半(3時53分45秒→4時06分13秒)に、画面で何が起きたのかを押さえていない。 当サイトは3時56分に「Search Consoleを開けばhttps://www.ai-jitan-hub.com/が未確認で並んでいるはずなので、HTMLタグ方式で確認を押す」という手順書を運営者に渡し、4時02分に「画面から自分でURLプレフィックス型プロパティを追加したうえで、HTMLタグ方式で確認を押す」へ書き換えている。4時06分にはwwwがsiteOwnerになっていた。ただし、運営者が画面でどの操作をしたか(所有権確認だけか、サービスアカウントの委任も行ったか)の記録は残していない。 確認トークン経由と委任経由のどちらが効いたのかは、この記録からは決められない。

sites.addが必ずsiteUnverifiedUserになるとは言えない。 当サイトが見たのはhttps://www.ai-jitan-hub.com/sc-domain:ai-jitan-hub.comの2件だけである。すでに所有権が確認済みのサイト、あるいは親ドメインの所有権を持つアカウントでsites.addを叩いた場合にどうなるかは試していない。

Site Verification APIを有効化して、所有権確認まで通した検証はしていない。 403で止めたままである。したがって「有効化すればAPIだけで確認まで完結する」とは書けない。書けるのは「有効化していないと403で始まらない」ところまでである。

エラー本文のGCPプロジェクト番号はマスクした。 それ以外の文字列(URL・reasondomainの値)は原文のままで、Details内で本文が繰り返される箇所だけ省略と明記した。

「本人のGoogleアカウントの画面に出てこない」は、当時のやり取りの記録に基づく。 2026年8月14日4時02分に当サイトが案内を訂正した事実は記録に残っているが、そのときの画面のスクリーンショットを本記事の執筆時に再確認したわけではない。公式リファレンスの「the user's sites」「in the context of the authenticated user's account」という記述と矛盾しない挙動だった、というところまでが言えることである。

引用は英語原文から採り、訳は当サイトで付けた。 Search Consoleヘルプの日本語ページには機械翻訳の注記が付く場合があるため、原文を優先した。訳の責任は当サイトにある。

効果はまだ測っていない。 sc-domain:ai-jitan-hub.comの所有権確認は2026年8月14日16時09分時点で未完了で、ドメインプロパティでデータがどう見えるかは分かっていない。

出典

シェア: ポスト はてブ

出典・参照資料

AIニュースの解説を動画でも

YouTubeでは注目ニュースの背景を解説し、Xでは新着記事をお知らせしています。

コメント

まだコメントはありません。最初のコメントを書いてみませんか?

AIについて聞きたいことはありますか?

質問箱で無料で受け付けています。回答は公開され、他の方の参考にもなります。

質問箱を見る →

新しい記事をメールで受け取る

AIの新しい発表を、出典付きで整理して届けます。

関連記事

AI時短ラボ
活用08.14読了36

www化の308を入れてもSearch Consoleの旧プロパティは集計を続ける──URLプレフィックス型で5週間データを取り逃した記録

出典 ─ Add a website or platf
AI時短ラボ
活用08.14読了31

URL Inspection APIのレスポンスを機械判定すると壊れる3点──coverageStateは表示文字列、ROBOTS_TXT_STATE_UNSPECIFIEDはrobots.txtの問題ではない

出典 ─ Method: index.inspect
AI時短ラボ
活用08.14読了42

IndexNowにGoogleは参加していない──418URL送ってもGoogleには渡らない仕組みと、鍵が無効なときに返る403 UserForbiddedToAccessSite

出典 ─ IndexNow - Home(indexn
AI時短ラボ
活用08.14読了26

出典URLの死活チェックで404だけ見てはいけない──1,517件を全数検査したら、HEADに404を返す公式ドキュメントと403の一次資料が出てきた

出典 ─ RFC 9110: HTTP Semanti
AI時短ラボ
活用08.14読了32

HTTP 200・79,525バイトなのに可視テキストは416文字──「取得できた」を200で数えてはいけない

出典 ─ RFC 9110: HTTP Semanti
AI時短ラボ
活用08.14読了24

macOSのawkはIGNORECASE=1をエラーも出さず無視する──Linux前提のワンライナーが「検出0件」で静かに通る

出典 ─ GAWK: Effective AWK Pr
AI時短ラボ
活用08.14読了36

Vercelの自動生成ドメインがGSCの参照元に117本入っていた──*.vercel.appと「Duplicate, Google chose different canonical than user」を全351記事で実測

出典 ─ Accessing Deployments
AI時短ラボ
活用08.14読了21

YouTubeのRSSフィードの404はUser-Agentのせいではなかった──UAヘッダごと削除しても200が返り、犯人はchannel_idだった

出典 ─ RFC 9110: HTTP Semanti