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

# Authentication

> Learn how to authenticate your API requests with workspace API keys

## Overview

The Voyant API uses **API keys** for authentication. Each API key is scoped to a specific workspace and automatically filters all data access to that workspace context.

<Warning>
  API keys provide complete access to your workspace data. Never share them publicly or commit them
  to version control.
</Warning>

## API key format

API keys are workspace-scoped credentials that look like this:

```
voy_ws_1a2b3c4d5e6f7g8h9i0j
```

Each API key includes:

* **Workspace ID**: Automatically determined from the key
* **Scopes**: Optional permissions limiting API access
* **Rate limits**: Per-workspace request limits
* **Status**: Active or revoked

## Authentication methods

### Authorization header (recommended)

Pass your API key using the `Authorization: Bearer <token>` header with every request:

```bash theme={null}
curl https://api.voyantcloud.com/v1/products \
  -H "Authorization: Bearer YOUR_API_KEY"
```

<Tip>This is the recommended method as it keeps your API key out of URLs and query strings.</Tip>

### Internal API authentication

For internal services, you can use an internal API key with explicit workspace specification:

```bash theme={null}
curl https://api.voyantcloud.com/v1/products \
  -H "Authorization: Bearer INTERNAL_API_KEY" \
  -H "x-workspace-id: ws_123abc"
```

<Note>
  Internal API keys are only available to Voyant system services and are not accessible to
  customers.
</Note>

## Managing API keys

### Creating an API key

<Steps>
  <Step title="Access workspace settings">
    Log in to your Voyant dashboard and navigate to workspace settings.
  </Step>

  <Step title="Go to API keys section">Find the **API Keys** tab in your workspace settings.</Step>

  <Step title="Generate new key">
    Click **Generate New Key** and provide a descriptive name (e.g., "Production API", "Staging
    Environment").
  </Step>

  <Step title="Copy and secure">
    Copy the API key immediately. It will only be displayed once. Store it securely in your environment variables or secrets manager.

    <Check>
      Save the key in a password manager or environment variable immediately.
    </Check>
  </Step>
</Steps>

### Rotating API keys

For security best practices, rotate your API keys periodically:

<Steps>
  <Step title="Generate new key">
    Create a new API key before revoking the old one to avoid downtime.
  </Step>

  <Step title="Update applications">
    Deploy the new key to all applications and services that use the API.
  </Step>

  <Step title="Verify functionality">Test that all integrations work with the new key.</Step>

  <Step title="Revoke old key">
    Once verified, revoke the old key from the workspace settings.
  </Step>
</Steps>

<Tip>Keep both keys active during the transition period to ensure zero-downtime key rotation.</Tip>

### Revoking API keys

Immediately revoke an API key if:

* It has been exposed publicly
* An employee with access has left
* You're migrating to a new key
* You suspect unauthorized access

<Warning>
  Revoking an API key is immediate and cannot be undone. All requests with that key will fail
  instantly.
</Warning>

### Propagation

Key changes take effect quickly across our platform. In most cases they are active immediately; allow
up to about a minute for caches to refresh in edge locations.

* Revocations stop new requests right away; rotate keys during low-traffic windows to avoid client cache hiccups.
* Scoped keys enforce minimum permissions and support wildcards (`products:*`, `*:read`, `*`).
* For best results, update your applications first, verify, then revoke old keys.

## Security best practices

### Environment variables

Always store API keys in environment variables, never in code:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    // ✅ Correct - use environment variables
    const apiKey = process.env.VOYANT_API_KEY;

    // ❌ Wrong - never hardcode keys
    const apiKey = "voy_ws_1a2b3c4d5e6f7g8h9i0j";
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import os

    # ✅ Correct - use environment variables
    api_key = os.environ['VOYANT_API_KEY']

    # ❌ Wrong - never hardcode keys
    api_key = "voy_ws_1a2b3c4d5e6f7g8h9i0j"
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    <?php
    // ✅ Correct - use environment variables
    $apiKey = getenv('VOYANT_API_KEY');

    // ❌ Wrong - never hardcode keys
    $apiKey = "voy_ws_1a2b3c4d5e6f7g8h9i0j";
    ?>
    ```
  </Tab>
</Tabs>

### Server-side only

<Warning>
  Never use API keys in client-side JavaScript, mobile apps, or any publicly accessible code.
</Warning>

API keys should only be used from secure server environments:

* ✅ Backend servers (Node.js, Python, PHP, Ruby, Go, etc.)
* ✅ Serverless functions (AWS Lambda, Cloudflare Workers, Vercel Functions)
* ✅ Internal services and microservices
* ❌ Frontend JavaScript (React, Vue, Angular)
* ❌ Mobile applications (iOS, Android)
* ❌ Desktop applications with embedded keys

### HTTPS only

Always use HTTPS when making API requests to protect your API key in transit:

```bash theme={null}
# ✅ Correct - HTTPS
https://api.voyantcloud.com/v1/products

# ❌ Wrong - HTTP (insecure)
http://api.voyantcloud.com/v1/products
```

### Minimal permissions

When creating API keys, grant only the minimum required permissions:

* Use scoped keys for specific operations when available
* Use sandbox workspaces for development and testing
* Create separate keys for each workspace

### Monitor key usage

Regularly review API key usage in your workspace settings:

* Check access logs for unusual patterns
* Monitor rate limit consumption
* Review which keys are actively used
* Revoke unused keys

## Workspace context

All API operations are automatically scoped to the workspace associated with your API key:

```bash theme={null}
# This request will only return products from your workspace
curl https://api.voyantcloud.com/v1/products \
  -H "Authorization: Bearer YOUR_API_KEY"
```

<Info>
  You never need to specify a workspace ID in API requests. The workspace context is automatically
  determined from your API key.
</Info>

### Multi-workspace access

If you need to access multiple workspaces, you must:

1. Generate a separate API key for each workspace
2. Use the appropriate key for each request
3. Manage keys separately in your application

<Tip>
  Use environment variables with descriptive names for each workspace:

  ```bash theme={null}
  VOYANT_API_KEY_LIVE=voy_ws_live123...
  VOYANT_API_KEY_SANDBOX=voy_ws_sandbox456...
  ```
</Tip>

## Rate limiting

Rate limits depend on your workspace type:

**Live workspaces:**

* **3,000 requests per minute**
* **30 requests per second** burst

**Sandbox workspaces:**

* **100 requests per minute**
* **5 requests per second** burst

Pricing is usage-based—no tiers or enterprise upgrades required.

Rate limit headers are included in every response:

```
X-RateLimit-Limit: 3000
X-RateLimit-Remaining: 2988
X-RateLimit-Reset: 1704067200
```

<Warning>
  Exceeding rate limits will result in `429 Too Many Requests` responses. Implement exponential
  backoff in your application.
</Warning>

## Error responses

Authentication errors return specific status codes:

<ResponseExample>
  ```json 401 Unauthorized - Missing or invalid Authorization Bearer token theme={null}
  {
    "error": "Unauthorized"
  }
  ```

  ```json 403 Forbidden - Valid key but insufficient permissions theme={null}
  {
    "error": "Forbidden"
  }
  ```

  ```json 429 Too Many Requests - Rate limit exceeded theme={null}
  {
    "error": "Rate limit exceeded",
    "retry_after": 30
  }
  ```
</ResponseExample>

## Testing authentication

Verify your API key works correctly:

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.voyantcloud.com/v1/products \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -v
  ```

  ```javascript Node.js theme={null}
  const apiKey = process.env.VOYANT_API_KEY

  const response = await fetch("https://api.voyantcloud.com/v1/products", {
    headers: { Authorization: `Bearer ${apiKey}` },
  })

  if (response.ok) {
    console.log("✅ Authentication successful")
  } else {
    console.error("❌ Authentication failed:", response.status)
  }
  ```

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

  api_key = os.environ['VOYANT_API_KEY']
  response = requests.get(
    'https://api.voyantcloud.com/v1/products',
    headers={'Authorization': f'Bearer {api_key}'}
  )

  if response.ok:
      print('✅ Authentication successful')
  else:
      print(f'❌ Authentication failed: {response.status_code}')
  ```
</CodeGroup>

<Check>A successful response with `200 OK` confirms your API key is valid and working.</Check>

## Troubleshooting

### Common authentication issues

<AccordionGroup>
  <Accordion title="401 Unauthorized - Invalid API key">
    * Verify you copied the complete API key
    * Check for extra spaces or line breaks
    * Ensure the key hasn't been revoked
    * Confirm you're using the correct header (`Authorization`) and Bearer scheme
  </Accordion>

  <Accordion title="429 Rate limit exceeded">
    * Implement request throttling in your application - Use exponential backoff for retries - Contact
      support for higher rate limits if needed - Cache responses when appropriate
  </Accordion>

  <Accordion title="Key rotation not working">
    * Ensure new key is active before revoking old one
    * Check all services are using the new key
    * Verify environment variables are updated
    * Allow DNS/CDN cache to clear (up to 5 minutes)
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Make your first authenticated API request
  </Card>

  <Card title="Rate limits" icon="gauge" href="/concepts/rate-limits">
    Learn about rate limiting and best practices
  </Card>

  <Card title="API reference" icon="code" href="/api-reference/introduction">
    Explore all available endpoints
  </Card>

  <Card title="Error handling" icon="triangle-exclamation" href="/api-reference/errors">
    Handle authentication and other API errors
  </Card>
</CardGroup>
