Skip to main content
API keys are used to authenticate API requests. They are different from session cookies used in the dashboard.
  • Self-hosted: Keys use prefix spk_selfhosted_
  • Cloud: Keys use prefix spk_live_

List API keys

This endpoint requires cookie authentication (dashboard login). It cannot be called with an API key.
curl -X GET https://analytics.example.com/api/auth/keys \
  -H "Cookie: spk_session=your-session-token"

Query Parameters

limit
integer
default:"20"
Number of keys to return (1-100)
offset
integer
default:"0"
Number of keys to skip (for pagination)

Response (200 OK)

data
array
Array of API key objects
pagination
object

Response Example

{
  "data": [
    {
      "id": "key_a1b2c3d4e5",
      "name": "Production API",
      "key_prefix": "spk_selfhosted_abc12",
      "created_at": "2026-03-01T10:00:00Z",
      "last_used_at": "2026-03-03T14:30:00Z",
      "revoked_at": null
    },
    {
      "id": "key_x9y8z7w6v5",
      "name": "Legacy Key",
      "key_prefix": "spk_selfhosted_xyz98",
      "created_at": "2026-02-15T08:00:00Z",
      "last_used_at": "2026-02-20T12:00:00Z",
      "revoked_at": "2026-03-01T09:00:00Z"
    }
  ],
  "pagination": {
    "total": 2,
    "limit": 20,
    "offset": 0,
    "has_more": false
  }
}

Create an API key

  • This endpoint requires cookie authentication (dashboard login)
  • The full API key is returned only once in the response
  • Store it securely — you cannot retrieve it again
curl -X POST https://analytics.example.com/api/auth/keys \
  -H "Cookie: spk_session=your-session-token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production API"
  }'

Request Body

name
string
required
Display name for the key (must not be empty)Best practices:
  • Use descriptive names (e.g., “Production API”, “CI/CD Pipeline”)
  • Include environment or service name
  • Avoid generic names like “Key 1”

Response (201 Created)

data
object

Response Example

{
  "data": {
    "id": "key_a1b2c3d4e5",
    "name": "Production API",
    "key": "spk_selfhosted_abc123def456789012345678901234",
    "prefix": "spk_selfhosted_abc12",
    "created_at": "2026-03-01T10:00:00Z"
  }
}
Copy the key value immediately! You cannot retrieve it after this response.

Error Responses

400 Bad Request
{
  "error": {
    "code": "bad_request",
    "message": "name is required"
  }
}

Delete (revoke) an API key

  • This endpoint requires cookie authentication (dashboard login)
  • Revoked keys cannot be restored
  • Any requests using this key will immediately fail with 401 Unauthorized
curl -X DELETE https://analytics.example.com/api/auth/keys/key_a1b2c3d4e5 \
  -H "Cookie: spk_session=your-session-token"

Path Parameters

id
string
required
API key ID (format: key_*)

Response (204 No Content)

Empty response body on successful revocation.

Error Responses

404 Not Found
{
  "error": {
    "code": "not_found",
    "message": "API key not found"
  }
}

Using API keys

Authentication Header

Include the API key in the Authorization header with the Bearer scheme:
curl -X GET https://analytics.example.com/api/websites \
  -H "Authorization: Bearer spk_selfhosted_abc123def456789012345678901234"

Security Best Practices

  • Never commit keys to version control (add to .gitignore, .env.example should use placeholders)
  • Use environment variables or secret management tools (e.g., AWS Secrets Manager, HashiCorp Vault)
  • Rotate keys periodically
  • Create separate keys for different environments (dev, staging, production)
  • Revoke unused keys immediately
  • Check last_used_at timestamps regularly
  • Revoke keys with suspicious activity or long inactivity
If a key is exposed (e.g., committed to a public repo):
  1. Revoke the key immediately via the dashboard or DELETE endpoint
  2. Create a new key
  3. Update your application with the new key
  4. Rotate any other potentially exposed secrets

Key Format

Self-Hosted Mode

spk_selfhosted_<32 hex chars>
Example: spk_selfhosted_abc123def456789012345678901234
  • Total length: 47 characters
  • Prefix stored: First 20 chars (spk_selfhosted_abc12)
  • Hash stored: SHA-256 of full key (64 hex chars)

Cloud Mode

spk_live_<32 hex chars>
Example: spk_live_xyz789abc123def456789012345678
  • Total length: 41 characters
  • Prefix stored: First 20 chars (spk_live_xyz789abc123)
  • Hash stored: SHA-256 of full key (64 hex chars)

Authentication Flow

When you make an API request with an API key:
  1. Header parsing: Sparklytics extracts the key from Authorization: Bearer <key>
  2. Hashing: The key is hashed using SHA-256
  3. Database lookup: The hash is looked up in the local_api_keys table (self-hosted) or api_keys table (cloud)
  4. Validation: The key must:
    • Exist in the database
    • Not be revoked (revoked_at must be null)
  5. Last-used tracking: On successful authentication, last_used_at is updated asynchronously (fire-and-forget)

Error Responses

401 Unauthorized
Returned when:
  • No Authorization header provided
  • Key is invalid (not found in database)
  • Key has been revoked
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing authentication credentials"
  }
}

FAQ

No. The dashboard requires cookie-based session authentication. API keys are only for programmatic API access (e.g., creating websites, fetching analytics via custom scripts).
The key is marked as revoked (revoked_at timestamp is set). All future requests using that key will immediately fail with 401 Unauthorized. The key cannot be restored — you must create a new one.
No. The full key is returned only once in the creation response. Only the SHA-256 hash is stored in the database. If you lose the key, you must revoke it and create a new one.
There is no hard limit, but best practice is to create one key per service/environment and revoke unused keys.
  • spk_selfhosted_* keys are generated in self-hosted mode (single-tenant, DuckDB)
  • spk_live_* keys are generated in cloud mode (multi-tenant, PostgreSQL + ClickHouse)
The prefix ensures keys cannot be accidentally used across environments.

Build docs developers (and LLMs) love