Skip to content

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

  1. Navigate to Settings > API Keys in your DocMap dashboard
  2. Click Create API Key
  3. Enter a descriptive name (e.g. "Production Server", "CI/CD Pipeline")
  4. Select an expiration period
  5. 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:

bash
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"
  }'
typescript
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);
python
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:

ValueDuration
30d30 days
60d60 days
90d90 days
1y1 year
neverNo expiration

The response includes both the raw key and the key metadata:

json
{
  "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:

bash
curl https://api.docmap.io/v1/api-keys \
  -H "Authorization: Bearer dm_live_your_api_key"
typescript
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"}`);
});
python
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:

json
{
  "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:

  1. Create a new key with a descriptive name indicating it is a replacement
  2. Update your systems (environment variables, secrets manager, CI/CD) to use the new key
  3. Verify the new key is working correctly by making a test API call
  4. Revoke the old key once all systems have been updated
typescript
// 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.

bash
curl -X DELETE https://api.docmap.io/v1/api-keys/key-abc123 \
  -H "Authorization: Bearer dm_live_your_api_key"
typescript
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); // true
python
response = requests.delete(
    "https://api.docmap.io/v1/api-keys/key-abc123",
    headers={"Authorization": f"Bearer {api_key}"},
)

print("Revoked:", response.json()["success"])  # True

WARNING

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:

typescript
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 90d or 1y over never. 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 prefix field 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.

DocMap API Documentation