Panther API (Beta)
Use Panther's GraphQL API for alert, role, and user management, and data lake querying

Overview

The Panther API is currently in public beta. Please share any bug reports and feature requests with your account team.
Panther offers a public GraphQL-over-HTTP API, meaning you can write GraphQL queries and invoke the API using a typical HTTP request. For more information on GraphQL, please see GraphQL's documentation.

How to use Panther's API

Step 1: Creating an API Token

  1. 1.
    Log in to your Panther Console.
  2. 2.
    Navigate to Settings > API Tokens.
  3. 3.
    Click Create an API Token.
  4. 4.
    Pick a friendly name for the API Token and configure the alert and permission settings.
  5. 5.
    Click Create API Token.
You will see a success screen that displays the value of the API Token. Please note that the API Token is sensitive information and it will not be displayed again; make sure you copy the API Token and store it in a secure location.

Testing the API Token

There may be a propagation delay of 30 to 60 seconds after adding an API Token.
After generating an API Token, you can test to verify that it works as expected:
  1. 1.
    On the API Token creation success screen, click the link that says Give it a go on our Playground.
  2. 2.
    Locate the REQUEST HEADERS tab at the bottom-left corner of the Playground screen. Under this tab, change the default value of the X-API-Key header from <ENTER_YOUR_KEY_HERE> to the value of your API Token.
  3. 3.
    In the upper left corner, press the "play" icon to run the test.
You can discover the available queries, mutations, and fields by clicking Documentation Explorer on the right side panel of the Playground.
For additional ways to discover the schema, see Discovering the Schema.

Step 2: Invoking the API

Prerequisites

To invoke the API using an HTTP curl operation, you will need the following information:
  • The GraphQL endpoint to hit
    • The GraphQL API endpoint is tied to your Panther domain and the API URL format is https://api.{YOUR_PANTHER_DOMAIN}/public/graphql.
    • For example, if your Panther domain is https://acme.runpanther.net, then your GraphQL API URL is https://api.acme.runpanther.net/public/graphql.
  • The auth-related header
    • The auth-related header is called X-API-Key and its value should always be a valid API Token that you generated through the Panther UI.
  • A GraphQL query

Invoking the API

There are two ways to invoke a GraphQL-over-HTTP API:

Option 1: Manually Constructing HTTP Calls

An example request:
1
curl 'YOUR_PANTHER_GRAPHQL_API_URL' \
2
-H 'Content-Type: application/json' \
3
-H 'X-API-Key: {YOUR_API_KEY}' \
4
-d '{"query":"\n query Foo {\n alerts {\n edges {\n node {\n id\n }\n }\n }\n }","variables":{}}'
Copied!
The query above returns the first page of all of your Panther alerts. If it's the first time you're using GraphQL, please note the following:
  • There's only one endpoint.
  • The HTTP operation is always a POST.
  • The API operations are defined in POST's body.
  • The body of the POST operation always contains the following keys:
    • query - a GraphQL string defining the GraphQL operation that should be executed
    • variables - an optional set of variables that will be passed along to the query
    • operationName - an optional "nickname" for this operation
  • You must always select a set of fields to return (if the operation returns data.)
Note: The only thing that would change from one GraphQL operation to another is the body of the HTTP POST.
While all GraphQL operations are essentially simple HTTP calls, the advantage of using a GraphQL client is that it is more user-friendly.
We recommend using:
Below you'll find some examples of how you would construct a GraphQL query to fetch the first page of alerts in your system:
NodeJS
Python
Golang
1
// npm install graphql graphql-request
2
3
import { GraphQLClient, gql } from 'graphql-request';
4
5
const client = new GraphQLClient(
6
'YOUR_PANTHER_API_URL',
7
{ headers: { 'X-API-Key': 'YOUR_API_KEY' }
8
});
9
10
// `PaginateAlerts` is a nickname for the operation
11
const query = gql`
12
query PaginateAlerts {
13
alerts {
14
edges {
15
node {
16
id
17
title
18
severity
19
status
20
}
21
}
22
pageInfo {
23
hasNextPage
24
endCursor
25
}
26
}
27
}
28
`;
29
30
client.request(query).then((data) => console.log(data));
Copied!
1
# pip install gql aiohttp
2
3
from gql import gql, Client
4
from gql.transport.aiohttp import AIOHTTPTransport
5
6
transport = AIOHTTPTransport(
7
url="YOUR_PANTHER_API_URL",
8
headers={"X-API-Key": "YOUR_API_KEY"}
9
)
10
11
client = Client(transport=transport, fetch_schema_from_transport=True)
12
13
# `PaginateAlerts` is a nickname for the operation
14
query = gql(
15
"""
16
query PaginateAlerts {
17
alerts {
18
edges {
19
node {
20
id
21
title
22
severity
23
status
24
}
25
}
26
pageInfo {
27
hasNextPage
28
endCursor
29
}
30
}
31
}
32
"""
33
)
34
35
result = client.execute(query)
36
print(result)
Copied!
1
package main
2
3
import (
4
"context"
5
"fmt"
6
"github.com/hasura/graphql"
7
)
8
9
// Strongly-typed languages don't pair well with GraphQL
10
var query struct {
11
Alerts struct {
12
Edges []struct {
13
Node struct {
14
Id graphql.String
15
Title graphql.String
16
Severity graphql.String
17
Status graphql.String
18
}
19
}
20
PageInfo struct {
21
HasNextPage graphql.Boolean
22
Cursor graphql.String
23
}
24
}
25
}
26
27
client := graphql.
28
NewClient("YOUR_PANTHER_API_URL", nil).
29
WithRequestModifier(func(req *http.Request) {
30
req.Header.Set("X-API-KEY", "YOUR_API_KEY")
31
})
32
33
if err := client.Query(context.Background(), &query, nil); err != nil {
34
// Handle error
35
}
36
37
fmt.Println(query.Alerts.PageInfo.HasNextPage)
38
Copied!
You can find all available operations of the API, as well as detailed end-to-end examples in the subpages of the current page. For a high level list, check out our supported operations.

Getting your Panther Version

1
query PantherVersion {
2
generalSettings {
3
pantherVersion
4
}
5
}
Copied!

Step 3: Discovering the Schema

There are three options to discover the GraphQL schema:

Option 1: Downloading the GraphQL schema file

You can download the latest version of the GraphQL schema file here.

Option 2: Using the GraphQL Playground

Panther's API Playground is a user-friendly way of browsing and discovering what's supported in our API. Please refer to our API Playground docs for information on how to use this as a discoverability mechanism.

Option 3: Performing an introspection query

An introspection query yields all the GraphQL API's entities in a format that most third-party libraries can parse. This discoverability option is useful if you want to make another library or service aware of the supported operations and types that the Panther API has. These libraries typically issue their own version of an introspection query, so they only need to be pointed to an API URL.
For security purposes, the introspection query is an authorized operation. This means that you'll need to add an X-API-Key header to your HTTP call with the value of an API Token in order for the introspection to work.
1
$ curl -H "X-API-Key: <API_KEY>" -d <INTROSPECTION_QUERY> <YOUR_PANTHER_API_URL>
Copied!
The actual shape of the introspection query is customizable. You can ask for a limited set of entities or for all possible information about the schema. For example, a query such as the following would yield every single piece of schema information:
1
query IntrospectionQuery {
2
__schema {
3
queryType { name }
4
mutationType { name }
5
types {
6
...FullType
7
}
8
directives {
9
name
10
description
11
locations
12
args {
13
...InputValue
14
}
15
}
16
}
17
}
18
fragment FullType on __Type {
19
kind
20
name
21
description
22
fields(includeDeprecated: true) {
23
name
24
description
25
args {
26
...InputValue
27
}
28
type {
29
...TypeRef
30
}
31
isDeprecated
32
deprecationReason
33
}
34
inputFields {
35
...InputValue
36
}
37
interfaces {
38
...TypeRef
39
}
40
enumValues(includeDeprecated: true) {
41
name
42
description
43
isDeprecated
44
deprecationReason
45
}
46
possibleTypes {
47
...TypeRef
48
}
49
}
50
fragment InputValue on __InputValue {
51
name
52
description
53
type { ...TypeRef }
54
defaultValue
55
}
56
fragment TypeRef on __Type {
57
kind
58
name
59
ofType {
60
kind
61
name
62
ofType {
63
kind
64
name
65
ofType {
66
kind
67
name
68
ofType {
69
kind
70
name
71
ofType {
72
kind
73
name
74
ofType {
75
kind
76
name
77
ofType {
78
kind
79
name
80
}
81
}
82
}
83
}
84
}
85
}
86
}
87
}
Copied!

Supported Operations

The Panther API supports an ever-growing set of capabilities that allow you to build your security workflows, as well as an API Playground to test operations.
See the Supported Operations page for a list of operations and examples.