> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usehasp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Issuing Credentials

> Issue time-bounded, scoped credentials to agents on behalf of a user. The issuance event anchors agent authority into the audit chain.

A credential is a time-bounded authorization issued to an agent on behalf of a specific user. Issuing a credential is the consent event that anchors the agent's authority into the audit chain.

## Dashboard

**Developers → Agents → \[agent name] → Issue credential**

| Field                      | Required | Description                                                                                              |
| -------------------------- | -------- | -------------------------------------------------------------------------------------------------------- |
| Name                       | Yes      | Label for this credential issuance (e.g. "Shift A — 2026-05-11").                                        |
| Description                | No       | Optional note for the audit trail.                                                                       |
| Scope grants               | Yes      | One or more scope grants defining what the agent may do. Must be within the agent's allowed scope types. |
| Expires in                 | Yes      | Duration until the credential expires. Options: 1 hour, 8 hours, 24 hours, 7 days, 30 days.              |
| Revocation policy          | Yes      | `drain` or `kill`. Defaults to the agent's registered default.                                           |
| Max concurrent invocations | No       | Maximum number of parallel tool invocations. Default 10.                                                 |

After issuing, the **plaintext bearer token is displayed once.** Copy it immediately — HASP stores only the SHA-256 hash and cannot recover the plaintext.

## API

```
POST https://api.usehasp.com/v1/agents/{agent_id}/credentials
Authorization: Bearer hasp_api_live_...
Content-Type: application/json
```

### Body

```json theme={null}
{
  "name": "Shift A — 2026-05-11",
  "granted_scopes": [
    { "type": "hasp.data.read" },
    { "type": "external.tool.invoke", "tool_id": "calendar.find_slots" }
  ],
  "expires_at": "2026-05-11T17:00:00Z",
  "revocation_policy": "drain",
  "max_concurrent_invocations": 10
}
```

### Fields

| Field                        | Type              | Required | Description                                                                          |
| ---------------------------- | ----------------- | -------- | ------------------------------------------------------------------------------------ |
| `name`                       | string            | Yes      | Credential label. 2–255 chars.                                                       |
| `description`                | string            | No       | Optional description.                                                                |
| `granted_scopes`             | ScopeGrant\[]     | Yes      | Scope grant objects. Min 1, max 20. See [Scope Grants](/ai-api/agents/scope-grants). |
| `expires_at`                 | ISO 8601 datetime | Yes      | Must be in the future.                                                               |
| `revocation_policy`          | `drain` \| `kill` | Yes      | Revocation behavior.                                                                 |
| `max_concurrent_invocations` | integer           | No       | 1–1000. Default 10.                                                                  |

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "credential": {
      "id": "01JQCRED0000000000000000",
      "agent_id": "01JQAGENT0000000000000000",
      "name": "Shift A — 2026-05-11",
      "prefix": "hasp_agt_live_",
      "last_four": "a3f9",
      "mode": "live",
      "granted_scopes": [
        { "type": "hasp.data.read" },
        { "type": "external.tool.invoke", "tool_id": "calendar.find_slots" }
      ],
      "expires_at": "2026-05-11T17:00:00+00:00",
      "revocation_policy": "drain",
      "max_concurrent_invocations": 10,
      "consent_record_id": "01JQAUDIT0000000000000000",
      "created_at": "2026-05-11T09:00:00+00:00"
    },
    "token": "hasp_agt_live_<32-random-chars>"
  }
}
```

The `token` field is returned **only in this response**. It is not stored and cannot be retrieved later.

### Errors

| Code                 | HTTP | Meaning                                                                          |
| -------------------- | ---- | -------------------------------------------------------------------------------- |
| `AGENT_ARCHIVED`     | 422  | Cannot issue credentials for an archived agent.                                  |
| `INVALID_SCOPE_TYPE` | 422  | A scope type is not in the agent's `allowed_scope_types`.                        |
| `VALIDATION_FAILED`  | 422  | Request body failed validation — including `expires_at` not being in the future. |

***

## Using the credential

Pass the bearer token in the `Authorization` header on every API call:

```
Authorization: Bearer hasp_agt_live_<token>
```

The gateway resolves the token to the credential, validates it is active and unexpired, and runs the pre-action authorization check before any tool invocation is executed.

***

## Token format

| Mode | Prefix           | Example                   |
| ---- | ---------------- | ------------------------- |
| Live | `hasp_agt_live_` | `hasp_agt_live_abcdef...` |
| Test | `hasp_agt_test_` | `hasp_agt_test_abcdef...` |

The test-mode token is issued when your developer console is in **test mode** (toggleable in the developer dashboard). Test credentials do not authorize real tool invocations and are excluded from metered Agent Actions billing.

***

## Listing credentials

```
GET https://api.usehasp.com/v1/agents/{agent_id}/credentials
Authorization: Bearer hasp_api_live_...
```

Returns credentials for the agent, newest first. The `token` field is never returned in list or detail responses — only in the issuance response.

### Query parameters

| Parameter | Description                                         |
| --------- | --------------------------------------------------- |
| `status`  | `active`, `revoked`, `expired`, or `all` (default). |
| `page`    | Page number.                                        |

***

## Retrieving a credential

```
GET https://api.usehasp.com/v1/agents/{agent_id}/credentials/{credential_id}
Authorization: Bearer hasp_api_live_...
```

***

## Revoking a credential

```
POST https://api.usehasp.com/v1/agents/{agent_id}/credentials/{credential_id}/revoke
Authorization: Bearer hasp_api_live_...
Content-Type: application/json
```

### Body (optional)

```json theme={null}
{
  "reason": "Shift ended"
}
```

Revocation is immediate. The credential's configured `revocation_policy` governs in-flight work (drain vs. kill). All delegation descendants are revoked simultaneously with `kill` policy regardless of their own configured policy.

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "revoked_credential_ids": [
      "01JQCRED0000000000000000",
      "01JQCRED0000000000000001"
    ]
  }
}
```

The response includes the root credential plus any cascade-revoked descendants.
