Skip to main content
GET
/
api
/
v1
/
auth
/
developer-keys
List Developer Keys
curl --request GET \
  --url https://api.devkit4ai.com/api/v1/auth/developer-keys \
  --header 'Authorization: Bearer <token>'
[
  {
    "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "name": "<string>",
    "key_prefix": "<string>",
    "is_active": true,
    "last_used_at": "2023-11-07T05:31:56Z",
    "created_at": "2023-11-07T05:31:56Z"
  }
]
Retrieve all active developer keys for the authenticated developer account. This endpoint returns key metadata including usage timestamps and identification prefixes, but never returns the full key values.

Authentication

Requires valid JWT token with developer role and an active developer key.

Headers

Authorization
string
required
Bearer JWT access token obtained from login
X-User-Role
string
required
Must be set to developer
X-Developer-Key
string
required
Active developer key for authentication (format: ak_ + 32 characters)

Response

Returns an array of developer key objects without the full key values.
[].id
string
Unique identifier (UUID) for the developer key
[].name
string
Descriptive name assigned to the key (e.g., “Production API”, “Staging Environment”)
[].key_prefix
string
First 8 characters of the key for identification (e.g., ak_abc12)
[].is_active
boolean
Key status - only active keys are returned by this endpoint
[].last_used_at
string
ISO 8601 timestamp of the most recent API request using this key. Returns null if the key has never been used.
[].created_at
string
ISO 8601 timestamp when the key was created

Example Request

curl -X GET https://api.vibecoding.ad/api/v1/auth/developer-keys \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "X-User-Role: developer" \
  -H "X-Developer-Key: ak_abc123XYZ-_789def456ghi012jkl345"

Example Response

[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Production API",
    "key_prefix": "ak_abc12",
    "is_active": true,
    "last_used_at": "2025-12-07T09:15:00Z",
    "created_at": "2025-12-01T10:30:00Z"
  },
  {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "name": "Staging Environment",
    "key_prefix": "ak_xyz78",
    "is_active": true,
    "last_used_at": null,
    "created_at": "2025-12-05T14:20:00Z"
  },
  {
    "id": "770e8400-e29b-41d4-a716-446655440002",
    "name": "Development Key",
    "key_prefix": "ak_dev99",
    "is_active": true,
    "last_used_at": "2025-12-08T14:30:00Z",
    "created_at": "2025-11-15T08:00:00Z"
  }
]

Use Cases

Key Management Dashboard

Display all developer keys with usage statistics:
async function fetchDeveloperKeys(
  jwtToken: string,
  developerKey: string
): Promise<DeveloperKey[]> {
  const response = await fetch(
    'https://api.vibecoding.ad/api/v1/auth/developer-keys',
    {
      headers: {
        'Authorization': `Bearer ${jwtToken}`,
        'X-User-Role': 'developer',
        'X-Developer-Key': developerKey
      }
    }
  );
  
  if (!response.ok) {
    throw new Error('Failed to fetch developer keys');
  }
  
  return response.json();
}
(((REPLACE_THIS_WITH_IMAGE: cloud-admin-developer-keys-list.png: Cloud Admin console showing list of developer keys with names, prefixes, last used timestamps, and action buttons)))

Identify Unused Keys

Find keys that haven’t been used recently for rotation:
function getUnusedKeys(keys: DeveloperKey[], daysSinceUse: number = 90) {
  const cutoffDate = new Date();
  cutoffDate.setDate(cutoffDate.getDate() - daysSinceUse);
  
  return keys.filter(key => {
    if (!key.last_used_at) return true; // Never used
    return new Date(key.last_used_at) < cutoffDate;
  });
}

Key Rotation Workflow

Implement automated key rotation:
async function rotateOldKeys(
  jwtToken: string,
  developerKey: string,
  maxAgeDays: number = 90
) {
  // List all keys
  const keys = await fetchDeveloperKeys(jwtToken, developerKey);
  
  // Find keys older than maxAgeDays
  const oldKeys = keys.filter(key => {
    const created = new Date(key.created_at);
    const age = Date.now() - created.getTime();
    return age > maxAgeDays * 24 * 60 * 60 * 1000;
  });
  
  // Create new keys and revoke old ones
  for (const oldKey of oldKeys) {
    console.log(`Key ${oldKey.key_prefix} is ${Math.floor((Date.now() - new Date(oldKey.created_at).getTime()) / (24 * 60 * 60 * 1000))} days old`);
    // Implementation continues with create and revoke...
  }
}

Security Considerations

The last_used_at timestamp is updated asynchronously and may have a delay of up to 1 minute. Use this for monitoring and auditing, not for real-time access control.

Best Practices

  1. Regular Audits: Review keys monthly to identify unused or unnecessary keys
  2. Monitor Usage: Track last_used_at to detect suspicious activity or compromised keys
  3. Name Convention: Use consistent naming (e.g., “Production”, “Staging”, “CI/CD Pipeline”)
  4. Limit Active Keys: Keep only necessary keys active to minimize attack surface

Error Responses

Unauthorized (401)

{
  "detail": "Could not validate credentials"
}
Missing or invalid JWT token.

Forbidden (403)

{
  "detail": "Insufficient permissions"
}
User role is not developer or developer key is invalid.

Authorizations

Authorization
string
header
required

The access token received from the authorization server in the OAuth 2.0 flow.

Response

200 - application/json

Successful Response

id
string<uuid>
required
name
string | null
required
key_prefix
string
required
is_active
boolean
required
last_used_at
string<date-time> | null
required
created_at
string<date-time>
required