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

# Create API Key

> Create a new API key for accessing the ZKScore API

## Overview

Create a new API key with specific permissions and rate limits for accessing the ZKScore API. This endpoint allows developers to generate secure API keys that can be used to authenticate requests and access platform features.

<Tip>
  Use this endpoint to create API keys for your applications. Store the API key securely and never expose it in client-side code. Use environment variables or secure key management systems.
</Tip>

## Parameters

<ParamField body="name" type="string" required>
  Human-readable name for the API key

  <Note>
    Choose a descriptive name that helps identify the key's purpose (e.g., "Production App", "Development Testing")
  </Note>
</ParamField>

<ParamField body="description" type="string">
  Optional description of the API key's intended use
</ParamField>

<ParamField body="permissions" type="array" required>
  Array of permissions for the API key

  <Expandable title="available permissions">
    <ParamField body="permissions[].resource" type="string">
      Resource type

      * `identity` - Identity management
      * `scores` - Score queries
      * `achievements` - Achievement operations
      * `trading` - Trading data
      * `trust` - Trust layer operations
      * `attestations` - Attestation management
      * `all` - All resources
    </ParamField>

    <ParamField body="permissions[].actions" type="array">
      Allowed actions

      * `read` - Read operations
      * `write` - Write operations
      * `delete` - Delete operations
      * `all` - All actions
    </ParamField>

    <ParamField body="permissions[].restrictions" type="object">
      Optional restrictions

      <Expandable title="restriction properties">
        <ParamField body="permissions[].restrictions.identities" type="array">
          Specific identities the key can access
        </ParamField>

        <ParamField body="permissions[].restrictions.chains" type="array">
          Specific blockchain networks
        </ParamField>

        <ParamField body="permissions[].restrictions.ipWhitelist" type="array">
          Allowed IP addresses
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="rateLimit" type="object">
  Rate limiting configuration

  <Expandable title="rateLimit properties">
    <ParamField body="rateLimit.requestsPerMinute" type="number">
      Maximum requests per minute (default: 60)
    </ParamField>

    <ParamField body="rateLimit.requestsPerHour" type="number">
      Maximum requests per hour (default: 1000)
    </ParamField>

    <ParamField body="rateLimit.requestsPerDay" type="number">
      Maximum requests per day (default: 10000)
    </ParamField>

    <ParamField body="rateLimit.burstLimit" type="number">
      Burst limit for short-term spikes (default: 100)
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="expiry" type="string">
  ISO 8601 timestamp when the API key expires (optional)
</ParamField>

<ParamField body="webhooks" type="array">
  Webhook configurations

  <Expandable title="webhook properties">
    <ParamField body="webhooks[].url" type="string">
      Webhook endpoint URL
    </ParamField>

    <ParamField body="webhooks[].events" type="array">
      Events to subscribe to
    </ParamField>

    <ParamField body="webhooks[].secret" type="string">
      Webhook secret for verification
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="metadata" type="object">
  Additional metadata for the API key
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Indicates if the API key was created successfully
</ResponseField>

<ResponseField name="apiKey" type="string">
  The generated API key (only shown once)

  <Warning>
    Store this API key securely. It will not be shown again and cannot be recovered if lost.
  </Warning>
</ResponseField>

<ResponseField name="keyId" type="string">
  Unique identifier for the API key
</ResponseField>

<ResponseField name="key" type="object">
  API key details

  <Expandable title="key properties">
    <ResponseField name="id" type="string">
      API key identifier
    </ResponseField>

    <ResponseField name="name" type="string">
      API key name
    </ResponseField>

    <ResponseField name="description" type="string">
      API key description
    </ResponseField>

    <ResponseField name="permissions" type="array">
      API key permissions
    </ResponseField>

    <ResponseField name="rateLimit" type="object">
      Rate limiting configuration
    </ResponseField>

    <ResponseField name="status" type="string">
      API key status (active, inactive, expired, revoked)
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO 8601 timestamp of creation
    </ResponseField>

    <ResponseField name="expiry" type="string">
      ISO 8601 timestamp of expiry (if set)
    </ResponseField>

    <ResponseField name="lastUsed" type="string">
      ISO 8601 timestamp of last use (null if never used)
    </ResponseField>

    <ResponseField name="usage" type="object">
      Usage statistics

      <Expandable title="usage properties">
        <ResponseField name="totalRequests" type="number">
          Total requests made
        </ResponseField>

        <ResponseField name="requestsToday" type="number">
          Requests made today
        </ResponseField>

        <ResponseField name="requestsThisMonth" type="number">
          Requests made this month
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="webhooks" type="array">
  Configured webhooks
</ResponseField>

<ResponseField name="timestamp" type="string">
  ISO 8601 timestamp of the response
</ResponseField>

## Examples

<CodeGroup>
  ```bash cURL (Basic API Key) theme={null}
  curl -X POST "https://api.onzks.com/v1/developer/keys" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Production App",
      "description": "API key for production application",
      "permissions": [
        {
          "resource": "scores",
          "actions": ["read"]
        },
        {
          "resource": "identity",
          "actions": ["read"]
        }
      ],
      "rateLimit": {
        "requestsPerMinute": 100,
        "requestsPerHour": 1000,
        "requestsPerDay": 10000
      }
    }'
  ```

  ```bash cURL (Full Permissions) theme={null}
  curl -X POST "https://api.onzks.com/v1/developer/keys" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Admin Dashboard",
      "description": "Full access API key for admin dashboard",
      "permissions": [
        {
          "resource": "all",
          "actions": ["all"]
        }
      ],
      "rateLimit": {
        "requestsPerMinute": 500,
        "requestsPerHour": 5000,
        "requestsPerDay": 50000
      },
      "expiry": "2025-01-20T15:45:00Z",
      "webhooks": [
        {
          "url": "https://myapp.com/webhooks/zkscore",
          "events": ["score.updated", "achievement.earned"],
          "secret": "webhook_secret_123"
        }
      ]
    }'
  ```

  ```bash cURL (Restricted Access) theme={null}
  curl -X POST "https://api.onzks.com/v1/developer/keys" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Limited Access Key",
      "description": "API key with restricted access",
      "permissions": [
        {
          "resource": "scores",
          "actions": ["read"],
          "restrictions": {
            "identities": ["alice.zks", "bob.zks"],
            "chains": [1, 137]
          }
        }
      ],
      "rateLimit": {
        "requestsPerMinute": 10,
        "requestsPerHour": 100,
        "requestsPerDay": 1000
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  async function createApiKey(keyData) {
    const {
      name,
      description,
      permissions,
      rateLimit = {
        requestsPerMinute: 60,
        requestsPerHour: 1000,
        requestsPerDay: 10000
      },
      expiry,
      webhooks = [],
      metadata = {}
    } = keyData;

    const requestBody = {
      name,
      description,
      permissions,
      rateLimit,
      webhooks,
      metadata
    };

    if (expiry) {
      requestBody.expiry = expiry;
    }

    const response = await fetch('https://api.onzks.com/v1/developer/keys', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(requestBody)
    });

    const result = await response.json();

    if (result.success) {
      console.log(`✅ API Key created: ${result.keyId}`);
      console.log(`API Key: ${result.apiKey}`);
      console.log(`Status: ${result.key.status}`);
      console.log(`Rate Limit: ${result.key.rateLimit.requestsPerMinute} req/min`);
      
      // Store the API key securely
      await storeApiKeySecurely(result.apiKey, result.keyId);
    } else {
      console.error('Failed to create API key:', result.message);
    }

    return result;
  }

  // Usage examples
  await createApiKey({
    name: 'Production App',
    description: 'API key for production application',
    permissions: [
      {
        resource: 'scores',
        actions: ['read']
      },
      {
        resource: 'identity',
        actions: ['read']
      }
    ],
    rateLimit: {
      requestsPerMinute: 100,
      requestsPerHour: 1000,
      requestsPerDay: 10000
    }
  });

  // Full permissions example
  await createApiKey({
    name: 'Admin Dashboard',
    description: 'Full access API key for admin dashboard',
    permissions: [
      {
        resource: 'all',
        actions: ['all']
      }
    ],
    rateLimit: {
      requestsPerMinute: 500,
      requestsPerHour: 5000,
      requestsPerDay: 50000
    },
    expiry: '2025-01-20T15:45:00Z',
    webhooks: [
      {
        url: 'https://myapp.com/webhooks/zkscore',
        events: ['score.updated', 'achievement.earned'],
        secret: 'webhook_secret_123'
      }
    ]
  });
  ```

  ```python Python theme={null}
  import requests
  import json
  from datetime import datetime, timedelta

  def create_api_key(name, description=None, permissions=None, rate_limit=None, 
                    expiry=None, webhooks=None, metadata=None):
      if permissions is None:
          permissions = []
      if rate_limit is None:
          rate_limit = {
              'requestsPerMinute': 60,
              'requestsPerHour': 1000,
              'requestsPerDay': 10000
          }
      if webhooks is None:
          webhooks = []
      if metadata is None:
          metadata = {}
      
      request_body = {
          'name': name,
          'description': description,
          'permissions': permissions,
          'rateLimit': rate_limit,
          'webhooks': webhooks,
          'metadata': metadata
      }
      
      if expiry:
          request_body['expiry'] = expiry
      
      response = requests.post(
          'https://api.onzks.com/v1/developer/keys',
          headers={
              'Authorization': 'Bearer YOUR_API_KEY',
              'Content-Type': 'application/json'
          },
          json=request_body
      )
      
      result = response.json()
      
      if result['success']:
          print(f"✅ API Key created: {result['keyId']}")
          print(f"API Key: {result['apiKey']}")
          print(f"Status: {result['key']['status']}")
          print(f"Rate Limit: {result['key']['rateLimit']['requestsPerMinute']} req/min")
          
          # Store the API key securely
          store_api_key_securely(result['apiKey'], result['keyId'])
      else:
          print(f"Failed to create API key: {result['message']}")
      
      return result

  # Usage examples
  create_api_key(
      name='Production App',
      description='API key for production application',
      permissions=[
          {
              'resource': 'scores',
              'actions': ['read']
          },
          {
              'resource': 'identity',
              'actions': ['read']
          }
      ],
      rate_limit={
          'requestsPerMinute': 100,
          'requestsPerHour': 1000,
          'requestsPerDay': 10000
      }
  )

  # Full permissions example
  create_api_key(
      name='Admin Dashboard',
      description='Full access API key for admin dashboard',
      permissions=[
          {
              'resource': 'all',
              'actions': ['all']
          }
      ],
      rate_limit={
          'requestsPerMinute': 500,
          'requestsPerHour': 5000,
          'requestsPerDay': 50000
      },
      expiry='2025-01-20T15:45:00Z',
      webhooks=[
          {
              'url': 'https://myapp.com/webhooks/zkscore',
              'events': ['score.updated', 'achievement.earned'],
              'secret': 'webhook_secret_123'
          }
      ]
  )
  ```
</CodeGroup>

## Response Example

```json theme={null}
{
  "success": true,
  "apiKey": "zk_live_1234567890abcdef1234567890abcdef12345678",
  "keyId": "key_1234567890abcdef",
  "key": {
    "id": "key_1234567890abcdef",
    "name": "Production App",
    "description": "API key for production application",
    "permissions": [
      {
        "resource": "scores",
        "actions": ["read"],
        "restrictions": {}
      },
      {
        "resource": "identity",
        "actions": ["read"],
        "restrictions": {}
      }
    ],
    "rateLimit": {
      "requestsPerMinute": 100,
      "requestsPerHour": 1000,
      "requestsPerDay": 10000,
      "burstLimit": 150
    },
    "status": "active",
    "createdAt": "2024-01-20T15:45:00Z",
    "expiry": null,
    "lastUsed": null,
    "usage": {
      "totalRequests": 0,
      "requestsToday": 0,
      "requestsThisMonth": 0
    }
  },
  "webhooks": [],
  "timestamp": "2024-01-20T15:45:00Z"
}
```

## Use Cases

### 1. Application API Keys

Create API keys for different applications:

```javascript theme={null}
async function createApplicationKeys() {
  const applications = [
    {
      name: 'Web Dashboard',
      description: 'API key for web dashboard',
      permissions: [
        { resource: 'scores', actions: ['read'] },
        { resource: 'identity', actions: ['read'] },
        { resource: 'achievements', actions: ['read'] }
      ],
      rateLimit: {
        requestsPerMinute: 200,
        requestsPerHour: 2000,
        requestsPerDay: 20000
      }
    },
    {
      name: 'Mobile App',
      description: 'API key for mobile application',
      permissions: [
        { resource: 'scores', actions: ['read'] },
        { resource: 'identity', actions: ['read'] }
      ],
      rateLimit: {
        requestsPerMinute: 100,
        requestsPerHour: 1000,
        requestsPerDay: 10000
      }
    },
    {
      name: 'Backend Service',
      description: 'API key for backend service',
      permissions: [
        { resource: 'all', actions: ['all'] }
      ],
      rateLimit: {
        requestsPerMinute: 500,
        requestsPerHour: 5000,
        requestsPerDay: 50000
      }
    }
  ];

  const results = [];
  
  for (const app of applications) {
    try {
      const result = await createApiKey(app);
      results.push({ app: app.name, success: true, keyId: result.keyId });
    } catch (error) {
      results.push({ app: app.name, success: false, error: error.message });
    }
  }
  
  return results;
}
```

### 2. Environment-Specific Keys

Create keys for different environments:

```javascript theme={null}
async function createEnvironmentKeys() {
  const environments = {
    development: {
      name: 'Development Environment',
      description: 'API key for development testing',
      permissions: [
        { resource: 'all', actions: ['all'] }
      ],
      rateLimit: {
        requestsPerMinute: 50,
        requestsPerHour: 500,
        requestsPerDay: 5000
      },
      expiry: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString() // 30 days
    },
    staging: {
      name: 'Staging Environment',
      description: 'API key for staging environment',
      permissions: [
        { resource: 'all', actions: ['all'] }
      ],
      rateLimit: {
        requestsPerMinute: 100,
        requestsPerHour: 1000,
        requestsPerDay: 10000
      },
      expiry: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toISOString() // 90 days
    },
    production: {
      name: 'Production Environment',
      description: 'API key for production environment',
      permissions: [
        { resource: 'all', actions: ['all'] }
      ],
      rateLimit: {
        requestsPerMinute: 1000,
        requestsPerHour: 10000,
        requestsPerDay: 100000
      }
    }
  };

  const results = {};
  
  for (const [env, config] of Object.entries(environments)) {
    try {
      const result = await createApiKey(config);
      results[env] = { success: true, keyId: result.keyId };
    } catch (error) {
      results[env] = { success: false, error: error.message };
    }
  }
  
  return results;
}
```

### 3. Restricted Access Keys

Create keys with specific restrictions:

```javascript theme={null}
async function createRestrictedKeys() {
  const restrictedKeys = [
    {
      name: 'Read-Only Analytics',
      description: 'Read-only access for analytics',
      permissions: [
        {
          resource: 'scores',
          actions: ['read'],
          restrictions: {
            chains: [1, 137] // Ethereum and Polygon only
          }
        }
      ],
      rateLimit: {
        requestsPerMinute: 50,
        requestsPerHour: 500,
        requestsPerDay: 5000
      }
    },
    {
      name: 'Specific User Access',
      description: 'Access limited to specific users',
      permissions: [
        {
          resource: 'scores',
          actions: ['read'],
          restrictions: {
            identities: ['alice.zks', 'bob.zks', 'charlie.zks']
          }
        }
      ],
      rateLimit: {
        requestsPerMinute: 20,
        requestsPerHour: 200,
        requestsPerDay: 2000
      }
    },
    {
      name: 'IP-Whitelisted Access',
      description: 'Access limited to specific IP addresses',
      permissions: [
        {
          resource: 'all',
          actions: ['all'],
          restrictions: {
            ipWhitelist: ['192.168.1.0/24', '10.0.0.0/8']
          }
        }
      ],
      rateLimit: {
        requestsPerMinute: 200,
        requestsPerHour: 2000,
        requestsPerDay: 20000
      }
    }
  ];

  const results = [];
  
  for (const keyConfig of restrictedKeys) {
    try {
      const result = await createApiKey(keyConfig);
      results.push({ name: keyConfig.name, success: true, keyId: result.keyId });
    } catch (error) {
      results.push({ name: keyConfig.name, success: false, error: error.message });
    }
  }
  
  return results;
}
```

### 4. Webhook Integration

Create keys with webhook configurations:

```javascript theme={null}
async function createWebhookKeys() {
  const webhookConfig = {
    name: 'Webhook Integration',
    description: 'API key with webhook support',
    permissions: [
      { resource: 'all', actions: ['all'] }
    ],
    rateLimit: {
      requestsPerMinute: 100,
      requestsPerHour: 1000,
      requestsPerDay: 10000
    },
    webhooks: [
      {
        url: 'https://myapp.com/webhooks/zkscore/scores',
        events: ['score.updated', 'score.calculated'],
        secret: 'webhook_secret_scores_123'
      },
      {
        url: 'https://myapp.com/webhooks/zkscore/achievements',
        events: ['achievement.earned', 'achievement.claimed'],
        secret: 'webhook_secret_achievements_123'
      },
      {
        url: 'https://myapp.com/webhooks/zkscore/attestations',
        events: ['attestation.created', 'attestation.revoked'],
        secret: 'webhook_secret_attestations_123'
      }
    ]
  };

  return await createApiKey(webhookConfig);
}
```

### 5. Batch Key Creation

Create multiple keys at once:

```javascript theme={null}
async function createBatchKeys(keyConfigs) {
  const results = [];
  
  for (const config of keyConfigs) {
    try {
      const result = await createApiKey(config);
      results.push({ 
        name: config.name, 
        success: true, 
        keyId: result.keyId,
        apiKey: result.apiKey
      });
    } catch (error) {
      results.push({ 
        name: config.name, 
        success: false, 
        error: error.message 
      });
    }
  }
  
  const successful = results.filter(r => r.success);
  const failed = results.filter(r => !r.success);
  
  console.log(`Successfully created ${successful.length} API keys`);
  if (failed.length > 0) {
    console.log(`Failed to create ${failed.length} API keys`);
  }
  
  return results;
}
```

## Best Practices

### 1. Security

Implement secure API key management:

```javascript theme={null}
async function storeApiKeySecurely(apiKey, keyId) {
  // Store in secure environment variables
  process.env.ZKSCORE_API_KEY = apiKey;
  process.env.ZKSCORE_KEY_ID = keyId;
  
  // Or store in secure key management system
  await keyManagementSystem.store({
    keyId,
    apiKey,
    encrypted: true
  });
}

function getApiKey() {
  return process.env.ZKSCORE_API_KEY;
}
```

### 2. Rate Limiting

Handle rate limits appropriately:

```javascript theme={null}
class RateLimiter {
  constructor(limits) {
    this.limits = limits;
    this.requests = [];
  }
  
  async checkLimit() {
    const now = Date.now();
    const oneMinute = 60 * 1000;
    const oneHour = 60 * 60 * 1000;
    const oneDay = 24 * 60 * 60 * 1000;
    
    // Remove old requests
    this.requests = this.requests.filter(time => now - time < oneDay);
    
    // Check limits
    const recentRequests = this.requests.filter(time => now - time < oneMinute);
    const hourlyRequests = this.requests.filter(time => now - time < oneHour);
    const dailyRequests = this.requests.length;
    
    if (recentRequests.length >= this.limits.requestsPerMinute) {
      throw new Error('Rate limit exceeded: requests per minute');
    }
    
    if (hourlyRequests.length >= this.limits.requestsPerHour) {
      throw new Error('Rate limit exceeded: requests per hour');
    }
    
    if (dailyRequests >= this.limits.requestsPerDay) {
      throw new Error('Rate limit exceeded: requests per day');
    }
    
    this.requests.push(now);
  }
}
```

### 3. Key Rotation

Implement key rotation:

```javascript theme={null}
async function rotateApiKey(keyId) {
  // Create new key
  const newKey = await createApiKey({
    name: 'Rotated Key',
    description: 'Key created during rotation',
    permissions: [
      { resource: 'all', actions: ['all'] }
    ]
  });
  
  // Revoke old key
  await revokeApiKey(keyId);
  
  return newKey;
}
```

### 4. Monitoring

Monitor API key usage:

```javascript theme={null}
async function monitorApiKeyUsage(keyId) {
  const usage = await getApiKeyUsage(keyId);
  
  const alerts = [];
  
  if (usage.requestsToday > usage.limits.requestsPerDay * 0.8) {
    alerts.push('Daily limit approaching');
  }
  
  if (usage.requestsThisHour > usage.limits.requestsPerHour * 0.9) {
    alerts.push('Hourly limit approaching');
  }
  
  if (usage.lastUsed && Date.now() - new Date(usage.lastUsed) > 7 * 24 * 60 * 60 * 1000) {
    alerts.push('Key not used in 7 days');
  }
  
  return { usage, alerts };
}
```

## Related Endpoints

* [List API Keys](/api-reference/developer/list-api-keys) - View all API keys
* [Revoke API Key](/api-reference/developer/revoke-api-key) - Revoke an API key
* [Get Usage](/api-reference/developer/get-usage) - View API key usage

## Troubleshooting

### "Invalid permissions"

**Cause**: Invalid permission configuration.

**Solution**:

* Use supported resources: identity, scores, achievements, trading, trust, attestations, all
* Use supported actions: read, write, delete, all
* Check permission structure

### "Rate limit too high"

**Cause**: Requested rate limits exceed your plan limits.

**Solution**:

* Check your plan's rate limits
* Reduce requested limits
* Upgrade your plan if needed

### "Invalid webhook URL"

**Cause**: Webhook URL is invalid or unreachable.

**Solution**:

* Ensure webhook URL is accessible
* Check URL format
* Verify webhook endpoint is working

### "API key already exists"

**Cause**: API key with same name already exists.

**Solution**:

* Use a different name
* Check existing keys
* Use unique identifiers

## Rate Limits

API key creation requests are subject to rate limits:

* **Free tier**: 5 keys per day
* **Starter tier**: 20 keys per day
* **Professional tier**: 100 keys per day
* **Enterprise tier**: Custom limits

Implement key rotation to manage key lifecycle.
