Skip to content

Commit e807dba

Browse files
authored
Merge pull request #313866 from EdB-MSFT/graph-api
graph rest api
2 parents 2095b52 + 307b3fb commit e807dba

2 files changed

Lines changed: 331 additions & 0 deletions

File tree

articles/sentinel/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,8 @@
627627
href: datalake/create-graphs-with-ai.md
628628
- name: GQL reference for Sentinel custom graph
629629
href: datalake/gql-reference-for-sentinel-custom-graph.md
630+
- name: Graph REST API
631+
href: datalake/graph-rest-api.md
630632
- name: Microsoft Sentinel MCP server
631633
items:
632634
- name: Microsoft Sentinel MCP server overview
Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
---
2+
title: Graph REST APIs for custom graphs
3+
titleSuffix: Microsoft Security
4+
description: Learn how to use the Graph REST APIs to list and query custom graphs in the Microsoft Sentinel data lake.
5+
author: EdB-MSFT
6+
ms.service: microsoft-sentinel
7+
ms.subservice: sentinel-platform
8+
ms.topic: reference
9+
ms.date: 03/30/2026
10+
ms.author: edbaynash
11+
ms.collection: ms-security
12+
13+
#Customer intent: As a security engineer, I want to use the Graph REST APIs to programmatically list and query custom graphs in my Microsoft Sentinel data lake so that I can automate graph-based security analysis.
14+
---
15+
16+
# Graph REST APIs for custom graphs
17+
18+
The Graph REST APIs let you list and query custom graphs in your Microsoft Sentinel data lake. Use these APIs to programmatically interact with your custom graphs from any HTTP client, automation pipeline, or custom application.
19+
20+
For more information on creating custom graphs, see [Create custom graphs in the security data lake](create-custom-graphs.md).
21+
22+
## Authentication
23+
24+
The Graph REST APIs use OAuth 2.0 bearer token authentication. To call the APIs, obtain an access token from Microsoft Entra ID and include it in the `Authorization` header of each request.
25+
26+
### Get an access token
27+
28+
1. Register an application in Microsoft Entra ID, or use an existing app registration. For more information, see [Register an application](/entra/identity-platform/quickstart-register-app).
29+
1. Grant the application the required permissions for Microsoft Defender XDR.
30+
1. Request an access token using the OAuth 2.0 client credentials flow or on behalf of a signed-in user.
31+
32+
### Include the token in requests
33+
34+
Add the token to the `Authorization` header of every API request:
35+
36+
```http
37+
Authorization: Bearer <access_token>
38+
```
39+
40+
## Base URL
41+
42+
All Graph REST API endpoints use the following base URL:
43+
44+
```http
45+
https://api.securityplatform.microsoft.com
46+
```
47+
48+
## List graphs
49+
50+
List all custom graphs available in your tenant.
51+
52+
### Request
53+
54+
```http
55+
GET https://api.securityplatform.microsoft.com/graphs/graph-instances?graphTypes=Custom
56+
```
57+
58+
No request body is required.
59+
60+
### Response
61+
62+
```json
63+
{
64+
"value": [
65+
{
66+
"name": "custom_graph_10",
67+
"mapFileName": "custom_graph_10",
68+
"mapFileVersion": "1.0.0",
69+
"graphDefinitionName": "custom_graph_10",
70+
"graphDefinitionVersion": "1.0.0",
71+
"refreshFrequency": "00:00:00",
72+
"createTime": "11/04/2025 22:32:43",
73+
"lastUpdateTime": "11/04/2025 22:32:43",
74+
"lastSnapshotTime": "2025-11-04T22:34:04.7105015+00:00",
75+
"lastSnapshotRequestTime": "2025-11-04T22:32:52.0187838+00:00",
76+
"instanceStatus": "Ready"
77+
},
78+
{
79+
"name": "notebook_graph_5",
80+
"mapFileName": null,
81+
"mapFileVersion": null,
82+
"graphDefinitionName": "notebook_graph_5",
83+
"graphDefinitionVersion": "1.0.0",
84+
"refreshFrequency": "00:00:00",
85+
"createTime": "11/04/2025 20:15:22",
86+
"lastUpdateTime": "11/04/2025 20:15:22",
87+
"lastSnapshotTime": null,
88+
"lastSnapshotRequestTime": null,
89+
"instanceStatus": "Creating"
90+
}
91+
]
92+
}
93+
```
94+
95+
### Response properties
96+
97+
| Property | Type | Description |
98+
|----------|------|-------------|
99+
| `name` | String | The name of the graph instance. |
100+
| `mapFileName` | String | The name of the map file associated with the graph. |
101+
| `mapFileVersion` | String | The version of the map file. |
102+
| `graphDefinitionName` | String | The name of the graph definition used to build this instance. |
103+
| `graphDefinitionVersion` | String | The version of the graph definition. |
104+
| `refreshFrequency` | String | How often the graph data is refreshed. |
105+
| `createTime` | String | When the graph instance was created. |
106+
| `lastUpdateTime` | String | When the graph instance was last updated. |
107+
| `lastSnapshotTime` | String | The timestamp of the most recent data snapshot. |
108+
| `lastSnapshotRequestTime` | String | When the last snapshot was requested. |
109+
| `instanceStatus` | String | The current status of the graph instance. |
110+
111+
### Response status codes
112+
113+
| Status code | Description |
114+
|-------------|-------------|
115+
| 200 OK | List retrieved successfully. |
116+
117+
## Query a graph
118+
119+
Query a custom graph using Graph Query Language (GQL). For more information on GQL, see [GQL reference for Microsoft Sentinel graph](gql-reference-for-sentinel-custom-graph.md).
120+
121+
> [!NOTE]
122+
> `{graphName}` refers to the `name` of a graph returned from the list operation.
123+
124+
### Request
125+
126+
```http
127+
POST https://api.securityplatform.microsoft.com/graphs/graph-instances/{graphName}/query
128+
Content-Type: application/json
129+
```
130+
131+
### Request body
132+
133+
```json
134+
{
135+
"query": "string",
136+
"queryLanguage": "GQL"
137+
}
138+
```
139+
140+
### Request body properties
141+
142+
| Property | Type | Required | Description |
143+
|----------|------|----------|-------------|
144+
| `query` | String | Yes | The GQL query to execute. |
145+
| `queryLanguage` | String | Yes | The query language. Must be `GQL`. |
146+
| `responseFormats` | String array | No | Controls the format of the query response. Accepts one or both of the following values: `Table`, `Graph`. Defaults to `Table` if not specified. |
147+
148+
### Response formats
149+
150+
The `responseFormats` property controls the structure of the response:
151+
152+
| Format | Description |
153+
|--------|-------------|
154+
| `Table` | Returns raw tabular data (default if not specified). |
155+
| `Graph` | Returns graph-structured data with nodes and edges. |
156+
157+
You can request one or both formats:
158+
- `["Table"]` - Returns only table format.
159+
- `["Graph"]` - Returns only graph format.
160+
- `["Table", "Graph"]` - Returns both formats in the response.
161+
162+
### Example: Basic query
163+
164+
```http
165+
POST https://api.securityplatform.microsoft.com/graphs/graph-instances/{graphName}/query
166+
Content-Type: application/json
167+
168+
{
169+
"query": "MATCH (u)-[v]->(w) RETURN * LIMIT 2",
170+
"queryLanguage": "GQL"
171+
}
172+
```
173+
174+
### Example: Query with both response formats
175+
176+
```http
177+
POST https://api.securityplatform.microsoft.com/graphs/graph-instances/{graphName}/query
178+
Content-Type: application/json
179+
180+
{
181+
"query": "MATCH (n:User)-[r:HasAccess]->(m:Resource) RETURN n, r, m LIMIT 100",
182+
"responseFormats": ["Table", "Graph"],
183+
"queryLanguage": "GQL"
184+
}
185+
```
186+
187+
### Sample response (both formats)
188+
189+
```json
190+
{
191+
"status": 200,
192+
"result": {
193+
"rawData": {
194+
"tables": [
195+
{
196+
"tableName": "PrimaryResult",
197+
"columns": [
198+
{
199+
"columnName": "u",
200+
"dataType": "dynamic"
201+
},
202+
{
203+
"columnName": "r",
204+
"dataType": "dynamic"
205+
},
206+
{
207+
"columnName": "g",
208+
"dataType": "dynamic"
209+
}
210+
],
211+
"rows": [
212+
[
213+
{
214+
"oid": "node-user-001",
215+
"labels": ["User"],
216+
"properties": {
217+
"name": "Aino Rebane",
218+
"email": "[email protected]",
219+
"department": "Engineering"
220+
}
221+
},
222+
{
223+
"oid": "edge-001",
224+
"labels": ["HasRole"],
225+
"sourceOid": "node-user-001",
226+
"targetOid": "node-group-001",
227+
"properties": {
228+
"assignedDate": "2024-01-15T10:30:00Z",
229+
"assignedBy": "[email protected]"
230+
}
231+
},
232+
{
233+
"oid": "node-group-001",
234+
"labels": ["Group"],
235+
"properties": {
236+
"name": "Administrators",
237+
"description": "System administrators group",
238+
"memberCount": 25
239+
}
240+
}
241+
]
242+
]
243+
}
244+
]
245+
},
246+
"graph": {
247+
"nodes": [
248+
{
249+
"id": "node-user-001",
250+
"labels": ["User"],
251+
"properties": {
252+
"name": "Aino Rebane",
253+
"email": "[email protected]",
254+
"department": "Engineering"
255+
}
256+
},
257+
{
258+
"id": "node-group-001",
259+
"labels": ["Group"],
260+
"properties": {
261+
"name": "Administrators",
262+
"description": "System administrators group",
263+
"memberCount": 25
264+
}
265+
},
266+
{
267+
"id": "node-group-002",
268+
"labels": ["Group"],
269+
"properties": {
270+
"name": "Engineering Team",
271+
"description": "Software engineering team",
272+
"memberCount": 150
273+
}
274+
}
275+
],
276+
"edges": [
277+
{
278+
"id": "edge-001",
279+
"sourceId": "node-user-001",
280+
"targetId": "node-group-001",
281+
"labels": ["HasRole"],
282+
"properties": {
283+
"assignedDate": "2024-01-15T10:30:00Z",
284+
"assignedBy": "[email protected]"
285+
}
286+
},
287+
{
288+
"id": "edge-002",
289+
"sourceId": "node-user-001",
290+
"targetId": "node-group-002",
291+
"labels": ["HasRole"],
292+
"properties": {
293+
"assignedDate": "2024-02-01T14:20:00Z",
294+
"assignedBy": "[email protected]"
295+
}
296+
}
297+
]
298+
}
299+
},
300+
"correlationId": "aaaa0000-bb11-2222-33cc-444444dddddd"
301+
}
302+
```
303+
304+
### Response status codes
305+
306+
| Status code | Description |
307+
|-------------|-------------|
308+
| 200 OK | Query executed successfully. |
309+
| 404 Not Found | The specified graph instance doesn't exist. |
310+
311+
### Error response example
312+
313+
```json
314+
{
315+
"error": {
316+
"code": "GraphInstanceNotFound",
317+
"message": "Graph Instance CustomGraph1 does not exist.",
318+
"target": null,
319+
"details": []
320+
}
321+
}
322+
```
323+
324+
## Next steps
325+
326+
- [Create custom graphs in the security data lake](create-custom-graphs.md)
327+
- [GQL reference for Microsoft Sentinel graph](gql-reference-for-sentinel-custom-graph.md)
328+
- [Microsoft Sentinel graph Python SDK provider reference](sentinel-graph-provider-reference.md)
329+
- [VS Code extension notebooks](notebooks.md)

0 commit comments

Comments
 (0)