Skip to main content

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:
AspectDevelopmentStagingProduction
Target URLhttp://localhost:3000https://staging-api.example.comhttps://api.example.com
Secretsdev_api_keystaging_api_keyprod_api_key
Allowed IPsYour laptopStaging serverProduction servers
Rate LimitsUnlimited1000/min100/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:
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. Click Resources in sidebar
  2. Select Environments
  3. You’ll see “production” already exists

Step 2: Create Development Environment

Click Add Environment Environment Name:
development
Lowercase, no spaces. Used in API requests. Display Name:
Development
Friendly name shown in UI Description (optional):
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:
staging
Display Name:
Staging
Description:
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:
https://api.production.com
Inject Headers:
{
  "Authorization": "Bearer {{secret:prod_api_key}}"
}
Base Environment:
production
Save the base configuration.

Step 3: Add Environment Overrides

Now add overrides for development and staging.

Development Override

  1. Click Environment Overrides tab
  2. Select development environment
  3. Configure:
Target Base URL:
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:
https://staging-api.production.com
Override: Route to staging server Inject Headers:
{
  "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 Environment 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

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

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)

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

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

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 LogsAPI 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 → Environment 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:
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:
feature-new-dashboard
Hotfix:
hotfix-critical-bug
After merging: Delete the environment (no longer needed)

Next Steps

Now that you have environments set up:
  • Base Route: Default configuration (usually production)
  • Environment Override: Environment-specific changes (NULL = inherit)
  • Default Environment: Used when no header specified
  • Environment Clients: IP whitelist per environment

📊 Statistics

  • Level: beginner
  • Time: 10 minutes

🏷️ Tags

environments, configuration, deployment, quickstart