---
title: "Microsoft Search APIの使い方｜SharePoint検索APIの実装とGraph・REST APIの違い【2026年版】"
url: "https://www.issoh.co.jp/tech/details/7496/"
published: 2025-06-30
updated: 2026-11-03
categories: ["REST API"]
publisher: "株式会社一創"
---

# Microsoft Search APIの使い方｜SharePoint検索APIの実装とGraph・REST APIの違い【2026年版】

SharePointを検索するAPIは、Microsoft Graphの `POST /search/query`（Microsoft Search API）と、SharePointサイトの `/_api/search/query`（SharePoint Search REST API）の2系統です。新規の実装はGraph側が基本ですが、結果ソースやFQL、5万件を超える走査が要るならREST側を使います。この記事では、両方の実装で引っかかる制約を公式ドキュメントの記述どおりに整理します。entityTypesの組み合わせ、size上限、アプリ権限のregion必須、RESTのレスポンスの読み方とページングが中心です。あわせて、生成AI向けのCopilot Retrieval APIとの使い分けも扱います。

## まとめ：SharePoint検索APIを選んで実装するときの要点

- Microsoft Search APIのエンドポイントは `POST https://graph.microsoft.com/v1.0/search/query`。`requests` は配列ですが、現在処理されるsearchRequestは1回に1件だけです。
- 複数のentityTypesを混在できるのは、ファイル・サイト・外部データ系と検索回答系の2つのグループ内です。message・event・chatMessageはそれぞれ単独でしか指定できません。
- 1ページの件数は、message・eventが25件まで、SharePoint・OneDriveは概要ページで1000件までです。ただしsearchRequestのリファレンスは上限を500としているので、公式推奨の200件前後で設計すると安全です。
- アプリケーション権限で検索するときは `region` が必須で、既定では共有コンテンツしか検索されません。`Sites.Selected` は権限表にありません。
- SharePoint Search REST APIの結果は `PrimaryQueryResult.RelevantResults.Table.Rows` の各行に、`Cells` のKey/Valueの配列として入ります。`TrimDuplicates` の既定がtrueなので、件数が画面と合わないときはまずここを疑います。
- RESTのアプリのみの検索は、Sites.Read.All以上で個人のOneDriveまで含む全コンテンツが対象になり、1秒あたり25リクエストで調整されます。
- RESTの `StartRow` は50,000が上限です。それより深く走査するなら、`docid` の昇順と `IndexDocId` の条件で次ページを取ります。
- SharePoint REST API自体は廃止されていません。2026年4月2日に止まったのはAzure ACSとSharePoint Add-Inで、アプリのみのアクセスはMicrosoft Entra IDアプリの証明書で認証します。
- 生成AIに渡すテキスト断片が欲しいならCopilot Retrieval APIが候補です。1回25件まで、ユーザーあたり1時間200リクエストまでで、KQLの構文を誤ると絞り込みが効かないまま実行されます。

## SharePoint検索に使う4つのAPIの選び分け

Microsoft 365のデータを検索するAPIは1つではありません。「SharePoint Search API」「Microsoft Graph Search」「Microsoft Search API」と呼び名が似ているため取り違えやすいので、まず次の4本を区別してください。

| API                        | エンドポイント                 | 検索範囲                     | 向く用途           |
| -------------------------- | ----------------------- | ------------------------ | -------------- |
| Microsoft Search API       | POST /search/query      | ファイル・メール・予定・チャット・外部データ   | 横断検索UI         |
| driveItem search           | GET …/root/search(q=)   | 1つのドライブやフォルダ配下           | 場所が決まったファイル探し  |
| SharePoint Search REST API | /\_api/search/query     | SharePointの検索インデックス      | 結果ソース・FQL・大量走査 |
| Copilot Retrieval API      | POST /copilot/retrieval | SharePoint・OneDrive・コネクタ | RAGのテキスト断片取得   |

driveItemの `search(q=)` は、ファイル名・メタデータ・ファイル内容をまとめて照合し、`$top`・`$select`・`$orderby` などのODataクエリパラメーターを使えます。サイトやフォルダが決まっているなら、こちらのほうが単純です。ただし[driveItem searchの公式リファレンス](https://learn.microsoft.com/ja-jp/graph/api/driveitem-search)には `This method doesn't support the Sites.Selected application permission.` と明記されています。特定サイトだけに権限を絞ったアプリでは、パス指定で `children` をたどる実装に切り替えることになります。

迷ったときの基準は次のとおりです。メールやTeamsも含めて横断するならMicrosoft Search API、SharePointの結果ソース・ランキングモデル・FQLを使うならSharePoint Search REST APIを選びます。LLMに根拠の文章を渡すならRetrieval APIです。Graph全体の認証方式やスロットリングは[Microsoft Graph APIの権限設計と呼び出し手順](/tech/details/18719/)で扱っています。

## 検索できるentityTypesと組み合わせの制約

検索対象はsearchRequestの `entityTypes` で指定します。次の表は主に委任権限での検索に必要な権限を示します。アプリケーション権限では同じ対象をすべて検索できるわけではなく、search/queryの権限表に掲載されているのはFiles.Read.AllとSites.Read.Allです。

| entityType               | 対象                  | 必要な権限                                  |
| ------------------------ | ------------------- | -------------------------------------- |
| driveItem                | ファイル・フォルダ・ページ・ニュース  | Files.Read.All または Sites.Read.All      |
| listItem                 | リストアイテム（ファイルも含む）    | Sites.Read.All                         |
| site / list / drive      | サイト・リスト・ドキュメントライブラリ | Sites.Read.All（driveはFiles.Read.Allも可） |
| message / event          | メール・予定表             | Mail.Read / Calendars.Read             |
| chatMessage              | Teamsのメッセージ         | Chat.Read または ChannelMessage.Read.All  |
| externalItem             | Copilotコネクタの取り込みデータ | ExternalItem.Read.All                  |
| acronym / bookmark / qna | 管理者が登録した検索回答        | Acronym.Read.All など                    |

[Search APIの概要ページ](https://learn.microsoft.com/ja-jp/graph/api/resources/search-api-overview)の対応表で組み合わせ可（True）になっているのは、次のグループの中だけです。

- driveItem・listItem・site・list・drive・externalItem は相互に混在できます。
- acronym・bookmark・qna は相互に混在できます。
- message、event、chatMessage、person は、それぞれ単独でしか指定できません。

メールとファイルを1つの画面に並べたい場合は、要求を2回に分けてクライアント側でまとめます。`requests` が配列でも、サービスが処理するのは1回に1件だからです。なお `contentSources` はexternalItemのときだけ有効です。Microsoft Graph connectorsは現在「Microsoft 365 Copilot connectors」に改称されており、公式ドキュメントも `formerly Microsoft Graph connectors` と併記しています。

## search/queryの基本リクエストとページング

以下は、委任権限でSharePointとOneDriveのWord文書を検索し、必要な列を25件ずつ受け取るHTTP要求例です。Files.Read.AllまたはSites.Read.Allを持つMicrosoft Graph向けアクセストークンを使用します。

```
POST https://graph.microsoft.com/v1.0/search/query
Content-Type: application/json
Authorization: Bearer {Microsoft Graph向けアクセストークン}

{
  "requests": [
    {
      "entityTypes": ["driveItem"],
      "query": { "queryString": "見積 filetype:docx" },
      "fields": ["name", "webUrl", "lastModifiedDateTime", "createdBy"],
      "from": 0,
      "size": 25
    }
  ]
}
```

レスポンスは `value[0].hitsContainers[0].hits` に結果が並び、`moreResultsAvailable` で続きの有無を判定します。`from` をずらして次のページを取りに行きます。

### size上限の公式記述の差異とfromによるページング

公式ドキュメントの記述が2か所で食い違っています。[searchRequestのリファレンス](https://learn.microsoft.com/ja-jp/graph/api/resources/searchrequest)はsizeを `The maximum value is 500.` としています。一方、Search APIの概要ページは既定25件・最大1000件とし、SharePointとOneDriveについて `A reasonable page size is 200.` と推奨しています。どちらの上限でも問題が起きないよう、1ページ目は25件、以降は200件以下で増やす実装が安全です。概要ページが例示しているページングは次のとおりです。

| ページ | from | size |
| --- | ---- | ---- |
| 1   | 0    | 25   |
| 2   | 25   | 50   |
| 3   | 75   | 75   |
| 4   | 150  | 100  |

message・eventは別の制約を持ちます。sizeの上限は25件で、1ページ目のfromが0でないとHTTP 400になります。また、関連度順の結果をページングすると、同じアイテムが複数のページに現れることがあります。重複を避けたいなら、並べ替えを固定するよう公式に推奨されています。

### fieldsで返るプロパティとSharePointの独自列

`fields` は、返すプロパティを絞る点でODataの `$select` に相当します。スキーマに無い名前や取得可能でない名前は、エラーにならず無視されます。結果に列が無いときは、まず列名の綴りを疑ってください。スキーマで取得可能にした拡張列を返せるのはlistItemとexternalItemだけです。ドキュメントライブラリの独自列（例：案件番号）を取りたい場合は、entityTypeにdriveItemではなくlistItemを指定します。fieldsを省略した場合、listItemは独自列を返しません。externalItemは、コネクタのスキーマで取得可能にした列をすべて返します。

## KQLでの絞り込み・並べ替え・集計

`queryString` には、キーワード・AND/OR・プロパティ制限をKQLで書けます。[SharePointのKQL構文リファレンス](https://learn.microsoft.com/ja-jp/sharepoint/dev/general-development/keyword-query-language-kql-syntax-reference)の例は、`filetype:docx`（Word文書）、`filename:budget.xlsx`（ファイル名）、`author:"John Smith"`（作成者）です。実装時にはまりやすい規則が3つあります。

- プロパティ名・演算子・値のあいだに空白を入れると、プロパティ制限ではなくフリーテキスト検索として扱われます（`author: "John Smith"` は不可）。
- ワイルドカード `*` は後方にしか付けられません。`title:"Advanced Sear*"` は有効ですが、前方一致以外の部分一致は書けません。
- プロパティ制限の長さは2,048文字までです。

「ファイル名の一部で探したい」という要件では、`filename:見積*` のように語の前方一致を指定できます。ただし、ファイル名全体の先頭一致とは限らず、検索インデックスでの語の分割に左右されます。末尾が一致するファイルを探す書き方はKQLにありません。要件を「語の前方一致で足りるか」まで確認してから設計してください。KQLはGraphとRESTで共通なので、ここで書いた条件はどちらのAPIでもそのまま使えます。

### sortPropertiesで並べ替えできる対象と上限

既定の並び順は、message・eventが日付順、SharePoint・OneDrive・person・コネクタが関連度順です。`sortProperties` は最大5件まで指定できます。対象のプロパティは検索スキーマでsortableでなければならず、条件を満たさないとHTTP 400が返ります。また、関連度順をsortPropertiesで明示することはできません。message・eventは並べ替えに対応していません。externalItemについては、概要ページの既知の制限は非対応としていますが、並べ替えの解説ページはrefinableなプロパティなら対応すると書いており、記述が割れています。コネクタのデータを並べ替える設計なら、実テナントで確認してから採用してください。

```
{
  "requests": [
    {
      "entityTypes": ["driveItem"],
      "query": { "queryString": "filetype:pptx" },
      "sortProperties": [
        { "name": "lastModifiedDateTime", "isDescending": true }
      ],
      "aggregations": [
        { "field": "fileType", "size": 10, "bucketDefinition": { "sortBy": "count", "isDescending": true, "minimumCount": 0 } }
      ],
      "from": 0,
      "size": 50
    }
  ]
}
```

### aggregationsによる絞り込みと重複の除外

`aggregations` は、SharePointでいう絞り込み（refiner）です。driveItem・listItem・list・externalItemのrefinableなプロパティで使えます。レスポンスのバケットにある `aggregationFilterToken` を、トークン単体ではなくフィールド名と組み合わせた `{field}:"{aggregationFilterToken}"` 形式の文字列にして次の要求の `aggregationFilters` 配列に入れると、そのバケットの結果に絞れます。これで「ファイル種別で絞る」UIを組めます。指定したプロパティ値が共通する結果をまとめたい場合、委任権限では `collapseProperties` がv1.0で使え、対象はdriveItem・listItem・drive・list・site・externalItemです。多段で指定するときは、後の段のlimitを前の段以下にしないとHTTP 400になります。`trimDuplicates` の解説はbetaエンドポイントの例で書かれており、v1.0のsearchRequestのプロパティ一覧には載っていません。

## 委任権限とアプリケーション権限の設計

search/queryの権限表では、委任権限（職場・学校アカウント）の最小権限がMail.Read、アプリケーション権限の最小権限がFiles.Read.Allです。個人のMicrosoftアカウントは非対応です。実際に必要な権限は、前の章の表のとおりentityTypeで決まります。委任権限の検索はサインインしたユーザーの代理で実行され、公式ドキュメントのとおり `Search results are scoped to enforce any access control applied to the items.` です。

### アプリケーション権限のregion指定と既定の検索対象

[アプリケーション権限での検索の解説](https://learn.microsoft.com/ja-jp/graph/search-concept-searchall)によると、検索は1つの地理的リージョンに限られます。searchRequestに `region` を指定しないと実行できません。値はsiteCollectionリソースの `dataLocationCode` で取得します。既定では共有コンテンツだけが検索対象で、個人のプライベートなコンテンツは含まれません。含めたい場合は `sharePointOneDriveOptions.includeContent` に `privateContent` を指定します（値は `sharedContent` と `privateContent`）。ただし `privateContent` の初回要求で専用インデックスの構築が始まり、完了までは共有コンテンツだけが返ります。公式は中〜大規模テナントで数日〜1週間かかるとし、3か月間 `privateContent` の要求が無いとインデックスは廃棄されます。また、アプリケーション権限では深いページングが非対応とされ、fromが1000を超える場合が例示されています。全件走査を前提にした用途には適しません。

```
{
  "requests": [
    {
      "entityTypes": ["driveItem"],
      "query": { "queryString": "契約書" },
      "region": "{dataLocationCodeの値}",
      "sharePointOneDriveOptions": { "includeContent": "privateContent,sharedContent" },
      "from": 0,
      "size": 25
    }
  ]
}
```

アプリケーション権限のFiles.Read.Allは、組織のすべてのSharePointとOneDriveのファイルを読める権限です。search/queryはSites.Selectedによるアプリケーション権限の制限には対応していません。KQLのPath条件で結果を特定サイトに絞れても、アプリの権限そのものは全サイトに及びます。また、画面の利用者本人の権限に自動で絞られることもありません。検索範囲を絞りたい要件なら、委任権限でユーザー本人の権限範囲に閉じる設計を先に検討してください。共有設定が緩いテナントでは、検索で思わぬ文書が見えてしまいます。事前に[過剰共有の可視化とRCD・DLPの設定](/tech/details/17565/)で棚卸ししておくと安全です。

## SharePoint Search REST API（\_api/search/query）の実装手順

SharePoint Search REST APIは、SharePointサイトのURLの下にある検索エンドポイントです。GETは `/_api/search/query`、POSTは `/_api/search/postquery` で、検索候補は `/_api/search/suggest` から取れます。KQLに加えてFQLも送れ、Graphには無い `SourceId`（結果ソース）や `RankingModelId`（ランキングモデル）を指定できます。Graphの概要ページは、カスタム検索スキーマや結果ソースがSearch APIの動作を妨げうると注意しています。サイトごとに作り込んだ検索を再現したいなら、REST側が確実です。パラメーターの既定値は[SharePoint Search REST APIの概要](https://learn.microsoft.com/ja-jp/sharepoint/dev/general-development/sharepoint-search-rest-api-overview)に一覧があります。

### GETとPOST（postquery）の書き方

GETはパラメーターをURLに並べます。文字列の値は単引用符で囲み、`selectproperties` はカンマ区切りの1つの文字列です。結果は既定でXMLなので、JSONで受けるには `Accept` ヘッダーを付けます。

```
GET https://contoso.sharepoint.com/sites/sales/_api/search/query?querytext='filetype:docx'&selectproperties='Title,Path,Author'&rowlimit=50&startrow=0
Accept: application/json;odata=nometadata
Authorization: Bearer {SharePoint向けアクセストークン}
```

URLの長さ制限を超える条件や、`ReorderingRules` を使う場合はPOSTにします。POSTでは `SelectProperties` と `RefinementFilters` が文字列の配列になり、GETとデータ型が変わる点に注意してください。本文は `request` で包み、`odata=verbose` の形式では配列を `results` の下に入れます。

```
POST https://contoso.sharepoint.com/sites/sales/_api/search/postquery
Accept: application/json;odata=nometadata
Content-Type: application/json;odata=verbose
Authorization: Bearer {SharePoint向けアクセストークン}

{
  "request": {
    "__metadata": { "type": "Microsoft.Office.Server.Search.REST.SearchRequest" },
    "Querytext": "見積 filetype:docx",
    "SelectProperties": { "results": ["Title", "Path", "Author", "DocId"] },
    "RefinementFilters": { "results": ["fileExtension:equals(\"docx\")"] },
    "RowLimit": 50,
    "ClientType": "ContentSearchRegular"
  }
}
```

呼び出し元のURLにも意味があります。`_api/search` の前に付けたサイトのURLで、そのサイトの既定の結果ソースとクエリルールが使われます（パラメーターで上書きしない限り）。サイトに個別の検索設定が無ければ、どのサイトから呼んでも結果は同じです。同じ `querytext` でもサイトによって結果が違うときは、そのサイトの結果ソースを先に確認してください。

### PrimaryQueryResultからの行の取り出し

レスポンスの中身は1つのテーブルです。公式のレスポンス例では、`PrimaryQueryResult` の下の `RelevantResults` に、返した件数の `RowCount`、ヒット総数の `TotalRows`、重複を含めた総数の `TotalRowsIncludingDuplicates` が並びます。結果の行は `Table.Rows` にあり、各行は `Cells` というKey・Value・ValueTypeの配列です。列名がプロパティになっていないので、そのままでは扱いにくい形をしています。

`odata=verbose` で受けると、全体が `d.query` に包まれ、配列も `results` の下に入ります（`d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results`）。`odata=nometadata` ならこの包みが無くなり、短いパスで読めます。次のPython関数は、nometadata形式の応答から検索結果の各行を取り出し、CellsのKeyとValueを「列名→値」の辞書に変換する例です。

```
def rows_to_dicts(result):
    """SharePoint Search REST (odata=nometadata) の応答を行ごとの辞書に変換する"""
    relevant = result["PrimaryQueryResult"]["RelevantResults"]
    rows = relevant["Table"]["Rows"]
    items = [{c["Key"]: c["Value"] for c in row["Cells"]} for row in rows]
    return relevant["TotalRows"], items
```

各セルには値の型が `ValueType`（例：`Edm.Int64`）として別に入るので、数値や日付として扱う列は `ValueType` を見て変換してください。`RefinementResults` は絞り込みを要求したときだけ値が入り、要求しない場合はnullです。

### RefinementFiltersによる絞り込みとTrimDuplicatesによる件数差

絞り込みは2段階で組みます。まず `refiners='author,size'` のように集計したい管理プロパティを指定すると、`RefinementResults` に値ごとの件数が返ります。次の要求で `refinementfilters='fileExtension:equals("docx")'` のようにFQLの条件を渡すと、その値に絞れます。KQLの `querytext` と違い、ここはFQLの構文です。複数条件は `and(...)` で組み合わせます。

件数がずれる典型的な原因は `TrimDuplicates` です。既定値はtrueで、重複とみなした文書を結果から外します。コピーして名前だけ変えたファイルのように内容が同じ文書は、1件しか一覧に出ないことがあります。全件を数える処理や、ライブラリの棚卸しでは `trimduplicates=false` を付けてください。もう1つの上限は行数です。[SharePoint Onlineの検索の制限](https://learn.microsoft.com/ja-jp/sharepoint/search-limits)では、1つの結果セットの行数は500が上限（Boundary）です。`RowLimit` を大きくしても1回で全件は取れないので、ページングを前提にしてください。

### 5万件を超える結果のIndexDocIdによるページング

`StartRow` で開始位置をずらすページングは、50,000が上限です。公式は、これを超えるとSharePointに調整（スロットリング）されるおそれがあるとしています。大量の結果を最後までたどるには、[大量の結果セットのページング](https://learn.microsoft.com/ja-jp/sharepoint/dev/general-development/pagination-for-large-result-sets)で案内されている方法を使います。`docid` の昇順で並べ、前のページの最後の行の `DocId` より大きいものを次の条件にします。

```
1ページ目: /_api/search/query?querytext='sharepoint'&sortlist='docid:ascending'
2ページ目: /_api/search/query?querytext='sharepoint indexdocid>10'&sortlist='docid:ascending'
3ページ目: /_api/search/query?querytext='sharepoint indexdocid>20'&sortlist='docid:ascending'
```

この方法にはページ数の上限がありません。最後の行の `DocId` は `Cells` から取るので、`selectproperties` に `DocId` を含めておくと確実です。関連度順ではなくなるため、検索インデックス内の一致結果を走査する処理に向きます。ただし、検索対象から除外されたコンテンツは取得できないため、移行前の全件棚卸しでは検索結果だけを完全な一覧として扱わないでください。Graph側はアプリケーション権限でfromが1000を超える深いページングに対応していないので、全件走査が要件ならREST側でこの方式を選びます。

### アプリのみのアクセスの証明書認証と廃止済みの方式

「SharePoint REST APIは廃止されたのか」という疑問には、廃止されていないと答えられます。止まったのは認証と拡張の仕組みです。検索まわりで非推奨になっているのは、旧来のQuery Webサービス（`/_vti_bin/search.asmx`）です。[Azure ACSの廃止告知](https://learn.microsoft.com/ja-jp/sharepoint/dev/sp-add-ins/retirement-announcement-for-azure-acs)のとおり、Azure ACSは新規テナントでは2024年11月1日に使えなくなり、既存テナントでも2026年4月2日に完全廃止されました。SharePoint Add-Inも同じ日に全テナントで停止しています。公式の廃止FAQは、サーバー側のコードはMicrosoft Graphを第一候補にし、Graphに必要な機能が無ければSharePoint RESTかCSOMを使うよう案内しています。ACSで発行したクライアントIDとシークレットで検索RESTを呼んでいたバッチは、移行していなければこの日以降は認証で失敗します。

現在、アプリのみのアクセスでSharePointのCSOM・REST APIを呼ぶには、Microsoft Entra IDアプリに証明書を登録します。[Entra IDでのアプリのみのアクセスの手順](https://learn.microsoft.com/ja-jp/sharepoint/dev/solution-guidance/security-apponly-azuread)は `you must use a certificate` と書いており、クライアントシークレットでは通りません。トークンの対象はGraphではなく `https://{テナント}.sharepoint.com` です。

アプリのみの検索は、Graphのアプリケーション権限と既定の範囲が逆です。[SharePoint Onlineの調整に関する公式解説](https://learn.microsoft.com/ja-jp/sharepoint/dev/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online)によると、Sites.Read.All以上を持つアプリはSharePoint Onlineの全コンテンツを検索でき、ユーザー個人のOneDriveも含まれます。Graphのように共有コンテンツだけに絞る既定はありません。さらに、この権限での検索は1秒あたり25リクエストで調整され、超えるとHTTP 429が返ります。429を受けたら、同じ種類の権限で投げている検索要求をすべて止めて待つよう求められており、送り続けると解除までの時間が延びます。並列で全件を走査するバッチは、ここで止まりやすいので注意してください。GraphとMSALへの移行手順は[Azure AD Graph廃止後のEntra IDアプリ移行手順](/tech/details/17491/)にまとめています。

## Microsoft Search APIの既知の制限とREST APIを選ぶ条件

Microsoft Search APIの公式の既知の制限のうち、設計を変える必要があるものを挙げます。

- SharePoint検索のカスタマイズ（独自の検索スキーマや結果ソース）は、Search APIの動作を妨げることがあります。
- サイトレベルの検索スキーマは使えません。テナントレベルか既定の検索スキーマで管理プロパティを定義します。
- ゲストによる検索は、acronym・bookmark・message・chatMessage・event・person・qna・externalItemに対応していません。
- driveを検索する場合は、ドキュメントライブラリ名に含まれる語をqueryStringに入れる必要があります。`*` で全ライブラリを列挙することはできません。
- XRANKによる順位の引き上げは、message・event・externalItemなどでは使えません。

このため、サイトごとに作り込んだ結果ソースやランキングを再現する要件では、Search APIを第一候補にせずSharePoint Search REST APIを選びます。特定サイトだけにアプリの権限を限定する要件では、検索を使わず、Sites.Selectedに対応する取得APIとサイトへの明示的な権限付与を組み合わせます。社内ポータルに検索Webパーツを置くだけで済むなら、APIを書かずに[SharePointの社内ポータル構成](/tech/details/16153/)の範囲で解決できる場合もあります。検索APIを業務システムに組み込む設計から任せたい場合は、[Microsoft 365・Copilot導入支援](/service/erp%5Fcrm/microsoft365/)で相談を受けています。

## RAG用途でのSearch APIとCopilot Retrieval APIの使い分け

生成AIの根拠データとしてMicrosoft 365の文書を使う場合、Search APIでファイルを探して本文を取り出し、自前で分割・ベクトル化することもできます。これに対し、Microsoft 365 Copilot Retrieval APIは、Copilotが使うハイブリッドインデックスから関連するテキスト断片を直接返します。エンドポイントは `POST https://graph.microsoft.com/v1.0/copilot/retrieval` で、betaにも同じ操作があります。APIそのものは2025年11月に一般提供（GA）が発表されています。

| 項目                     | Retrieval APIの仕様                 |
| ---------------------- | -------------------------------- |
| 対象データ                  | SharePoint・OneDrive・Copilotコネクタ  |
| 権限方式                   | 委任権限のみ                           |
| SharePoint・OneDriveの権限 | Files.Read.AllとSites.Read.Allの両方 |
| コネクタの権限                | ExternalItem.Read.All            |
| maximumNumberOfResults | 最大25                             |
| queryString            | 1,500文字まで                        |
| レート                    | ユーザーあたり1時間200リクエスト               |
| 意味・ハイブリッド検索            | doc・docx・pptx・pdf・aspx・oneのみ     |
| ライセンス                  | Copilotアドオンで追加費用なし               |
| 従量課金（プレビュー）            | 1 APIコール0.10ドル                   |

[Retrieval APIの概要](https://learn.microsoft.com/ja-jp/microsoft-365-copilot/extensibility/api/ai-services/retrieval/overview)によると、従量課金はプレビューでSLAはありません。有効化時と利用期間中は、テナント内に少なくとも1つのMicrosoft 365 Copilotライセンスが必要です。対象はSharePointやコネクタといったテナント単位のデータソースだけで、OneDriveは使えません。実装で最も注意すべき点は、既知の制限にある `If the filterExpression request parameter has incorrect KQL syntax, the query successfully executes with no scoping.` です。KQLを書き間違えてもエラーにならず、絞り込みが外れたまま検索されます。「承認済みライブラリだけを根拠にする」ためにfilterExpressionを使う設計では、単体テストで絞り込みが効いているかを検証してください。返る結果と断片は順不同なので、LLMの入力トークン数に厳しい制限がない限り、maximumNumberOfResultsを小さく制限せず、返された断片をすべてLLMへ渡すことが推奨されています。キーワード一致とベクトル検索を組み合わせる考え方は[ハイブリッド検索の仕組みとRRF](/tech/details/8014/)で解説しています。

Copilotライセンスが無く、OneDriveも対象に含めたい場合は、Retrieval APIの従量課金では届きません。Search APIと自前の分割処理が残る選択肢になります。

## よくある質問

### Microsoft Search APIとMicrosoft Graph APIは別物ですか？

別物ではありません。Microsoft Search APIは、Microsoft Graphの一部として提供される `/search/query` などの検索系APIの総称です。認証はほかのGraph APIと同じくMicrosoft Entra IDのアクセストークンで行い、Graph Explorerからも試せます。

### SharePoint REST APIは廃止されましたか？

廃止されていません。`/_api/search/query` と `/_api/search/postquery` は現行のドキュメントに掲載されています。2026年4月2日に止まったのはAzure ACSとSharePoint Add-Inです。アプリのみのアクセスでは、Microsoft Entra IDアプリに証明書を登録して認証します。ACS廃止で止まった範囲と、移行後の認証・権限の設定は[SharePoint APIとは？REST APIとGraphの使い分け](https://www.issoh.co.jp/tech/details/19261/)で解説しています。

### 検索結果は1回に何件まで取得できますか？

Graphのmessage・eventは1ページ25件までです。SharePoint・OneDriveは、概要ページでは1000件、searchRequestのリファレンスでは500件が上限と記述が割れています。公式推奨の200件前後でページングしてください。RESTは1回の結果セットが最大500行です。`StartRow` は50,000までで、それより先はIndexDocIdの条件で取ります。

### 個人のMicrosoftアカウントでも使えますか？

使えません。search/queryの権限表では、個人のMicrosoftアカウントは最小権限・上位権限とも非対応です。職場または学校アカウントのテナントが必要です。

### Microsoft Graph connectorsで取り込んだデータも検索できますか？

できます。entityTypesに `externalItem` を指定し、`contentSources` に接続を指定します。Microsoft Graph connectorsは現在「Microsoft 365 Copilot connectors」という名称です。権限はExternalItem.Read.Allが必要です。

## 関連記事

- [Microsoft Graph APIとは？できること・権限設計とPythonでの呼び出し手順【2026年10月】](/tech/details/18719/)
- [Entra IDのアプリをMicrosoft GraphとMSALへ移行する手順｜Azure AD Graph廃止後の実装](/tech/details/17491/)
- [SharePointで社内ポータルを作る実装手順｜サイト構成・Webパーツ・権限・ナビ設計を上限値から解説](/tech/details/16153/)
- [Microsoft 365 Copilotの情報漏洩対策｜過剰共有の可視化とRCD・DLPの設定手順](/tech/details/17565/)
- [ハイブリッド検索とは？RAGでBM25とベクトル検索を統合する仕組み・RRF・実装コード](/tech/details/8014/)

---

出典: [Microsoft Search APIの使い方｜SharePoint検索APIの実装とGraph・REST APIの違い【2026年版】](<https://www.issoh.co.jp/tech/details/7496/>)（株式会社一創）
