[role="xpack"]
[[security-api-query-api-key]]
=== Query API key information API

++++
<titleabbrev>Query API key information</titleabbrev>
++++

Retrieves information for API keys with <<query-dsl,Query DSL>>
in a <<paginate-search-results,paginated>> fashion.

[[security-api-query-api-key-request]]
==== {api-request-title}

`GET /_security/_query/api_key`

`POST /_security/_query/api_key`

[[security-api-query-api-key-prereqs]]
==== {api-prereq-title}

* To use this API, you must have at least the `manage_own_api_key` cluster
privilege.
* If you have only the `manage_own_api_key` privilege, this API returns only
the API keys that you own. If you have the `manage_api_key` or greater
privileges (including `manage_security`), this API returns all API keys
regardless of ownership.

[[security-api-query-api-key-desc]]
==== {api-description-title}

Use this API to retrieve the API keys created with the
<<security-api-create-api-key,create API key API>> in a paginated manner.
You can optionally filter the results with a query.

[[security-api-query-api-key-request-body]]
==== {api-request-body-title}

You can specify the following parameters in the request body:

`query`::
(Optional, string) A <<query-dsl,query>> to filter which API keys to return.
The query supports a subset of query types, including
<<query-dsl-match-all-query,`match_all`>>, <<query-dsl-bool-query,`bool`>>,
<<query-dsl-term-query,`term`>>, <<query-dsl-terms-query,`terms`>>, <<query-dsl-ids-query,`ids`>>,
<<query-dsl-prefix-query,`prefix`>>, <<query-dsl-wildcard-query,`wildcard`>>, and <<query-dsl-range-query,`range`>>.
+
You can query all public information associated with an API key, including the
following values.
+
.Valid values for `query`
[%collapsible%open]
====
`id`::
ID of the API key. Note `id` must be queried with the <<query-dsl-ids-query,`ids`>> query.

`name`::
Name of the API key.

`creation`::
Creation time of the API key in milliseconds.

`expiration`::
Expiration time of the API key in milliseconds.

`invalidated`::
Indicates whether the API key is invalidated. If `true`, the key is invalidated.
Defaults to `false`.

`username`::
Username of the API key owner.

`realm`::
Realm name of the API key owner.

`metadata`::
Metadata field associated with the API key, such as `metadata.my_field`. Because
metadata is stored as a <<flattened,flattened>> field type, all fields act like
`keyword` fields when querying and sorting.
====

include::{es-repo-dir}/rest-api/common-parms.asciidoc[tag=from]
+
By default, you cannot page through more than 10,000 hits using the `from` and
`size` parameters. To page through more hits, use the
<<search-after,`search_after`>> parameter.

`size`::
(Optional, integer) The number of hits to return. Must not be negative and defaults to `10`.
+
By default, you cannot page through more than 10,000 hits using the `from` and
`size` parameters. To page through more hits, use the
<<search-after,`search_after`>> parameter.

`sort`::
(Optional, object) <<sort-search-results,Sort definition>>. Other than `id`,
all public fields of an API key are eligible for sorting. In addition, sort can
also be applied to the `_doc` field to sort by index order.

`search_after`::
(Optional, array) <<search-after,Search after>> definition.


[[security-api-query-api-key-response-body]]
==== {api-response-body-title}

This API returns the following top level fields:

`total`::
The total number of API keys found.

`count`::
The number of API keys returned in the response.

`api_keys`::
A list of API key information.

[[security-api-query-api-key-example]]
==== {api-examples-title}

The following request lists all API keys, assuming you have the
`manage_api_key` privilege:

[source,console]
----
GET /_security/_query/api_key
----

A successful call returns a JSON structure that contains the information
retrieved from one or more API keys:

[source,js]
----
{
  "total": 3,
  "count": 3,
  "api_keys": [ <1>
    {
      "id": "nkvrGXsB8w290t56q3Rg",
      "name": "my-api-key-1",
      "creation": 1628227480421,
      "expiration": 1629091480421,
      "invalidated": false,
      "username": "elastic",
      "realm": "reserved",
      "metadata": {
        "letter": "a"
      }
    },
    {
      "id": "oEvrGXsB8w290t5683TI",
      "name": "my-api-key-2",
      "creation": 1628227498953,
      "expiration": 1628313898953,
      "invalidated": false,
      "username": "elastic",
      "realm": "reserved",
      "metadata": {
        "letter": "b"
      }
    }
  ]
}
----
// NOTCONSOLE

<1> The list of API keys that were retrieved for this request

If you create an API key with the following details:

[source,console]
----
POST /_security/api_key
{
  "name": "application-key-1",
  "metadata": { "application": "my-application"}
}
----

A successful call returns a JSON structure that provides
API key information. For example:

[source,console-result]
----
{
  "id": "VuaCfGcBCdbkQm-e5aOx",
  "name": "application-key-1",
  "api_key": "ui2lp2axTNmsyakw9tvNnw",
  "encoded": "VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw=="
}
----
// TESTRESPONSE[s/VuaCfGcBCdbkQm-e5aOx/$body.id/]
// TESTRESPONSE[s/ui2lp2axTNmsyakw9tvNnw/$body.api_key/]
// TESTRESPONSE[s/VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw==/$body.encoded/]

Use the information from the response to retrieve the API key by ID:

[source,console]
----
GET /_security/_query/api_key
{
  "query": {
    "ids": {
      "values": [
        "VuaCfGcBCdbkQm-e5aOx"
      ]
    }
  }
}
----
// TEST[s/VuaCfGcBCdbkQm-e5aOx/$body.id/]
// TEST[continued]

You can also retrieve the API key by name:

[source,console]
----
GET /_security/_query/api_key
{
  "query": {
    "term": {
      "name": {
        "value": "application-key-1"
      }
    }
  }
}
----
// TEST[continued]

Use a `bool` query to issue complex logical conditions and use
`from`, `size`, `sort` to help paginate the result:

[source,js]
----
{
  "query": {
    "bool": {
      "must": [
        {
          "prefix": {
            "name": "app1-key-" <1>
          }
        },
        {
          "term": {
            "invalidated": "false" <2>
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "name": "app1-key-01" <3>
          }
        }
      ],
      "filter": [
        {
          "wildcard": {
            "username": "org-*-user" <4>
          }
        },
        {
          "term": {
            "metadata.environment": "production" <5>
          }
        }
      ]
    }
  },
  "from": 20, <6>
  "size": 10, <7>
  "sort": [ <8>
    { "creation": { "order": "desc", "format": "date_time" } },
    "name"
  ]
}
----
// NOTCONSOLE

<1> The API key name must begin with `app1-key-`
<2> The API key must still be valid
<3> The API key name must not be `app1-key-01`
<4> The API key must be owned by a username of the <<query-dsl-wildcard-query,wildcard>> pattern `org-*-user`
<5> The API key must have the metadata field `environment` that has the value of `production`
<6> The offset to begin the search result is the 20th (zero-based index) API key
<7> The page size of the response is 10 API keys
<8> The result is first sorted by `creation` date in descending order, then by name in ascending order

The response contains a list of matched API keys along with their sort values:

[source,js]
----
{
  "total": 100,
  "count": 10,
  "api_keys": [
    {
      "id": "CLXgVnsBOGkf8IyjcXU7",
      "name": "app1-key-79",
      "creation": 1629250154811,
      "invalidated": false,
      "username": "org-admin-user",
      "realm": "native1",
      "metadata": {
        "environment": "production"
      },
      "_sort": [
        "2021-08-18T01:29:14.811Z",  <1>
        "app1-key-79"  <2>
      ]
    },
    {
      "id": "BrXgVnsBOGkf8IyjbXVB",
      "name": "app1-key-78",
      "creation": 1629250153794,
      "invalidated": false,
      "username": "org-admin-user",
      "realm": "native1",
      "metadata": {
        "environment": "production"
      },
      "_sort": [
        "2021-08-18T01:29:13.794Z",
        "app1-key-78"
      ]
    },
    ...
  ]
}
----
// NOTCONSOLE

<1> The first sort value is creation time, which is displayed in `date_time` <<mapping-date-format,format>> as defined in the request
<2> The second sort value is the API key name
