> ## 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.

# Testing Routes

> Use the built-in route tester to validate configuration before going live. Test headers, body, secrets, and response.

# Testing Routes

Use KnoxCall's built-in route tester to validate your configuration before sending real traffic.

## What is the Route Tester?

The **Route Tester** is a built-in tool that lets you:

* ✅ Test route configuration without writing code
* ✅ See exactly what headers/body are sent to your backend
* ✅ Verify secrets are injected correctly
* ✅ Test different HTTP methods
* ✅ Debug issues before going live
* ✅ No need for Postman or curl

## Access the Route Tester

### Option 1: From Route List

1. Navigate to **Routes**
2. Find your route
3. Click the **Test** button (🧪 icon)

### Option 2: From Route Details

1. Navigate to **Routes**
2. Click your route to open details
3. Click **Test Route** tab
4. Or click **Test** button in header

## Using the Route Tester

### Step 1: Select HTTP Method

Choose the method to test:

* GET
* POST
* PUT
* DELETE
* PATCH
* OPTIONS
* HEAD

### Step 2: Enter Path

Specify the URL path (appended to target base URL):

**Example:**

Target Base URL: `https://api.example.com`

Path: `/users/123`

**Result:** `https://api.example.com/users/123`

**Tips:**

* Include leading slash: `/api/users` ✅
* No leading slash: `api/users` ⚠️ (works but inconsistent)
* Can include query params: `/users?status=active`

### Step 3: Add Query Parameters (Optional)

Add query parameters that will be:

1. Sent to backend
2. Available in templates as `{{var:param_name}}`

**Example:**

| Key    | Value  |
| ------ | ------ |
| filter | active |
| sort   | name   |
| limit  | 10     |

**Result URL:** `/users?filter=active&sort=name&limit=10`

### Step 4: Add Request Headers (Optional)

Add custom headers to include in the request:

**Example:**

| Header          | Value            |
| --------------- | ---------------- |
| Content-Type    | application/json |
| X-Custom-Header | test-value       |

These are **in addition to** injected headers from route config.

### Step 5: Add Request Body (Optional)

For POST/PUT/PATCH requests, provide request body:

**JSON:**

```json theme={"dark"}
{
  "name": "John Doe",
  "email": "john@example.com",
  "status": "active"
}
```

**Form Data:**

```text theme={"dark"}
name=John+Doe&email=john@example.com
```

**Raw:**

```text theme={"dark"}
Any raw text or data
```

### Step 6: Select Environment (Optional)

Choose which environment to test:

* production (default)
* staging
* development
* Custom environments

This determines which environment override config is used.

### Step 7: Click "Send Test Request"

KnoxCall will:

1. Apply route configuration
2. Inject secrets (if any)
3. Apply environment overrides (if any)
4. Apply method-specific config (if any)
5. Send request to backend
6. Return response

## Understanding Test Results

### Request Details Section

Shows exactly what was sent to your backend:

**Request URL:**

```text theme={"dark"}
https://api.example.com/users/123?filter=active
```

**Request Method:**

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

**Request Headers:**

```text theme={"dark"}
Authorization: Bearer sk_live_abc123xyz789...
Content-Type: application/json
X-Custom-Header: test-value
X-Forwarded-For: 192.168.1.1
```

Notice:

* `Authorization` header was injected from route config
* Secret was decrypted and value inserted
* Custom headers are included

**Request Body:**

```json theme={"dark"}
{
  "name": "John Doe",
  "email": "john@example.com",
  "api_key": "sk_live_abc123..."
}
```

Notice:

* `api_key` was injected from body template
* Secret was decrypted

### Response Details Section

Shows what your backend returned:

**Status Code:**

```text theme={"dark"}
200 OK
```

**Response Headers:**

```text theme={"dark"}
Content-Type: application/json
X-Request-ID: req_abc123
Cache-Control: no-cache
```

**Response Body:**

```json theme={"dark"}
{
  "id": 123,
  "name": "John Doe",
  "email": "john@example.com",
  "created_at": "2025-01-15T10:30:00Z"
}
```

**Response Time:**

```text theme={"dark"}
245ms
```

### Config Applied Section

Shows which configuration was used:

**Environment:**

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

**Method Config:**

```text theme={"dark"}
POST method config (overrides global)
```

**Secrets Injected:**

```text theme={"dark"}
- stripe_api_key → sk_live_abc... (in Authorization header)
- database_url → postgres://... (in body)
```

**Rate Limit:**

```text theme={"dark"}
Not enforced in test mode
```

**Signature:**

```text theme={"dark"}
Not required in test mode
```

<Note>
  **Test mode bypasses some security checks:**

  * Rate limiting is not enforced
  * Client IP authorization is skipped
  * Signatures are not required

  This lets you test freely without hitting limits or needing signatures.
</Note>

## Example Test Scenarios

### Scenario 1: Test Secret Injection

**Goal:** Verify Stripe API key is injected correctly

**Setup:**

1. Select method: POST
2. Path: `/charges`
3. Body:
   ```json theme={"dark"}
   {
     "amount": 1000,
     "currency": "usd"
   }
   ```
4. Send request

**Verify:**

* Request headers show: `Authorization: Bearer sk_live_...` (actual key, not template)
* Response from Stripe API (charge created)
* No errors about authentication

### Scenario 2: Test Method-Specific Config

**Goal:** Verify POST uses different headers than GET

**Test GET:**

1. Method: GET
2. Path: `/users`
3. Send request
4. **Check:** Authorization header uses `read_key`

**Test POST:**

1. Method: POST
2. Path: `/users`
3. Body: `{"name": "Test"}`
4. Send request
5. **Check:** Authorization header uses `write_key`

### Scenario 3: Test Environment Override

**Goal:** Verify staging environment uses staging URL

**Setup:**

1. Method: GET
2. Path: `/health`
3. Environment: **staging**
4. Send request

**Verify:**

* Request URL shows staging URL: `https://staging-api.example.com/health`
* Not production URL

### Scenario 4: Test Query Param Variables

**Goal:** Verify `{{var:filter}}` is replaced correctly

**Setup:**

1. Method: GET
2. Path: `/users`
3. Query params:
   * `filter` = `active`
4. Send request

**Verify:**

* Request headers show: `X-Filter: active` (variable replaced)
* Not: `X-Filter: {{var:filter}}` (literal template)

### Scenario 5: Test Error Handling

**Goal:** See how backend handles invalid data

**Setup:**

1. Method: POST
2. Path: `/users`
3. Body:
   ```json theme={"dark"}
   {
     "email": "invalid-email"
   }
   ```
4. Send request

**Verify:**

* Status code: 400 Bad Request
* Response body shows validation error
* Error message is clear

## Common Test Cases

### ✅ Before Going Live Checklist

Test these scenarios before sending real traffic:

* [ ] **GET request works**
  * Returns expected data
  * Correct headers injected
  * Secrets work

* [ ] **POST request works**
  * Creates resource successfully
  * Body template works
  * Secrets injected correctly

* [ ] **PUT/PATCH request works**
  * Updates resource
  * Idempotency works (if applicable)

* [ ] **DELETE request works**
  * Deletes resource
  * Correct permissions

* [ ] **Test each environment**
  * Production URL
  * Staging URL
  * Development URL

* [ ] **Test method configs**
  * Each method uses correct config
  * Secrets differ per method

* [ ] **Test error cases**
  * Invalid data returns 400
  * Missing auth returns 401
  * Not found returns 404

* [ ] **Test with real data**
  * Not just test values
  * Actual production-like payloads

## Troubleshooting with Route Tester

### Issue: "Connection refused"

**Possible causes:**

* Target URL is wrong
* Backend server is down
* Firewall blocking KnoxCall IPs

**Debug:**

1. Check target URL in route config
2. Verify backend is running: `curl https://your-backend.com/health`
3. Check backend firewall allows KnoxCall IPs

### Issue: "401 Unauthorized"

**Possible causes:**

* Secret not injected
* Wrong secret value
* Secret expired

**Debug:**

1. Check "Request Headers" section
2. Verify `Authorization` header present
3. Check secret value is correct (not template literal)
4. Test secret directly with backend

### Issue: Template Not Replaced

**Symptoms:** Backend receives `{{secret:api_key}}` literal

**Causes:**

* Secret doesn't exist
* Typo in secret name
* Wrong template syntax

**Debug:**

1. Check "Secrets Injected" section
2. Verify secret exists: **Secrets** page
3. Check spelling: `{{secret:api_key}}` not `{{api_key}}`

### Issue: "502 Bad Gateway"

**Possible causes:**

* Backend took too long (timeout)
* Backend returned invalid response
* Backend crashed

**Debug:**

1. Check response time (>30 seconds?)
2. Check backend logs for errors
3. Test backend directly: `curl https://your-backend.com/endpoint`

### Issue: Wrong Environment Used

**Symptoms:** Request went to production instead of staging

**Debug:**

1. Check environment dropdown selection
2. Verify environment override exists
3. Check "Config Applied" section shows correct environment

## Generate Code Snippets

The Route Tester has a **Code** tab that generates a ready-to-run snippet for calling
the route from your own application. It is useful for copying a working request out of
the tester and into your codebase, CI/CD pipeline, or terminal.

1. Open the Route Tester
2. Switch to the **Code** tab
3. Pick a language: cURL, JavaScript, Python, PHP, Go, Java, C#, Ruby, or C++
4. Click the copy button to copy the snippet to your clipboard

The generated snippet reflects your current method, path, request body, and environment
selection, and includes the correct KnoxCall headers (`x-knoxcall-key`,
`x-knoxcall-route`, and `x-knoxcall-environment` when a non-base environment is
selected). The cURL snippet looks like:

```bash theme={"dark"}
curl -X POST 'https://your-slug.knoxcall.com/api/users' \
  -H 'x-knoxcall-key: $KNOXCALL_API_KEY' \
  -H 'x-knoxcall-route: <route-id>' \
  -H 'Content-Type: application/json' \
  -d '{"name":"John"}'
```

## Best Practices

### 1. Test Before Deploy

Always test routes before sending production traffic.

### 2. Test All Methods

Don't just test GET - test POST, PUT, DELETE too.

### 3. Test All Environments

Verify dev, staging, prod all work.

### 4. Test Error Cases

Don't only test happy path - test failures too.

### 5. Save Test Cases

Document test cases in route description or wiki.

### 6. Test After Changes

Re-test after changing:

* Route config
* Secrets
* Environment overrides
* Backend URL

### 7. Use Real Data

Test with actual production-like data, not just `{"test": "data"}`.

### 8. Check Response Times

Monitor how long requests take. Optimize if >1 second.

## Limitations

### Rate Limiting Bypassed

Test mode doesn't enforce rate limits. Don't use for load testing.

### IP Authorization Skipped

Test requests don't check client IP whitelist.

### Signatures Not Required

Test mode doesn't require HMAC signatures.

### Real Backend Impact

Test requests **actually hit your backend**. They're not simulated.

<Warning>
  **Test requests are real!** They actually call your backend API. Be careful testing:

  * DELETE requests (will delete data!)
  * POST requests (will create data)
  * Payment endpoints (will charge real money!)

  Use test/staging environments when possible.
</Warning>

## Related Features

* **Method Configs**: Test different configs per HTTP method
* **Environments**: Test staging before production
* **Secrets**: Verify secrets inject correctly
* **Logs**: View historical requests and replay them

## Next Steps

<CardGroup cols={2}>
  <Card title="Method Configs" icon="code-branch" href="/advanced/method-specific-config">
    Test method-specific configurations
  </Card>

  <Card title="Environments" icon="layer-group" href="/getting-started/first-environment">
    Test different environments
  </Card>

  <Card title="API Logs" icon="list" href="/monitoring/api-logs">
    View real request logs
  </Card>

  <Card title="Secrets" icon="key" href="/getting-started/first-secret">
    Verify secret injection
  </Card>
</CardGroup>

***

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

  <Card title="🏷️ Tags" icon="tags">
    `testing`, `debugging`, `routes`, `tools`
  </Card>
</CardGroup>
