Managing API Keys
Overview
API keys provide programmatic access to the DocMap API. Each key is a 72-character token prefixed with dm_live_ that you pass as a Bearer token in the Authorization header.
Key facts:
- Maximum 10 active keys per account
- Format:
dm_live_followed by 64 random hex characters (72 characters total) - Keys are hashed before storage -- the raw key is only shown once at creation time
- Keys can be scoped with expiration dates or set to never expire
Creating a Key
From the Dashboard
- Navigate to Settings > API Keys in your DocMap dashboard
- Click Create API Key
- Enter a descriptive name (e.g. "Production Server", "CI/CD Pipeline")
- Select an expiration period
- Copy the displayed key immediately -- it will not be shown again
From the API
You can also create keys programmatically by authenticating with an existing API key:
curl -X POST https://api.docmap.io/v1/api-keys \
-H "Authorization: Bearer dm_live_your_existing_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Server",
"expiresIn": "90d"
}'const response = await fetch("https://api.docmap.io/v1/api-keys", {
method: "POST",
headers: {
Authorization: `Bearer ${existingApiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Production Server",
expiresIn: "90d",
}),
});
const { data } = await response.json();
// Store this immediately -- it will never be shown again
console.log("API Key:", data.key);
console.log("Key ID:", data.apiKey.id);import requests
response = requests.post(
"https://api.docmap.io/v1/api-keys",
headers={
"Authorization": f"Bearer {existing_api_key}",
"Content-Type": "application/json",
},
json={
"name": "Production Server",
"expiresIn": "90d",
},
)
data = response.json()["data"]
# Store this immediately -- it will never be shown again
print("API Key:", data["key"])
print("Key ID:", data["apiKey"]["id"])Available expiresIn values:
| Value | Duration |
|---|---|
30d | 30 days |
60d | 60 days |
90d | 90 days |
1y | 1 year |
never | No expiration |
The response includes both the raw key and the key metadata:
{
"data": {
"key": "dm_live_a1b2c3d4e5f6...",
"apiKey": {
"id": "key-abc123",
"userId": "user_789",
"name": "Production Server",
"prefix": "dm_live_a1b2c3d4",
"expiresAt": "2025-10-13T12:00:00.000Z",
"lastUsedAt": null,
"createdAt": "2025-07-15T12:00:00.000Z",
"revoked": false
}
}
}WARNING
The key field in the response is the only time the raw API key is returned. Store it in a secure location (e.g. environment variable, secrets manager) immediately. If you lose it, you will need to create a new key.
Listing Keys
Retrieve all active (non-revoked) API keys for your account:
curl https://api.docmap.io/v1/api-keys \
-H "Authorization: Bearer dm_live_your_api_key"const response = await fetch("https://api.docmap.io/v1/api-keys", {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await response.json();
data.forEach((key) => {
console.log(`${key.name} (${key.prefix}...) - Last used: ${key.lastUsedAt ?? "Never"}`);
});response = requests.get(
"https://api.docmap.io/v1/api-keys",
headers={"Authorization": f"Bearer {api_key}"},
)
for key in response.json()["data"]:
last_used = key["lastUsedAt"] or "Never"
print(f"{key['name']} ({key['prefix']}...) - Last used: {last_used}")The response includes metadata for each key but never the full key value -- only the prefix (first 16 characters) is shown:
{
"data": [
{
"id": "key-abc123",
"userId": "user_789",
"name": "Production Server",
"prefix": "dm_live_a1b2c3d4",
"expiresAt": "2025-10-13T12:00:00.000Z",
"lastUsedAt": "2025-07-15T14:30:00.000Z",
"createdAt": "2025-07-15T12:00:00.000Z",
"revoked": false
}
]
}Rotating Keys
To rotate an API key with zero downtime, follow these steps:
- Create a new key with a descriptive name indicating it is a replacement
- Update your systems (environment variables, secrets manager, CI/CD) to use the new key
- Verify the new key is working correctly by making a test API call
- Revoke the old key once all systems have been updated
// Step 1: Create the new key
const createResponse = await fetch("https://api.docmap.io/v1/api-keys", {
method: "POST",
headers: {
Authorization: `Bearer ${currentApiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Production Server (rotated 2025-07)",
expiresIn: "90d",
}),
});
const { data: newKeyData } = await createResponse.json();
const newKey = newKeyData.key;
// Step 2: Verify the new key works
const testResponse = await fetch("https://api.docmap.io/v1/usage", {
headers: { Authorization: `Bearer ${newKey}` },
});
if (testResponse.ok) {
console.log("New key verified. Update your environment variables now.");
// Step 3: Revoke the old key (after updating systems)
// await fetch(`https://api.docmap.io/v1/api-keys/${oldKeyId}`, {
// method: "DELETE",
// headers: { Authorization: `Bearer ${newKey}` },
// });
}TIP
Keep both keys active during the transition period. Only revoke the old key after you have confirmed all systems are using the new one.
Revoking Keys
Revoke an API key by sending a DELETE request with the key ID. The key stops working immediately.
curl -X DELETE https://api.docmap.io/v1/api-keys/key-abc123 \
-H "Authorization: Bearer dm_live_your_api_key"const response = await fetch("https://api.docmap.io/v1/api-keys/key-abc123", {
method: "DELETE",
headers: { Authorization: `Bearer ${apiKey}` },
});
const result = await response.json();
console.log("Revoked:", result.success); // trueresponse = requests.delete(
"https://api.docmap.io/v1/api-keys/key-abc123",
headers={"Authorization": f"Bearer {api_key}"},
)
print("Revoked:", response.json()["success"]) # TrueWARNING
Revocation is immediate and permanent. Any request using the revoked key will receive a 401 UNAUTHORIZED error. Make sure no active systems depend on the key before revoking it.
Monitoring Usage
Each API key tracks a lastUsedAt timestamp that updates automatically whenever the key is used to authenticate a request. Use the list endpoint to monitor when your keys were last active:
const response = await fetch("https://api.docmap.io/v1/api-keys", {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data: keys } = await response.json();
// Find keys that haven't been used in over 30 days
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
keys.forEach((key) => {
if (!key.lastUsedAt || new Date(key.lastUsedAt) < thirtyDaysAgo) {
console.log(`Key "${key.name}" (${key.prefix}...) is inactive — consider revoking it`);
}
});Best Practices
Use descriptive names. Name keys after their purpose or environment: "Production API", "Staging", "GitHub Actions CI". This makes it easy to identify which key to revoke if one is compromised.
Set expiration dates. Prefer
90dor1yovernever. Expiring keys force regular rotation, which limits the window of exposure if a key is leaked.Separate environments. Use different keys for development, staging, and production. Never share a key across environments.
Rotate regularly. Even with expiration dates, rotate keys proactively -- especially after team members leave or infrastructure changes.
Never log raw keys. Avoid printing API keys in application logs, error reports, or console output. Use the
prefixfield when you need to reference a key in logs.Use environment variables. Store keys in environment variables or a secrets manager. Never hardcode them in source code or commit them to version control.
