# Issue a token

> The credential's usable secret, refreshed if needed, plus the same values under the env var names the list advertises. Every call is logged with your reason.

Source: https://docs.generalinput.com/api/vault/issue-token



<Endpoint method="POST" path="/v1/credentials/:id/token" />

<Access scope="vault:token" note="vault:token implies vault:read." />

The one place a keyed caller obtains a secret. The vault decrypts the credential, refreshes an OAuth access token if it is stale, writes the access log, and returns the usable fields. Refresh tokens are withheld.

## Path parameters [#path-parameters]

| Name | Notes          |
| ---- | -------------- |
| `id` | Credential id. |

## Body [#body]

| Field    | Type   | Notes                                                                                                         |
| -------- | ------ | ------------------------------------------------------------------------------------------------------------- |
| `reason` | string | Required, 1 to 500 characters. Why the secret is needed. Shown to the workspace in the credential access log. |

```json
{ "reason": "Posting the daily digest to #engineering" }
```

## Response [#response]

```json
{
  "credentialId": "cred_01HX7AB",
  "service": "slack",
  "data": {
    "accessToken": "xoxp-…",
    "teamId": "T0123"
  },
  "env": {
    "SLACK_ACCESS_TOKEN_01HX7AB": "xoxp-…",
    "SLACK_BOT_TOKEN": "xoxp-…"
  },
  "expiresAt": "2026-09-03T10:00:00.000Z",
  "grantedScopes": ["chat:write", "channels:read"]
}
```

| Field           | Type            | Notes                                                                                                            |
| --------------- | --------------- | ---------------------------------------------------------------------------------------------------------------- |
| `data`          | object          | The credential's fields, camelCase, as the operation docs name them. Refresh tokens are removed.                 |
| `env`           | object          | The same values keyed by env var name, ready to export into a subprocess.                                        |
| `expiresAt`     | string, null    | When the access token stops working, when the provider says so. Call again after it passes; the vault refreshes. |
| `grantedScopes` | string\[], null | OAuth scopes on the credential.                                                                                  |

## Errors [#errors]

| Status | When                                                                          |
| ------ | ----------------------------------------------------------------------------- |
| `400`  | `reason` missing or too long.                                                 |
| `403`  | The member can see the credential but may not use it (shared as viewer only). |
| `404`  | No such credential, or not visible to the member.                             |

## Example [#example]

```sh
TOKEN=$(curl -s -X POST "https://cloud.generalinput.com/v1/credentials/cred_01HX7AB/token" \
  -H "Authorization: Bearer $GI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason":"Listing channels for the onboarding bot"}' | jq -r '.data.accessToken')

curl -s https://slack.com/api/conversations.list -H "Authorization: Bearer $TOKEN"
```
