Skip to main content
POST
https://api-mainnet.onzks.com
/
v1
/
developer
/
keys
Create API Key
curl --request POST \
  --url https://api-mainnet.onzks.com/v1/developer/keys \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "name": "<string>",
  "description": "<string>",
  "permissions": [
    {
      "permissions[].resource": "<string>",
      "permissions[].actions": [
        {}
      ],
      "permissions[].restrictions": {
        "permissions[].restrictions.identities": [
          {}
        ],
        "permissions[].restrictions.chains": [
          {}
        ],
        "permissions[].restrictions.ipWhitelist": [
          {}
        ]
      }
    }
  ],
  "rateLimit": {
    "rateLimit.requestsPerMinute": 123,
    "rateLimit.requestsPerHour": 123,
    "rateLimit.requestsPerDay": 123,
    "rateLimit.burstLimit": 123
  },
  "expiry": "<string>",
  "webhooks": [
    {
      "webhooks[].url": "<string>",
      "webhooks[].events": [
        {}
      ],
      "webhooks[].secret": "<string>"
    }
  ],
  "metadata": {}
}
'
{
  "success": true,
  "apiKey": "<string>",
  "keyId": "<string>",
  "key": {
    "id": "<string>",
    "name": "<string>",
    "description": "<string>",
    "permissions": [
      {}
    ],
    "rateLimit": {},
    "status": "<string>",
    "createdAt": "<string>",
    "expiry": "<string>",
    "lastUsed": "<string>",
    "usage": {
      "totalRequests": 123,
      "requestsToday": 123,
      "requestsThisMonth": 123
    }
  },
  "webhooks": [
    {}
  ],
  "timestamp": "<string>"
}

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

Parameters

name
string
required
Human-readable name for the API key
Choose a descriptive name that helps identify the key’s purpose (e.g., “Production App”, “Development Testing”)
description
string
Optional description of the API key’s intended use
permissions
array
required
Array of permissions for the API key
rateLimit
object
Rate limiting configuration
expiry
string
ISO 8601 timestamp when the API key expires (optional)
webhooks
array
Webhook configurations
metadata
object
Additional metadata for the API key

Response

success
boolean
Indicates if the API key was created successfully
apiKey
string
The generated API key (only shown once)
Store this API key securely. It will not be shown again and cannot be recovered if lost.
keyId
string
Unique identifier for the API key
key
object
API key details
webhooks
array
Configured webhooks
timestamp
string
ISO 8601 timestamp of the response

Examples

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
    }
  }'

Response Example

{
  "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:
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:
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:
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:
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:
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:
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:
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:
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:
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 };
}

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.