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

# Creating Your First Environment

> Set up dev, staging, and production environments. Route the same API to different backends based on environment.

# Creating Your First Environment

Set up development, staging, and production environments to safely test changes before deploying to production.

## What is an Environment?

An **environment** in KnoxCall allows you to use the **same route** with **different configurations** for dev, staging, and production.

**Same route, different configurations per environment:**

| Aspect          | Development             | Staging                           | Production                |
| --------------- | ----------------------- | --------------------------------- | ------------------------- |
| **Target URL**  | `http://localhost:3000` | `https://staging-api.example.com` | `https://api.example.com` |
| **Secrets**     | `dev_api_key`           | `staging_api_key`                 | `prod_api_key`            |
| **Allowed IPs** | Your laptop             | Staging server                    | Production servers        |
| **Rate Limits** | Unlimited               | 1000/min                          | 100/min                   |

## Why Use Environments?

✅ **Test safely**: Try changes in dev/staging before production

✅ **Prevent mistakes**: Can't accidentally break production

✅ **Easy switching**: Change environment with one header

✅ **Different security**: Relaxed limits for dev, strict for prod

✅ **Separate credentials**: Dev keys for dev, prod keys for prod

## Understanding Environment Overrides

KnoxCall uses a **base + override** system:

1. **Base route**: Default configuration (usually production)
2. **Environment overrides**: Environment-specific changes

**Override pattern**: `NULL = inherit from base`

**Example:**

```text theme={"dark"}
Base Route (production):
  target_url: https://api.production.com
  inject_headers: {"X-API-Key": "{{secret:prod_key}}"}
  rate_limit: 100/min

Development Override:
  target_url: http://localhost:3000       (overridden)
  inject_headers: NULL                     (inherited from base)
  rate_limit: NULL                         (inherited from base)

Staging Override:
  target_url: https://api.staging.com     (overridden)
  inject_headers: {"X-API-Key": "{{secret:staging_key}}"}  (overridden)
  rate_limit: 1000/min                     (overridden)
```

## Create Environments

By default, KnoxCall creates a **"production"** environment for you. Let's add development and staging.

### Step 1: Navigate to Environments

1. Open the **Proxy** section in the sidebar
2. Select **Environments**
3. You'll see "production" already exists

### Step 2: Create Development Environment

Click **Add Environment**

**Environment Name:**

```text theme={"dark"}
development
```

*Lowercase, no spaces. Used in API requests.*

**Display Name:**

```text theme={"dark"}
Development
```

*Friendly name shown in UI*

**Description** (optional):

```text theme={"dark"}
Local development servers and testing
```

**Color:** Choose a color

* 🟢 Green (`#00ff88`) for development

**Set as Default:** ❌ NO
*Leave production as default*

Click **Create**

### Step 3: Create Staging Environment

Click **Add Environment** again

**Environment Name:**

```text theme={"dark"}
staging
```

**Display Name:**

```text theme={"dark"}
Staging
```

**Description:**

```text theme={"dark"}
Pre-production testing environment
```

**Color:**

* 🟡 Yellow (`#ffaa00`) for staging

**Set as Default:** ❌ NO

Click **Create**

Now you have three environments: development, staging, production!

## Configure Route for Environments

Now configure your route to use different URLs per environment.

### Step 1: Edit Your Route

1. Navigate to **Routes**
2. Click your route (e.g., "my-first-route")
3. Click **Edit**

### Step 2: Set Base Configuration (Production)

This is your **base environment** (production):

**Target Base URL:**

```text theme={"dark"}
https://api.production.com
```

**Inject Headers:**

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:prod_api_key}}"
}
```

**Base Environment:**

```text theme={"dark"}
production
```

Save the base configuration.

### Step 3: Add Environment Overrides

Now add overrides for development and staging.

#### Development Override

1. Click **Environment** tab
2. Select **development** environment
3. Configure:

**Target Base URL:**

```text theme={"dark"}
http://localhost:3000
```

*Override: Route to local dev server*

**Inject Headers:** Leave NULL
*Inherit from base (uses same header template)*

**Rate Limit:** Leave NULL
*Inherit from base*

**Require Signature:** Leave NULL
*Inherit from base*

Save development override.

#### Staging Override

1. Select **staging** environment
2. Configure:

**Target Base URL:**

```text theme={"dark"}
https://staging-api.production.com
```

*Override: Route to staging server*

**Inject Headers:**

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:staging_api_key}}"
}
```

*Override: Use staging API key instead of prod*

**Rate Limit:** Leave NULL or set different limit
*Can be inherited or overridden*

Save staging override.

### Step 4: Assign Environment-Specific Clients

Now assign different IP addresses per environment:

#### Development

1. Go to **Clients** tab
2. Select "development"
3. Assign your laptop/dev machine IP
4. Example: `dev-laptop` (203.45.67.89)

#### Staging

1. Select "staging"
2. Assign staging server IPs
3. Example: `staging-server` (34.56.78.90)

#### Production

1. Select "production"
2. Assign production server IPs
3. Example: `prod-server-1`, `prod-server-2`

## Use Environments in Requests

Specify the environment via the `x-knoxcall-environment` header:

### Development Request

```bash theme={"dark"}
curl -X GET "https://a1b2c3d4.DunderMifflin.knoxcall.com/api/users" \
  -H "x-knoxcall-key: tk_abc123..." \
  -H "x-knoxcall-route: my-route" \
  -H "x-knoxcall-environment: development"
```

This routes to: `http://localhost:3000/api/users`

### Staging Request

```bash theme={"dark"}
curl -X GET "https://a1b2c3d4.DunderMifflin.knoxcall.com/api/users" \
  -H "x-knoxcall-key: tk_abc123..." \
  -H "x-knoxcall-route: my-route" \
  -H "x-knoxcall-environment: staging"
```

This routes to: `https://staging-api.production.com/api/users`

### Production Request (Default)

```bash theme={"dark"}
curl -X GET "https://a1b2c3d4.DunderMifflin.knoxcall.com/api/users" \
  -H "x-knoxcall-key: tk_abc123..." \
  -H "x-knoxcall-route: my-route"
```

No environment header = uses base environment (production)

This routes to: `https://api.production.com/api/users`

## JavaScript Examples

### With Environment Switching

```javascript theme={"dark"}
const ENVIRONMENT = process.env.NODE_ENV; // 'development', 'staging', 'production'

const headers = {
  "x-knoxcall-key": process.env.KNOXCALL_API_KEY,
  "x-knoxcall-route": "my-route"
};

// Add environment header for non-production
if (ENVIRONMENT !== 'production') {
  headers["x-knoxcall-environment"] = ENVIRONMENT;
}

fetch("https://a1b2c3d4.DunderMifflin.knoxcall.com/api/users", {
  headers
})
.then(res => res.json())
.then(data => console.log(data));
```

### Environment-Specific Logic

```javascript theme={"dark"}
class ApiClient {
  constructor(environment = 'production') {
    this.baseUrl = "https://a1b2c3d4.DunderMifflin.knoxcall.com";
    this.environment = environment;
    this.apiKey = process.env.KNOXCALL_API_KEY;
  }

  async request(path, options = {}) {
    const headers = {
      "x-knoxcall-key": this.apiKey,
      "x-knoxcall-route": "my-route",
      ...options.headers
    };

    // Only add environment header if not production
    if (this.environment !== 'production') {
      headers["x-knoxcall-environment"] = this.environment;
    }

    const response = await fetch(`${this.baseUrl}${path}`, {
      ...options,
      headers
    });

    return response.json();
  }
}

// Usage
const devClient = new ApiClient('development');
const prodClient = new ApiClient('production');

await devClient.request('/api/users');  // → http://localhost:3000/api/users
await prodClient.request('/api/users'); // → https://api.production.com/api/users
```

## View Environment Activity

### In Request Logs

1. Navigate to **Logs** → **API Logs**
2. See **Environment** badge on each request
3. Filter by environment

### In Analytics

1. Navigate to **Analytics**
2. Group by environment
3. Compare traffic across dev/staging/prod

## Best Practices

### Environment Naming

**Recommended names:**

* `development` (or `dev`)
* `staging` (or `stage`)
* `production` (or `prod`)

**Avoid:**

* Capital letters
* Spaces
* Special characters (except hyphens)

### Default Environment

**Always set production as default!**

If clients forget the environment header, they should hit production (not dev/staging).

This prevents accidental dev traffic in production apps.

### Environment Colors

Use colors for quick visual identification:

* 🔴 **Production**: Red (`#ff0055`) - be careful!
* 🟡 **Staging**: Yellow (`#ffaa00`) - caution
* 🟢 **Development**: Green (`#00ff88`) - safe to experiment

### Separate Secrets Per Environment

**Don't** use the same API keys for dev and production!

**Do** create environment-specific secrets:

* `stripe_dev_key`
* `stripe_staging_key`
* `stripe_prod_key`

### Different Rate Limits

**Development:** Unlimited (or very high)

* Fast iteration, no throttling during testing

**Staging:** Moderate (1000/min)

* Test rate limiting behavior

**Production:** Strict (100/min)

* Protect your backend

## Common Issues

### Environment Not Found

**Error:** `Environment 'staging' not found`

**Causes:**

* Typo in environment name
* Environment doesn't exist
* Environment name is case-sensitive

**Fix:**

* Check environment name spelling
* Verify environment exists in Environments page
* Use exact lowercase name

### Wrong Backend Reached

**Symptoms:** Development request hits production API

**Causes:**

* Missing `x-knoxcall-environment` header
* Typo in header value
* Environment override not configured

**Fix:**

* Add header: `x-knoxcall-environment: development`
* Check header spelling (lowercase)
* Verify environment override has correct target URL

### "IP not authorized" in New Environment

**Cause:** You created a new environment but didn't assign clients to it

**Fix:**

1. Go to route → **Clients** tab
2. Select the new environment
3. Assign clients (IP addresses)
4. Save

### NULL vs Empty String

**NULL (not set):** Inherits from base
**Empty string `""`:** Overrides with empty value

**Example:**

```text theme={"dark"}
Base: inject_headers = {"X-Key": "abc"}

Override with NULL: inject_headers = NULL
  → Result: {"X-Key": "abc"} (inherited)

Override with {}: inject_headers = {}
  → Result: {} (no headers injected)
```

## Advanced: Temporary Environments

For large features or hotfixes, create temporary environments:

**Feature branch:**

```text theme={"dark"}
feature-new-dashboard
```

**Hotfix:**

```text theme={"dark"}
hotfix-critical-bug
```

**After merging:** Delete the environment (no longer needed)

## Next Steps

Now that you have environments set up:

<CardGroup cols={2}>
  <Card title="Environment Workflows" icon="rocket" href="/essentials/environments/environment-workflows">
    Learn safe deployment strategies
  </Card>

  <Card title="Secret Management" icon="key" href="/essentials/secrets/secrets-overview">
    Create environment-specific secrets
  </Card>

  <Card title="Per-Environment Clients" icon="network-wired" href="/getting-started/first-client">
    Assign different IPs per environment
  </Card>

  <Card title="Rate Limiting" icon="gauge" href="/advanced/rate-limiting">
    Configure different limits per environment
  </Card>
</CardGroup>

## Related Concepts

* **Base Route**: Default configuration (usually production)
* **Environment Override**: Environment-specific changes (NULL = inherit)
* **Default Environment**: Used when no header specified
* **Per-environment clients**: IP whitelist per environment

***

<CardGroup cols={2}>
  <Card title="📊 Statistics" icon="chart-line">
    * **Level**: beginner
    * **Time**: 10 minutes
  </Card>

  <Card title="🏷️ Tags" icon="tags">
    `environments`, `configuration`, `deployment`, `quickstart`
  </Card>
</CardGroup>
