Delete API Key
Expires (deactivates) an API key, preventing it from being used for future API requests. This is also called "revoking" a key.
Endpointβ
DELETE /api/v1/api-keys/{api_key_id}
Authenticationβ
Requires JWT token (Bearer authentication).
Path Parametersβ
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key_id | UUID | Yes | The ID of the API key to expire |
Responseβ
Success Response (200 OK)β
{
"message": "API key expired successfully",
"success": true
}
Examplesβ
curl -X DELETE https://api.callcov.com/api/v1/api-keys/550e8400-e29b-41d4-a716-446655440000 \-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."What Happens When a Key is Expiredβ
- Marked as inactive:
is_activeset tofalse - API requests fail: Key can no longer authenticate
- Cannot be reactivated: Expiration is permanent
- Retained in history: Key remains in database for audit purposes
- Frees up slot: Allows creating new keys (max 10 active)
Use Casesβ
Revoke Compromised Keyβ
def revoke_compromised_key(access_token, key_id):
"""Immediately revoke a compromised API key"""
url = f"https://api.callcov.com/api/v1/api-keys/{key_id}"
headers = {"Authorization": f"Bearer {access_token}"}
response = requests.delete(url, headers=headers)
if response.status_code == 200:
print("β οΈ Compromised key revoked!")
print("Create a new key and update your applications immediately.")
return True
return False
Key Rotationβ
def rotate_api_key(access_token, old_key_id, description):
"""Rotate an API key: create new, expire old"""
# Create new key
create_url = "https://api.callcov.com/api/v1/api-keys/"
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
new_key_response = requests.post(
create_url,
headers=headers,
json={"description": description}
)
if new_key_response.status_code == 201:
new_key = new_key_response.json()['api_key']
print(f"β
New key created: {new_key}")
print("β οΈ SAVE THIS KEY NOW!")
# Expire old key
delete_url = f"https://api.callcov.com/api/v1/api-keys/{old_key_id}"
requests.delete(delete_url, headers=headers)
print("β
Old key expired")
return new_key
return None
Cleanup Unused Keysβ
def cleanup_unused_keys(access_token):
"""Expire all API keys that have never been used"""
headers = {"Authorization": f"Bearer {access_token}"}
# Get all keys
list_url = "https://api.callcov.com/api/v1/api-keys/"
response = requests.get(list_url, headers=headers)
keys = response.json()['api_keys']
unused_keys = [k for k in keys if k['last_used_at'] is None]
print(f"Found {len(unused_keys)} unused keys")
for key in unused_keys:
# Ask for confirmation
confirm = input(f"Expire {key['key_prefix']} ({key['description']})? (y/n): ")
if confirm.lower() == 'y':
delete_url = f"https://api.callcov.com/api/v1/api-keys/{key['id']}"
requests.delete(delete_url, headers=headers)
print(f" β
Expired {key['key_prefix']}")
else:
print(f" βοΈ Skipped {key['key_prefix']}")
Errorsβ
400 Bad Requestβ
Key is already expired:
{
"detail": "API key is already expired"
}
404 Not Foundβ
API key not found or doesn't belong to you:
{
"detail": "API key not found"
}
401 Unauthorizedβ
Invalid or missing JWT token:
{
"detail": "Could not validate credentials"
}
When to Expire an API Keyβ
β Expire immediately when:β
- Compromised: Key was exposed or leaked
- No longer needed: Integration is decommissioned
- Rotation: Implementing regular key rotation policy
- Security breach: Precautionary measure
- Employee offboarding: Key was used by someone who left
βΈοΈ Consider before expiring:β
- In use: Check
last_used_atto see if actively used - Impact: Will this break any running integrations?
- Replacement: Do you have a new key ready?
- Communication: Have you notified team members?
Best Practicesβ
Regular Key Rotationβ
# Rotate keys every 90 days
from datetime import datetime, timedelta
def should_rotate(key):
created = datetime.fromisoformat(key['created_at'].replace('Z', '+00:00'))
age = datetime.now(timezone.utc) - created
return age.days >= 90 # 90 days old
# Check all keys
keys = get_api_keys(access_token)
for key in keys:
if should_rotate(key):
print(f"β οΈ Key {key['key_prefix']} is {age.days} days old - consider rotating")
Emergency Revocation Processβ
- Identify compromised key (by prefix or description)
- Revoke immediately (don't wait)
- Create new key (if still needed)
- Update applications (deploy new key)
- Verify old key blocked (test that it fails)
- Document incident (for security audit)
Before Expiringβ
# Verify key exists and is active before expiring
def safe_expire_key(access_token, key_id):
"""Safely expire a key with verification"""
headers = {"Authorization": f"Bearer {access_token}"}
# First, verify the key exists
list_url = "https://api.callcov.com/api/v1/api-keys/"
response = requests.get(list_url, headers=headers)
keys = response.json()['api_keys']
key_to_expire = next((k for k in keys if k['id'] == key_id), None)
if not key_to_expire:
print("β Key not found")
return False
if not key_to_expire['is_active']:
print("β οΈ Key is already expired")
return False
print(f"About to expire:")
print(f" Prefix: {key_to_expire['key_prefix']}")
print(f" Description: {key_to_expire['description']}")
print(f" Created: {key_to_expire['created_at']}")
print(f" Last used: {key_to_expire['last_used_at'] or 'Never'}")
confirm = input("Proceed? (yes/no): ")
if confirm.lower() == 'yes':
delete_url = f"https://api.callcov.com/api/v1/api-keys/{key_id}"
response = requests.delete(delete_url, headers=headers)
if response.status_code == 200:
print("β
Key expired successfully")
return True
print("β Expiration cancelled")
return False
Securityβ
- User isolation: You can only expire your own keys
- Permanent action: Cannot be undone
- Immediate effect: Key stops working instantly
- Audit trail: Expired keys remain in history
Difference Between Expire and Deleteβ
This endpoint expires (soft deletes) the key:
- β Key is deactivated
- β Key remains in database
- β
Shows in history with
include_expired=true - β Audit trail preserved
The key is NOT permanently deleted:
- β Key is not removed from database
- β Cannot reuse the same key
Relatedβ
- Create API Key - Generate new API key
- List API Keys - View all your API keys
- Authentication Guide - Using API keys