Authentication

Knify uses API key authentication to secure all API requests.

API Keys

Every request to the Knify API requires an API key in the Authorization header:

Authorization: Bearer your_api_key_here

Getting API Keys

For Organizations

Contact your Knify administrator to generate API keys for your team.

Self-Hosted Instances

Generate keys using the Knify CLI:

# Generate a new API key
python scripts/create_api_key.py \
  --name "Production API Key" \
  --workspace ws_abc123

Response:

{
  "key_id": "key_xyz789",
  "api_key": "knify_live_abc123def456...",
  "name": "Production API Key",
  "workspace_id": "ws_abc123",
  "created_at": "2025-11-17T10:00:00Z"
}

Important: Save your API key immediately. For security reasons, it won't be shown again.

Using API Keys

Command Line (curl)

export KNIFY_API_KEY="knify_live_abc123def456..."

curl https://api.knify.io/jobs \
  -H "Authorization: Bearer $KNIFY_API_KEY"

Python

import requests

API_KEY = "knify_live_abc123def456..."
BASE_URL = "https://api.knify.io"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

response = requests.post(
    f"{BASE_URL}/jobs",
    headers=headers,
    json={"spec": {"job_type": "cursor_task", "prompt": "Hello"}}
)

JavaScript/Node.js

const KNIFY_API_KEY = 'knify_live_abc123def456...';
const BASE_URL = 'https://api.knify.io';

const response = await fetch(`${BASE_URL}/jobs`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${KNIFY_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    spec: {
      job_type: 'cursor_task',
      prompt: 'Hello'
    }
  })
});

API Key Types

Production Keys

Used for production workloads:

knify_live_...

Characteristics:

  • Full API access
  • No rate limit restrictions (based on plan)
  • Suitable for production deployments

Test Keys

Used for development and testing:

knify_test_...

Characteristics:

  • Same API access as production
  • Lower rate limits
  • Free sandbox usage (limited)
  • Ideal for development

Key Management

Rotating Keys

Regularly rotate API keys for security:

  1. Generate a new key
  2. Update your applications to use the new key
  3. Revoke the old key after verification
# Revoke an API key
curl -X DELETE https://api.knify.io/keys/{key_id} \
  -H "Authorization: Bearer $ADMIN_API_KEY"

Key Permissions

Keys can be scoped to specific permissions:

{
  "permissions": [
    "jobs:create",
    "jobs:read",
    "jobs:continue",
    "workspaces:read"
  ]
}

Available Permissions:

  • jobs:create - Create new jobs
  • jobs:read - View job details and events
  • jobs:continue - Continue existing jobs
  • jobs:cleanup - Clean up sandboxes
  • workspaces:read - View workspaces
  • workspaces:write - Upload/modify workspaces
  • admin:all - Full administrative access

Workspace Scoping

Keys can be limited to specific workspaces:

python scripts/create_api_key.py \
  --name "Team A Key" \
  --workspace ws_team_a \
  --permissions jobs:create,jobs:read

This key can only create and read jobs, and only within workspace ws_team_a.

Security Best Practices

1. Never Commit Keys

Add API keys to .gitignore:

# .gitignore
.env
.env.local
*.key
secrets/

2. Use Environment Variables

Store keys in environment variables, not code:

# .env
KNIFY_API_KEY=knify_live_...
KNIFY_WORKSPACE_ID=ws_abc123
import os
from dotenv import load_dotenv

load_dotenv()

API_KEY = os.getenv('KNIFY_API_KEY')

3. Rotate Regularly

Set up automatic key rotation:

# Cron job to rotate keys monthly
0 0 1 * * /usr/local/bin/rotate-knify-keys.sh

4. Monitor Usage

Track API key usage via the dashboard:

curl https://api.knify.io/keys/{key_id}/usage \
  -H "Authorization: Bearer $ADMIN_API_KEY"

Response:

{
  "key_id": "key_xyz789",
  "requests_today": 142,
  "requests_this_month": 3821,
  "rate_limit": 1000,
  "last_used": "2025-11-17T10:00:00Z"
}

5. Use Least Privilege

Only grant necessary permissions:

# Good: Limited permissions
--permissions jobs:read

# Bad: Excessive permissions
--permissions admin:all

Troubleshooting

401 Unauthorized

Cause: Missing or invalid API key

Solution: Verify your API key:

curl https://api.knify.io/keys/verify \
  -H "Authorization: Bearer $KNIFY_API_KEY"

403 Forbidden

Cause: Insufficient permissions

Solution: Check key permissions:

curl https://api.knify.io/keys/{key_id} \
  -H "Authorization: Bearer $ADMIN_API_KEY"

Request additional permissions from your administrator.

429 Too Many Requests

Cause: Rate limit exceeded

Solution:

  • Wait for rate limit reset (see X-RateLimit-Reset header)
  • Upgrade to a higher tier
  • Implement request throttling

Webhook Authentication

Webhooks from Knify include a signature header for verification:

X-Knify-Signature: sha256=abc123...

Verify webhooks:

import hmac
import hashlib

def verify_webhook(payload, signature, secret):
    computed = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    
    expected = f"sha256={computed}"
    return hmac.compare_digest(expected, signature)
Get Started

Create your first job with Knify.