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

# Authentication

> Authenticate API requests using Bearer tokens

The API uses **Bearer token authentication** for all requests. This simple and secure method requires you to include your API token in the `Authorization` header of every request.

## Getting Your API Token

### Step 1: Access API Settings

Navigate to your Penbox API settings page:

```
https://app.penbox.io/workspace/settings/api
```

### Step 2: Create a New Token

1. Click the **"Create API Token"** button
2. Give your token a descriptive name (e.g., "Production Integration", "Development", "Analytics Tool")
3. Select the workspace you want to authorize
4. Copy the generated token immediately

<Warning>
  **Important:** Your API token will only be displayed once. Copy it immediately and store it securely. If you lose it, you'll need to generate a new token.
</Warning>

### Token Format

Your API token will look like this:

```
pnbx_1234567890abcdef1234567890abcdef1234567890abcdef
```

Tokens always start with the `pnbx_` prefix.

## Using Your API Token

Include your API token in the `Authorization` header of every API request using the Bearer scheme:

```bash theme={null}
Authorization: Bearer pnbx_1234567890abcdef1234567890abcdef1234567890abcdef
```

### Example Requests

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET 'https://connect.penbox.io/v1/workspaces' \
    -H 'Authorization: Bearer pnbx_1234567890abcdef1234567890abcdef1234567890abcdef'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://connect.penbox.io/v1/cases', {
    headers: {
      'Authorization': `Bearer ${apiToken}`
    }
  });

  const forms = await response.json();
  ```

  ```python Python theme={null}
  import requests

  headers = {
      'Authorization': f'Bearer {api_token}'
  }

  response = requests.get(
      'https://connect.penbox.io/v1/forms',
      headers=headers
  )

  forms = response.json()
  ```

  ```php PHP theme={null}
  <?php
  $token = 'pnbx_1234567890abcdef1234567890abcdef1234567890abcdef';

  $ch = curl_init('https://connect.penbox.io/v1/forms');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer ' . $token
  ]);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  $forms = json_decode($response, true);
  ```
</CodeGroup>

### Making Authenticated Requests

Every API endpoint requires authentication. Here's an example creating a form request:

```javascript theme={null}
const apiToken = 'pnbx_1234567890abcdef1234567890abcdef1234567890abcdef';

const response = await fetch('https://connect.penbox.io/v1/forms', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    flow: { slug: 'client-onboarding' },
    user: {
      email: 'client@example.com',
      given_name: 'John',
      family_name: 'Doe'
    }
  })
});

const form = await response.json();
console.log('Form created:', form.id);
```

## Token Scopes and Permissions

Each API token is associated with a specific workspace. The token will have access to:

* All forms in the workspace
* All cases in the workspace
* All form templates enabled for the workspace
* All files and attachments in the workspace
* Document intelligence features for the workspace

<Note>
  Tokens are workspace-specific. If you need to access multiple workspaces, create a separate token for each one.
</Note>

## Token Security

### Best Practices

<AccordionGroup>
  <Accordion title="Store tokens securely" icon="lock">
    * Never commit tokens to version control (Git, SVN, etc.)
    * Store tokens in environment variables or secure credential management systems
    * Use secrets management services (AWS Secrets Manager, HashiCorp Vault, etc.)
    * Never expose tokens in client-side code or browser JavaScript
  </Accordion>

  <Accordion title="Use environment variables" icon="code">
    Store your API token in environment variables:

    ```bash .env theme={null}
    PENBOX_API_TOKEN=pnbx_1234567890abcdef1234567890abcdef1234567890abcdef
    ```

    Then load it in your application:

    ```javascript theme={null}
    const apiToken = process.env.PENBOX_API_TOKEN;
    ```
  </Accordion>

  <Accordion title="Rotate tokens regularly" icon="arrows-rotate">
    * Rotate tokens periodically for enhanced security
    * Create a new token before revoking the old one to avoid downtime
    * Update all applications using the old token
    * Revoke the old token once migration is complete
  </Accordion>

  <Accordion title="Use descriptive names" icon="tag">
    Give your tokens meaningful names to track usage:

    * ✅ "Production API - CRM Integration"
    * ✅ "Development Environment"
    * ✅ "Analytics Dashboard"
    * ❌ "Token 1", "Test", "My Token"
  </Accordion>

  <Accordion title="Monitor token usage" icon="chart-line">
    * Track which applications use which tokens
    * Monitor for unexpected API usage patterns
    * Set up alerts for unusual activity
    * Revoke tokens immediately if compromised
  </Accordion>
</AccordionGroup>

### What NOT to Do

<Warning>
  **Never:**

  * Commit tokens to Git repositories
  * Share tokens via email, chat, or screenshots
  * Store tokens in plain text files
  * Use the same token across multiple environments
  * Hardcode tokens in your source code
  * Post tokens in public forums or documentation
</Warning>

## Managing Tokens

### Viewing Active Tokens

Visit [app.penbox.io/workspace/settings/api](https://app.penbox.io/workspace/settings/api) to see all your active API tokens:

* Token name
* Creation date
* Last used date
* Associated workspace

### Revoking Tokens

To revoke a token:

1. Go to [app.penbox.io/workspace/settings/api](https://app.penbox.io/workspace/settings/api)
2. Find the token you want to revoke
3. Click the **"Revoke"** button
4. Confirm the action

<Note>
  Once revoked, a token is immediately invalidated. All API requests using that token will fail with a `401 Unauthorized` error.
</Note>

### Token Lifecycle

```mermaid theme={null}
graph LR
    A[Create Token] --> B[Use Token]
    B --> C{Still Needed?}
    C -->|Yes| B
    C -->|No| D[Revoke Token]
    C -->|Rotate| E[Create New Token]
    E --> F[Update Applications]
    F --> D
```

## Authentication Errors

### Common Error Responses

#### 401 Unauthorized - Missing Token

```json theme={null}
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Missing authorization header"
}
```

**Cause:** The `Authorization` header is missing from your request.

**Solution:** Add the `Authorization` header with your Bearer token.

#### 401 Unauthorized - Invalid Token

```json theme={null}
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Invalid token"
}
```

**Cause:** The token is invalid, expired, or has been revoked.

**Solution:** Check your token is correct, or create a new token if it was revoked.

#### 403 Forbidden - No Access

```json theme={null}
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "No access to this resource"
}
```

**Cause:** Your token doesn't have access to the requested resource (e.g., wrong workspace).

**Solution:** Verify you're using the correct token for the workspace you're trying to access.

### Debugging Authentication Issues

If you're experiencing authentication issues:

1. **Verify the token format**
   * Token should start with `pnbx_`
   * No extra spaces or newlines
   * Complete token copied

2. **Check the Authorization header**
   ```bash theme={null}
   Authorization: Bearer pnbx_your_token_here
   ```
   * Includes "Bearer " prefix with a space
   * Token immediately after the space

3. **Verify token is active**
   * Check [app.penbox.io/workspace/settings/api](https://app.penbox.io/workspace/settings/api)
   * Ensure token hasn't been revoked
   * Confirm token exists in the list

4. **Test with cURL**
   ```bash theme={null}
   curl -v -X GET 'https://connect.penbox.io/v1/workspaces' \
     -H 'Authorization: Bearer YOUR_TOKEN'
   ```
   The `-v` flag shows detailed request/response information.

## Rate Limiting

API tokens are subject to rate limiting to ensure fair usage and system stability.

### Rate Limit Exceeded

If you exceed the rate limit, you'll receive a `429 Too Many Requests` response:

```json theme={null}
{
  "statusCode": 429,
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Please try again later.",
  "retryAfter": 60
}
```

### Best Practices for Rate Limiting

* Cache responses when possible
* Implement exponential backoff on errors
* Monitor your usage patterns
* Spread requests over time instead of bursting
* Use webhooks instead of polling when possible

## Testing Your Authentication

### Quick Test

Test your token with a simple request to list workspaces:

```bash theme={null}
curl -X GET 'https://connect.penbox.io/v1/workspaces' \
  -H 'Authorization: Bearer YOUR_TOKEN'
```

**Expected response (success):**

```json theme={null}
{
  "data": [
    {
      "id": "...",
      "slug": "my-workspace",
      "name": "My Workspace"
    }
  ]
}
```

**Error response (invalid token):**

```json theme={null}
{
  "statusCode": 401,
  "error": "Unauthorized"
}
```

### Integration Checklist

Before deploying to production:

* [ ] Token stored securely (environment variable or secrets manager)
* [ ] Authorization header correctly formatted
* [ ] Error handling implemented for 401/403 responses
* [ ] Rate limiting handled with backoff strategy
* [ ] Token name clearly identifies the integration
* [ ] Monitoring/logging in place for API usage
* [ ] Token rotation plan documented

## Multiple Environments

For different environments, create separate tokens:

### Development

```bash theme={null}
PENBOX_API_TOKEN_DEV=pnbx_dev_token_here
```

### Staging

```bash theme={null}
PENBOX_API_TOKEN_STAGING=pnbx_staging_token_here
```

### Production

```bash theme={null}
PENBOX_API_TOKEN_PROD=pnbx_production_token_here
```

Then load the appropriate token based on your environment:

```javascript theme={null}
const apiToken = process.env.NODE_ENV === 'production'
  ? process.env.PENBOX_API_TOKEN_PROD
  : process.env.PENBOX_API_TOKEN_DEV;
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Create Forms" icon="file-lines" href="/api-reference/requests/create-request">
    Learn how to create forms
  </Card>

  <Card title="List Workspaces" icon="building" href="/api-reference/workspaces/list-workspaces">
    Retrieve your authorized workspaces
  </Card>

  <Card title="API Overview" icon="book" href="/api-reference/pen-connect-overview">
    Complete API capabilities guide
  </Card>

  <Card title="All Endpoints" icon="list" href="/api-reference/all-endpoints">
    Browse all available endpoints
  </Card>
</CardGroup>

## Support

If you encounter issues with authentication:

1. Check this documentation for troubleshooting steps
2. Verify your token at [app.penbox.io/workspace/settings/api](https://app.penbox.io/workspace/settings/api)
3. Test with the cURL examples above
4. Contact support at [support@penbox.io](mailto:support@penbox.io) with:
   * Token name (never send the actual token)
   * Error messages received
   * API endpoint being called
   * Request timestamp
