# Get a token

> Get an Identity token with the OpenStack CLI or the Identity API, and send it with an API request.

This guide gets a token from Identity and uses it to call an API. You only need to do this for
direct API calls: the `openstack` CLI and the OpenStack SDKs get tokens for you.

## Before you begin

You need either the `openstack` CLI [signed in](/developer/cli), or an
[application credential](/identity/application-credentials) for calls with `curl`.

## 1. Get the token

<Tabs items="['CLI', 'API']">
  <Tab value="CLI">
    The CLI prints a token for the project it is signed in to. Keep only the token in a variable:

    ```sh
    export TOKEN=$(openstack token issue -f value -c id)
    ```

    To see which project the token is for and when it expires, show those fields instead:

    ```sh
    openstack token issue -c expires -c project_id -c user_id
    ```

    ```
    +------------+----------------------------------+
    | Field      | Value                            |
    +------------+----------------------------------+
    | expires    | 2026-10-07T23:41:09+0000         |
    | project_id | a6f1c2d93b8e4f07b5d4e2c1a9f8e7d6 |
    | user_id    | 4c8e2f1a9b7d4e6f8a3c5b1d7e9f2a4c |
    +------------+----------------------------------+
    ```
  </Tab>

  <Tab value="API">
    Send an application credential to Identity. The token comes back in the `X-Subject-Token`
    response header:

    ```sh
    curl --silent --include https://auth.vexxhost.net/v3/auth/tokens \
      --header "Content-Type: application/json" \
      --data '{
        "auth": {
          "identity": {
            "methods": ["application_credential"],
            "application_credential": {
              "id": "3c2b8e1f4a6d4c0e9b7a5f3d1e2c4b6a",
              "secret": "Jq7mX2vL9pR4tW8yZ1bC5nF3hK6dS0gAuE2iO7qT4wY9rU1oP3aL6sD8fG5hJ2kZ0xC7vB4nM1qW8eR3tY6u"
            }
          }
        }
      }'
    ```

    ```http
    HTTP/1.1 201 Created
    Content-Type: application/json
    X-Subject-Token: gAAAAABnA4tJq8r2Lw0m5X1zY7cT3vH9kQ6pN4sB2dF8gR0jU5eW1iO7aZ3xC9yV6nM4bK2lE8hG0fD5tS1uP7qA3wI9oJ6zL4cX2vN8mB5kR1yT7eU3iO9pS6dF2gH0jK4lZ8xC5vB1nM3qW7eR9tY2uI6oP0aS4dF8gJ
    ```

    The JSON body describes the token: its `expires_at`, its `project`, and the
    [service catalog](/identity/service-catalog). Copy the `X-Subject-Token` value into `TOKEN`.
  </Tab>
</Tabs>

## 2. Send it with a request

Put the token in the `X-Auth-Token` header. This request asks Identity which projects you can
access, which works with any valid token:

```sh
curl https://auth.vexxhost.net/v3/auth/projects \
  --header "X-Auth-Token: $TOKEN"
```

```json
{
  "links": {
    "self": "https://auth.vexxhost.net/v3/auth/projects",
    "previous": null,
    "next": null
  },
  "projects": [
    {
      "id": "a6f1c2d93b8e4f07b5d4e2c1a9f8e7d6",
      "name": "acme-production",
      "description": "Production workloads",
      "domain_id": "default",
      "enabled": true,
      "is_domain": false,
      "parent_id": "default",
      "links": {
        "self": "https://auth.vexxhost.net/v3/projects/a6f1c2d93b8e4f07b5d4e2c1a9f8e7d6"
      }
    }
  ]
}
```

Other services take the token the same way. Find their endpoints in the
[service catalog](/identity/service-catalog).

## Verify

A request with a valid token gets a `200 OK` response. A `401 Unauthorized` response means the
token is missing or has expired. Get a new one.

## Next steps

* Learn how tokens work in [Authentication](/identity/authentication).
* [Make API requests](/developer/api) to other services with the token.
