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

# API Keys: Authenticate Your Scout Integrations Securely

> Create and manage Scout API keys (Org Credentials) to authenticate REST API calls, SDK clients, and CI/CD pipelines. Rotate without downtime.

API keys let you authenticate programmatic requests to Scout. Whether you're building an integration, connecting a service to Scout, or running automated workflows from a CI/CD pipeline, you need an API key. Scout gives you fine-grained control over your keys: create multiple per organization, name them by purpose, toggle them on and off, and rotate them without downtime.

## Two Types of Credentials

Scout provides two types of API credentials:

<CardGroup cols={2}>
  <Card title="Org Credentials" icon="key">
    The modern, recommended credential type. Asymmetric key pairs you can create in any quantity, name by purpose, enable or disable, and rotate safely.
  </Card>

  <Card title="Legacy Keys" icon="clock">
    Older single-key credentials that continue to work. Org Credentials replace them with more flexibility and security options.
  </Card>
</CardGroup>

### Org Credentials vs. Legacy Keys

| Feature                       | Legacy Key | Org Credentials |
| ----------------------------- | ---------- | --------------- |
| Multiple keys per org         | No         | Yes             |
| Enable / disable toggle       | No         | Yes             |
| Key rotation without downtime | No         | Yes             |
| Named keys                    | No         | Yes             |
| Asymmetric key pair           | No         | Yes             |
| Scoped permissions (planned)  | No         | Yes             |

<Note>
  Org Credentials are asymmetric key pairs. When using bearer token authentication, use the **private key** portion of your Org Credential as the token value. You can view and copy it at any time from Scout Studio.
</Note>

## Creating an API Key

### Prerequisites

You need organization admin permissions in Scout Studio to create API keys.

### Steps

<Steps>
  <Step title="Open API Keys settings">
    Navigate to **Settings** → **API Keys** in Scout Studio.
  </Step>

  <Step title="Create a new key">
    Click **Create New Key** to open the **Add a key pair** modal.
  </Step>

  <Step title="Name your key">
    Enter a descriptive name that tells you what this key is for six months from now — for example, `prod-api-server`, `github-actions-deploy`, or `staging-tests`.
  </Step>

  <Step title="Select a role">
    Choose **Admin** for full organization permissions or **Member** for standard access.
  </Step>

  <Step title="Save the key">
    Click **Save**. Your new key is active immediately. The key pair (public and private) appears in your keys list.
  </Step>
</Steps>

Each key row in the list shows:

* **Name** and assigned role
* **Public key** — masked by default; use the eye icon to reveal or the copy icon to copy
* **Private key** — masked by default; use the eye icon to reveal or the copy icon to copy
* **Enable / disable toggle** — suspend access without deleting the key
* **Actions menu (⋮)** — rename, rotate, or delete

<Warning>
  Scout does not re-display the private key after you navigate away from the creation screen. If you lose it, create a new key and rotate your applications to use it.
</Warning>

## Using API Keys

Scout API keys support two authentication methods. Both use the `Authorization: Bearer` header. Choose based on your security requirements.

| Method                          | What you send                                 | Best for                                                      |
| ------------------------------- | --------------------------------------------- | ------------------------------------------------------------- |
| **Private key as Bearer token** | The private key string directly               | Quick scripts, internal tools, local testing                  |
| **Signed JWT**                  | A short-lived JWT signed with the private key | Production integrations, anything that handles sensitive data |

In both cases, the key's role determines what operations are permitted.

***

### Method 1: Private Key as Bearer Token

Use the private key string exactly as shown in Settings as your Bearer token.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.scoutos.com/v2/workflows" \
    -H "Authorization: Bearer YOUR_PRIVATE_KEY"
  ```

  ```python Python theme={null}
  from scout import Scout

  client = Scout(api_key="YOUR_PRIVATE_KEY")
  ```

  ```typescript TypeScript theme={null}
  import Scout from "scoutos";

  const client = new Scout({ apiKey: "YOUR_PRIVATE_KEY" });
  ```
</CodeGroup>

<Warning>
  The private key travels over the network on every request when you use this method. Use it only over TLS (HTTPS). For persistent or production integrations, use the signed JWT method below — the private key never leaves your environment.
</Warning>

***

### Method 2: Signed JWT

Sign a short-lived JWT locally with the private key and send that as the Bearer token. Scout verifies the signature against the stored public key. The private key never leaves your environment.

#### Step 1: Convert the key to PEM format

Scout keys are stored as base64url-encoded DER. Most JWT libraries expect PEM format. Run this conversion once at startup.

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    // key-utils.js
    export function derToPem(base64urlDer, type = 'PRIVATE KEY') {
      const b64 = base64urlDer
        .replace(/-/g, '+')
        .replace(/_/g, '/')
        .padEnd(base64urlDer.length + (4 - base64urlDer.length % 4) % 4, '=');
      const lines = b64.match(/.{1,64}/g).join('\n');
      const sep = '-----';
      return `${sep}BEGIN ${type}${sep}\n${lines}\n${sep}END ${type}${sep}`;
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # key_utils.py
    import base64

    def der_to_pem(base64url_der: str, key_type: str = "PRIVATE KEY") -> str:
        padded = base64url_der + "=" * (4 - len(base64url_der) % 4)
        der_bytes = base64.urlsafe_b64decode(padded)
        b64 = base64.b64encode(der_bytes).decode()
        lines = "\n".join(b64[i:i+64] for i in range(0, len(b64), 64))
        sep = "-----"
        return f"{sep}BEGIN {key_type}{sep}\n{lines}\n{sep}END {key_type}{sep}"
    ```
  </Tab>
</Tabs>

<Tip>
  If your JWT signing call throws a key parsing error, a missing PEM conversion is almost always the cause.
</Tip>

#### Step 2: Sign and send the JWT

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    import jwt from 'jsonwebtoken';
    import { derToPem } from './key-utils.js';

    const keyPem        = derToPem(process.env.SCOUT_PRIVATE_KEY);
    const CREDENTIAL_ID = process.env.SCOUT_CREDENTIAL_ID;
    const KID           = process.env.SCOUT_KID; // shown in Settings → API Keys

    function makeToken() {
      const now = Math.floor(Date.now() / 1000);
      return jwt.sign(
        { iss: 'scout', sub: CREDENTIAL_ID, iat: now, exp: now + 300 },
        keyPem,
        { algorithm: 'RS256', header: { alg: 'RS256', kid: KID } }
      );
    }

    const res = await fetch('https://api.scoutos.com/v2/workflows', {
      headers: { Authorization: `Bearer ${makeToken()}` },
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import jwt, time, os, requests
    from key_utils import der_to_pem

    key_pem       = der_to_pem(os.environ["SCOUT_PRIVATE_KEY"])
    CREDENTIAL_ID = os.environ["SCOUT_CREDENTIAL_ID"]
    KID           = os.environ["SCOUT_KID"]  # shown in Settings → API Keys

    def make_token():
        now = int(time.time())
        return jwt.encode(
            { "iss": "scout", "sub": CREDENTIAL_ID, "iat": now, "exp": now + 300 },
            key_pem,
            algorithm="RS256",
            headers={ "kid": KID }
        )

    res = requests.get(
        "https://api.scoutos.com/v2/workflows",
        headers={ "Authorization": f"Bearer {make_token()}" }
    )
    ```
  </Tab>
</Tabs>

<Tip>
  Generate a token once per process startup and cache it in memory. Regenerate it when fewer than 30 seconds remain before expiry. Tokens are valid for 5 minutes (300 seconds).
</Tip>

#### JWT Claims Reference

| Claim | Required | Value                                                               |
| ----- | -------- | ------------------------------------------------------------------- |
| `iss` | Yes      | Must be the string `scout`                                          |
| `sub` | Yes      | Your credential ID, shown in Settings → API Keys                    |
| `iat` | Yes      | Current Unix timestamp in seconds                                   |
| `exp` | No       | Expiry Unix timestamp. Maximum 300 seconds after `iat`.             |
| `kid` | Header   | RFC 7638 thumbprint of the public key, shown in Settings → API Keys |

***

### Authentication Troubleshooting

| Error              | Check                                                                                                                                       |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `401 Unauthorized` | The key is disabled or deleted. Confirm it is enabled in Settings → API Keys. Verify you are using the **private** key, not the public key. |
| `403 Forbidden`    | The key is valid but lacks permission for this operation. Check the role assigned to the key.                                               |
| JWT parse error    | The key needs PEM conversion before use with a JWT library. Follow Step 1 above.                                                            |

## Managing Keys

### Enabling and Disabling a Key

Disable a key temporarily without deleting it — useful for suspending access during a security review or pausing an integration.

1. Go to **Settings** → **API Keys**.
2. Find the key and toggle the **Enabled** switch off.

Disabled keys return `401 Unauthorized` on all requests. Re-enable at any time by toggling it back on.

### Rotating Keys

Because Org Credentials support multiple active keys, you can rotate without downtime:

<Steps>
  <Step title="Create a new key">
    Create a new key with a version suffix (e.g., `prod-api-v2`).
  </Step>

  <Step title="Update your applications">
    Update your application or secrets manager to use the new private key.
  </Step>

  <Step title="Verify the new key works">
    Confirm the new key is working in all affected services.
  </Step>

  <Step title="Disable the old key">
    Disable the old key and monitor for unexpected `401` errors.
  </Step>

  <Step title="Delete the old key">
    Once you confirm no service depends on the old key, delete it.
  </Step>
</Steps>

### Deleting Keys

Deleting a key is **permanent**. Any service using that key immediately receives `401 Unauthorized` errors.

1. Go to **Settings** → **API Keys**.
2. Click the **Actions menu (⋮)** → **Delete**.
3. Confirm the deletion in the dialog.

Always disable a key and monitor for errors before permanently deleting it.

## Security Best Practices

Treat API keys like passwords. Follow these practices to reduce risk:

* **Never commit keys to source control.** Use `.gitignore` to exclude `.env` files. Use tools like [git-secrets](https://github.com/awslabs/git-secrets) or pre-commit hooks to scan for accidental commits.
* **Use one key per service or environment.** Separate keys for production, staging, CI/CD, and local development let you revoke access for one system without affecting others.
* **Use descriptive names.** Names like `prod-api-server` or `github-actions-deploy` make it easy to audit which key is used where.
* **Rotate keys on a schedule.** Quarterly rotation is a reasonable baseline for most teams.
* **Disable before you delete.** Disabling first lets you confirm no active service depends on a key before permanently removing it.
* **Store keys in a secrets manager.** Prefer AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, or Doppler over plain environment files in production.
* **Audit access regularly.** Review your active keys and remove any that are no longer in use.

### Multi-Key Strategy

Use separate keys for each environment and integration:

| Key Name          | Purpose                    | Environment |
| ----------------- | -------------------------- | ----------- |
| `prod-api-server` | Main production backend    | Production  |
| `prod-cicd`       | GitHub Actions deployments | Production  |
| `staging-api`     | Staging and QA testing     | Staging     |
| `dev-local`       | Local development          | Development |

This pattern lets you rotate or revoke one key without disrupting unrelated services.

## Key Management Troubleshooting

| Error                           | Likely Cause                                    | Solution                                                                                                                    |
| ------------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `401 Unauthorized`              | Key is disabled, deleted, or copied incorrectly | Confirm the key is enabled in Settings. Re-copy the private key from Scout Studio.                                          |
| `403 Forbidden`                 | Key doesn't have permission for this resource   | Confirm your organization has access to the feature you are calling. Check the key's role.                                  |
| Key not appearing in Settings   | Session or membership issue                     | Refresh the page. Verify you are logged into the correct organization.                                                      |
| Requests failing after rotation | Old key still in use somewhere                  | Search your codebase and secrets manager for references to the old key. Check CI/CD environment variables.                  |
| Private key only shown once     | Expected behavior                               | Scout does not re-display the private key after creation. If lost, create a new key and rotate your applications to use it. |

## Migrating from Legacy Keys

Legacy Keys continue to work and Scout will provide advance notice before any deprecation. When you're ready to migrate:

<Steps>
  <Step title="Create new Org Credentials">
    Create a new Org Credential for each service or use case that currently uses a Legacy Key.
  </Step>

  <Step title="Update your applications">
    Update your applications and environment variables to use the new private keys.
  </Step>

  <Step title="Verify all services">
    Confirm all services are working correctly with the new credentials.
  </Step>

  <Step title="Disable the Legacy Key">
    Disable the Legacy Key and monitor for errors over the next 24 hours.
  </Step>

  <Step title="Delete the Legacy Key">
    Once you confirm no service depends on it, delete the Legacy Key.
  </Step>
</Steps>

## Upcoming Features

**Scoped Permissions** will let you restrict a key to specific Scout services or API actions, so a CI/CD key can only trigger workflows and cannot read or delete databases. **Audit Trail** will provide a time-stamped log of every key creation, rotation, disable, and delete event — useful for compliance reviews and incident response. Both features are in active development.

## Next Steps

<CardGroup cols={3}>
  <Card title="Skills Overview" icon="stars" href="/skills/overview">
    Configure Skills to authenticate with your API key via the `SCOUT_API_KEY` environment variable.
  </Card>

  <Card title="Scout MCP" icon="server" href="/mcp-server">
    Use your API key to authenticate the Scout MCP server for coding agent access.
  </Card>

  <Card title="API Reference" icon="book" href="https://ref.scoutos.com/api-sdk">
    Full reference for all Scout REST API endpoints you can authenticate with your key.
  </Card>
</CardGroup>
