> ## Documentation Index
> Fetch the complete documentation index at: https://pulse-41cf5b0d.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Authenticate REST API Requests to PulseGuard

> All PulseGuard API calls require a Bearer token. Create API keys in the dashboard with read and write access, protected by SHA-256 hashing.

Every request to the PulseGuard API must include a valid API key. Keys are long-lived tokens you create in the dashboard and carry both `read` and `write` scopes by default. You may set an optional expiry date. PulseGuard hashes each key with SHA-256 and stores only the hash — the raw key is shown exactly once and cannot be retrieved again, so copy it to a safe location immediately after creation.

## API key format

PulseGuard API keys follow this structure:

```
pg_live_<48 hex characters>
```

Example: `pg_live_a3f8c2d1e4b5a6f7c8d9e0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6`

The `pg_live_` prefix makes it easy to identify PulseGuard keys in your environment variables and secret managers.

## Key scopes

Every API key carries both `read` and `write` scopes. The scopes are stored as a comma-separated string (`read,write`) and the `write` scope is enforced on all endpoints that create, modify, or delete resources:

<CardGroup cols={2}>
  <Card title="read" icon="eye">
    Included in every key. `GET` endpoints require a valid key but do not explicitly check for this scope — any unexpired key grants read access.
  </Card>

  <Card title="write" icon="pen-to-square">
    Required for `POST`, `PUT`, and `DELETE` requests. Creating or modifying monitors, triggering checks with a URL override, and deleting resources all explicitly check for this scope and return `403` if it is absent.
  </Card>
</CardGroup>

<Note>
  All newly created keys include both scopes. If a key is compromised, delete it immediately from the dashboard — it will stop accepting requests instantly.
</Note>

## Create an API key

<Steps>
  <Step title="Open API Keys settings">
    In the PulseGuard dashboard, navigate to **Settings → API Keys**.
  </Step>

  <Step title="Click New Key">
    Click **New Key** and enter a descriptive name (e.g. `ci-pipeline`, `grafana-monitoring`).
  </Step>

  <Step title="Set an optional expiry">
    If you want the key to expire automatically, set an expiry date. Leave it blank for a non-expiring key.
  </Step>

  <Step title="Copy the raw key">
    After creation, the full raw key is displayed **once**. Copy it to your password manager or secret store immediately — PulseGuard stores only the SHA-256 hash and cannot show the raw key again.
  </Step>
</Steps>

## Send authenticated requests

Add the key to the `Authorization` header of every request using the `Bearer` scheme.

**curl:**

```bash theme={null}
curl https://app.pulseguard.io/api/cli/monitors \
  -H "Authorization: Bearer pg_live_your_api_key_here"
```

**JavaScript (fetch):**

```javascript theme={null}
const response = await fetch('https://app.pulseguard.io/api/cli/monitors', {
  headers: {
    'Authorization': `Bearer ${process.env.PULSEGUARD_API_KEY}`,
    'Content-Type': 'application/json'
  }
});
const { monitors } = await response.json();
```

**Environment variable convention:**

Store your key in an environment variable named `PULSEGUARD_API_KEY` to keep it out of source code.

```bash theme={null}
export PULSEGUARD_API_KEY="pg_live_your_api_key_here"
```

## How PulseGuard verifies your key

When your request arrives, PulseGuard:

1. Reads the `Authorization: Bearer <key>` header.
2. Hashes the raw key with SHA-256.
3. Looks up the hash in the database.
4. Checks whether the key has expired (`expiresAt < now`).
5. Returns the associated `userId` and `scopes` string (comma-separated, e.g. `read,write`).

If any step fails, the request is rejected with a `401`. PulseGuard also asynchronously records a `lastUsedAt` timestamp so you can audit usage in the dashboard without adding latency to your request.

## 401 vs 403 errors

| Status             | Cause                                              | Resolution                                                                                                          |
| ------------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `401 Unauthorized` | The key is missing, not recognized, or has expired | Check the `Authorization` header format; verify the key has not expired in the dashboard                            |
| `403 Forbidden`    | The key is valid but lacks the `write` scope       | All current keys include `write` scope; this error can occur if a key was created with a custom scope configuration |

## Rotate a key

<Steps>
  <Step title="Create the replacement key">
    In **Settings → API Keys**, create a new key with the same scope as the one you are replacing. Copy the raw key.
  </Step>

  <Step title="Update your integrations">
    Replace the old value of `PULSEGUARD_API_KEY` (or wherever you store the key) in every service, CI pipeline, and secret manager.
  </Step>

  <Step title="Delete the old key">
    Once all integrations are updated and confirmed working, delete the old key from the dashboard. It will immediately stop accepting requests.
  </Step>
</Steps>

<Warning>
  Deleting a key is irreversible and takes effect immediately. Any service still using the old key will receive `401` errors after deletion.
</Warning>
