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

# Authentication

> Authenticate your API requests with API keys.

Every request to the Propal API must include an API key in the `Authorization` header.

```
Authorization: Bearer pp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

API keys are scoped to a single organization. All data accessed through a key belongs to that organization — there's no cross-organization access.

## Creating API keys

You can create API keys from your Propal dashboard:

1. Navigate to **Settings > API Keys**
2. Click **Create API Key**
3. Enter a name (e.g., "Zapier Integration", "Internal Dashboard")
4. Select the scopes (permissions) the key should have
5. Click **Create Key**

<Warning>
  The full API key is displayed only once at creation time. Copy it immediately and store it securely.
</Warning>

## Key format

API keys follow the format:

```
pp_live_<random_base64url_string>
```

* `pp_live_` — fixed prefix, identifies this as a Propal API key
* The rest is a cryptographically random string

Keys are stored as SHA-256 hashes in our database — we never store the raw key. If you lose it, you'll need to create a new one.

## Scopes

Each API key has a set of scopes that define what it can access. Scopes follow the format `{resource}:{action}`.

### Available scopes

| Resource         | Read                | Write             | Delete             |
| ---------------- | ------------------- | ----------------- | ------------------ |
| **Proposals**    | `proposals:read`    | `proposals:write` | `proposals:delete` |
| **Leads**        | `leads:read`        | `leads:write`     | `leads:delete`     |
| **Catalog**      | `products:read`     | `products:write`  | `products:delete`  |
| **Templates**    | `templates:read`    | `templates:write` | `templates:delete` |
| **Themes**       | `themes:read`       | `themes:write`    | `themes:delete`    |
| **Media**        | `media:read`        | `media:write`     | `media:delete`     |
| **Metrics**      | `metrics:read`      | —                 | —                  |
| **Organization** | `organization:read` | —                 | —                  |

### Scope combinations by use case

<AccordionGroup>
  <Accordion title="CRM Integration (read-only)">
    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    ["leads:read", "proposals:read", "metrics:read"]
    ```

    Ideal for syncing data from Propal to your CRM without modifying anything.
  </Accordion>

  <Accordion title="Full Automation">
    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    [
      "proposals:read", "proposals:write",
      "leads:read", "leads:write",
      "products:read",
      "templates:read",
      "themes:read"
    ]
    ```

    Create proposals automatically from your pipeline. Read-only on catalog, templates, and themes.
  </Accordion>

  <Accordion title="Analytics Dashboard">
    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    ["metrics:read", "proposals:read", "organization:read"]
    ```

    Build custom dashboards with your proposal metrics and pipeline data.
  </Accordion>

  <Accordion title="Full Access">
    All scopes selected. Use this only for trusted internal tools.
  </Accordion>
</AccordionGroup>

## Security best practices

<Steps>
  <Step title="Use minimal scopes">
    Only grant the scopes your integration actually needs. A read-only dashboard doesn't need `write` or `delete` permissions.
  </Step>

  <Step title="Rotate keys periodically">
    Revoke and recreate API keys on a regular basis (e.g., every 90 days).
  </Step>

  <Step title="Never expose keys in client-side code">
    API keys should only be used in server-side code, backend services, or CI/CD pipelines. Never include them in JavaScript bundles, mobile apps, or public repositories.
  </Step>

  <Step title="Use environment variables">
    Store keys in environment variables or a secrets manager — never hardcode them.

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    export PROPAL_API_KEY="pp_live_your_key_here"
    ```
  </Step>

  <Step title="Monitor usage">
    Check the "Last used" column in Settings > API Keys to detect unexpected activity.
  </Step>
</Steps>

## Error responses

If authentication fails, you'll receive a `401 Unauthorized` response:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid API key."
  }
}
```

If your key doesn't have the required scope for an endpoint, you'll get a `403 Forbidden`:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "error": {
    "code": "forbidden",
    "message": "API key missing required scope: proposals:write"
  }
}
```
