Skip to main content
This guide provides SQL query examples for common analytics scenarios covering all the use cases from the legacy API and more. All examples use ClickHouse SQL syntax and work with the /v2/analytics.getVerifications endpoint.

Using Queries in API Requests

When making API requests, you need to format the SQL query as a JSON string on a single line. Here’s how: Readable format (for documentation):
SELECT COUNT(*) as total
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 7 DAY
JSON format (for API requests):
{
  "query": "SELECT COUNT(*) as total FROM key_verifications_v1 WHERE time >= now() - INTERVAL 7 DAY"
}
Each example below shows both the readable multi-line SQL and the single-line JSON format you can copy directly into your API requests.

Usage Analytics

SELECT COUNT(*) as total_verifications
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 7 DAY
JSON format:
{
  "query": "SELECT COUNT(*) as total_verifications FROM key_verifications_v1 WHERE time >= now() - INTERVAL 7 DAY"
}
SELECT
  outcome,
  COUNT(*) as count
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 30 DAY
GROUP BY outcome
ORDER BY count DESC
JSON format:
{
  "query": "SELECT outcome, COUNT(*) as count FROM key_verifications_v1 WHERE time >= now() - INTERVAL 30 DAY GROUP BY outcome ORDER BY count DESC"
}
SELECT
  time as date,
  SUM(count) as verifications
FROM key_verifications_per_day_v1
WHERE time >= now() - INTERVAL 30 DAY
GROUP BY date
ORDER BY date
JSON format:
{
  "query": "SELECT time as date, SUM(count) as verifications FROM key_verifications_per_day_v1 WHERE time >= now() - INTERVAL 30 DAY GROUP BY date ORDER BY date"
}
SELECT
  time as hour,
  outcome,
  SUM(count) as verifications
FROM key_verifications_per_hour_v1
WHERE time >= toStartOfDay(now())
GROUP BY time, outcome
ORDER BY time, outcome
JSON format:
{
  "query": "SELECT time as hour, outcome, SUM(count) as verifications FROM key_verifications_per_hour_v1 WHERE time >= toStartOfDay(now()) GROUP BY time, outcome ORDER BY time, outcome"
}

Usage by User

SELECT
  external_id,
  COUNT(*) as total_verifications,
  countIf(outcome = 'VALID') as successful,
  countIf(outcome = 'RATE_LIMITED') as rate_limited
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 30 DAY
  AND external_id != ''
  GROUP BY external_id
ORDER BY total_verifications DESC
LIMIT 100
JSON format:
{
  "query": "SELECT external_id, COUNT(*) as total_verifications, countIf(outcome = 'VALID') as successful, countIf(outcome = 'RATE_LIMITED') as rate_limited FROM key_verifications_v1 WHERE time >= now() - INTERVAL 30 DAY AND external_id != '' GROUP BY external_id ORDER BY total_verifications DESC LIMIT 100"
}
SELECT
  COUNT(*) as total_verifications,
  countIf(outcome = 'VALID') as successful,
  countIf(outcome = 'RATE_LIMITED') as rate_limited
FROM key_verifications_v1
WHERE external_id = 'user_123'
  AND time >= now() - INTERVAL 30 DAY
JSON format:
{
  "query": "SELECT COUNT(*) as total_verifications, countIf(outcome = 'VALID') as successful, countIf(outcome = 'RATE_LIMITED') as rate_limited FROM key_verifications_v1 WHERE external_id = 'user_123' AND time >= now() - INTERVAL 30 DAY"
}
SELECT
  external_id,
  COUNT(*) as total_verifications
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 30 DAY
  AND external_id != ''
  GROUP BY external_id
ORDER BY total_verifications DESC
LIMIT 10
JSON format:
{
  "query": "SELECT external_id, COUNT(*) as total_verifications FROM key_verifications_v1 WHERE time >= now() - INTERVAL 30 DAY AND external_id != '' GROUP BY external_id ORDER BY total_verifications DESC LIMIT 10"
}
SELECT
  external_id,
  toDate(time) as date,
  COUNT(*) as verifications
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 30 DAY
GROUP BY external_id, date
ORDER BY external_id, date
JSON format:
{
  "query": "SELECT external_id, toDate(time) as date, COUNT(*) as verifications FROM key_verifications_v1 WHERE time >= now() - INTERVAL 30 DAY GROUP BY external_id, date ORDER BY external_id, date"
}

API Analytics

SELECT
  key_space_id,
  COUNT(*) as total_verifications,
  countIf(outcome = 'VALID') as successful
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 30 DAY
GROUP BY key_space_id
ORDER BY total_verifications DESC
JSON format:
{
  "query": "SELECT key_space_id, COUNT(*) as total_verifications, countIf(outcome = 'VALID') as successful FROM key_verifications_v1 WHERE time >= now() - INTERVAL 30 DAY GROUP BY key_space_id ORDER BY total_verifications DESC"
}
SELECT
  COUNT(*) as total_verifications,
  countIf(outcome = 'VALID') as successful,
  countIf(outcome = 'RATE_LIMITED') as rate_limited,
  countIf(outcome = 'INVALID') as invalid
FROM key_verifications_v1
WHERE key_space_id = 'ks_1234'
  AND time >= now() - INTERVAL 30 DAY
JSON format:
{
  "query": "SELECT COUNT(*) as total_verifications, countIf(outcome = 'VALID') as successful, countIf(outcome = 'RATE_LIMITED') as rate_limited, countIf(outcome = 'INVALID') as invalid FROM key_verifications_v1 WHERE key_space_id = 'ks_1234' AND time >= now() - INTERVAL 30 DAY"
}
SELECT
  key_space_id,
  COUNT(*) as verifications,
  round(countIf(outcome = 'VALID') / COUNT(*) * 100, 2) as success_rate
FROM key_verifications_v1
WHERE key_space_id IN ('ks_1234', 'ks_5678')
  AND time >= now() - INTERVAL 7 DAY
GROUP BY key_space_id
JSON format:
{
  "query": "SELECT key_space_id, COUNT(*) as verifications, round(countIf(outcome = 'VALID') / COUNT(*) * 100, 2) as success_rate FROM key_verifications_v1 WHERE key_space_id IN ('ks_1234', 'ks_5678') AND time >= now() - INTERVAL 7 DAY GROUP BY key_space_id"
}

Key Analytics

SELECT
  key_id,
  COUNT(*) as total_verifications,
  countIf(outcome = 'VALID') as successful
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 30 DAY
GROUP BY key_id
ORDER BY total_verifications DESC
LIMIT 100
JSON format:
{
  "query": "SELECT key_id, COUNT(*) as total_verifications, countIf(outcome = 'VALID') as successful FROM key_verifications_v1 WHERE time >= now() - INTERVAL 30 DAY GROUP BY key_id ORDER BY total_verifications DESC LIMIT 100"
}
SELECT
  COUNT(*) as total_verifications,
  countIf(outcome = 'VALID') as successful,
  countIf(outcome = 'RATE_LIMITED') as rate_limited
FROM key_verifications_v1
WHERE key_id = 'key_1234'
  AND time >= now() - INTERVAL 30 DAY
JSON format:
{
  "query": "SELECT COUNT(*) as total_verifications, countIf(outcome = 'VALID') as successful, countIf(outcome = 'RATE_LIMITED') as rate_limited FROM key_verifications_v1 WHERE key_id = 'key_1234' AND time >= now() - INTERVAL 30 DAY"
}
SELECT
  key_id,
  COUNT(*) as total_errors,
  groupArray(DISTINCT outcome) as error_types
FROM key_verifications_v1
WHERE outcome != 'VALID'
  AND time >= now() - INTERVAL 7 DAY
GROUP BY key_id
ORDER BY total_errors DESC
LIMIT 20
JSON format:
{
  "query": "SELECT key_id, COUNT(*) as total_errors, groupArray(DISTINCT outcome) as error_types FROM key_verifications_v1 WHERE outcome != 'VALID' AND time >= now() - INTERVAL 7 DAY GROUP BY key_id ORDER BY total_errors DESC LIMIT 20"
}

Tag-Based Analytics

Tags allow you to add custom metadata to verification requests for filtering and aggregation.
SELECT COUNT(*) as total
FROM key_verifications_v1
WHERE has(tags, 'path=/api/v1/users')
  AND time >= now() - INTERVAL 7 DAY
JSON format:
{
  "query": "SELECT COUNT(*) as total FROM key_verifications_v1 WHERE has(tags, 'path=/api/v1/users') AND time >= now() - INTERVAL 7 DAY"
}
SELECT COUNT(*) as total
FROM key_verifications_v1
WHERE hasAny(tags, ['path=/api/v1/users', 'path=/api/v1/posts'])
  AND time >= now() - INTERVAL 7 DAY
JSON format:
{
  "query": "SELECT COUNT(*) as total FROM key_verifications_v1 WHERE hasAny(tags, ['path=/api/v1/users', 'path=/api/v1/posts']) AND time >= now() - INTERVAL 7 DAY"
}
SELECT COUNT(*) as total
FROM key_verifications_v1
WHERE hasAll(tags, ['environment=production', 'team=backend'])
  AND time >= now() - INTERVAL 7 DAY
JSON format:
{
  "query": "SELECT COUNT(*) as total FROM key_verifications_v1 WHERE hasAll(tags, ['environment=production', 'team=backend']) AND time >= now() - INTERVAL 7 DAY"
}
SELECT
  arrayJoin(tags) as tag,
  COUNT(*) as verifications
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 7 DAY
GROUP BY tag
ORDER BY verifications DESC
LIMIT 20
JSON format:
{
  "query": "SELECT arrayJoin(tags) as tag, COUNT(*) as verifications FROM key_verifications_v1 WHERE time >= now() - INTERVAL 7 DAY GROUP BY tag ORDER BY verifications DESC LIMIT 20"
}
SELECT
  arrayJoin(arrayFilter(x -> startsWith(x, 'path='), tags)) as endpoint,
  COUNT(*) as requests
FROM key_verifications_v1
WHERE time >= now() - INTERVAL 24 HOUR
GROUP BY endpoint
ORDER BY requests DESC
JSON format:
{
  "query": "SELECT arrayJoin(arrayFilter(x -> startsWith(x, 'path='), tags)) as endpoint, COUNT(*) as requests FROM key_verifications_v1 WHERE time >= now() - INTERVAL 24 HOUR GROUP BY endpoint ORDER BY requests DESC"
}

Billing & Usage-Based Pricing

SELECT
  external_id,
  toStartOfMonth(time) as month,
  SUM(spent_credits) as total_credits
FROM key_verifications_v1
WHERE external_id != ''
  AND time >= toStartOfMonth(now())
GROUP BY external_id, month
ORDER BY total_credits DESC
JSON format:
{
  "query": "SELECT external_id, toStartOfMonth(time) as month, SUM(spent_credits) as total_credits FROM key_verifications_v1 WHERE external_id != '' AND time >= toStartOfMonth(now()) GROUP BY external_id, month ORDER BY total_credits DESC"
}
SELECT
  external_id,
  SUM(spent_credits) as credits_this_period
FROM key_verifications_v1
WHERE external_id = 'user_123'
  AND time >= 1704067200000  -- Start of billing period (Unix millis)
  AND time < 1706745600000   -- End of billing period (Unix millis)
GROUP BY external_id
JSON format:
{
  "query": "SELECT external_id, SUM(spent_credits) as credits_this_period FROM key_verifications_v1 WHERE external_id = 'user_123' AND time >= 1704067200000 AND time < 1706745600000 GROUP BY external_id"
}
SELECT
  external_id,
  SUM(spent_credits) as total_credits,
  CASE
    WHEN total_credits <= 1000 THEN 'free'
    WHEN total_credits <= 10000 THEN 'starter'
    WHEN total_credits <= 100000 THEN 'pro'
    ELSE 'enterprise'
  END as tier
FROM key_verifications_v1
WHERE time >= toStartOfMonth(now())
  AND external_id = 'user_123'
GROUP BY external_id
JSON format:
{
  "query": "SELECT external_id, SUM(spent_credits) as total_credits, CASE WHEN total_credits <= 1000 THEN 'free' WHEN total_credits <= 10000 THEN 'starter' WHEN total_credits <= 100000 THEN 'pro' ELSE 'enterprise' END as tier FROM key_verifications_v1 WHERE time >= toStartOfMonth(now()) AND external_id = 'user_123' GROUP BY external_id"
}
SELECT
  toDate(time) as date,
  SUM(spent_credits) as credits_used,
  credits_used * 0.001 as estimated_cost  -- $0.001 per credit
FROM key_verifications_v1
WHERE external_id = 'user_123'
  AND time >= now() - INTERVAL 30 DAY
GROUP BY date
ORDER BY date
JSON format:
{
  "query": "SELECT toDate(time) as date, SUM(spent_credits) as credits_used, credits_used * 0.001 as estimated_cost FROM key_verifications_v1 WHERE external_id = 'user_123' AND time >= now() - INTERVAL 30 DAY GROUP BY date ORDER BY date"
}

Advanced Queries

WITH first_seen AS (
  SELECT
    external_id,
    min(time) as first_verification
  FROM key_verifications_v1
  WHERE external_id != ''
  GROUP BY external_id
)
SELECT
  toDate(kv.time) as date,
  countIf(kv.time = fs.first_verification) as new_users,
  countIf(kv.time > fs.first_verification) as returning_users
FROM key_verifications_v1 kv
JOIN first_seen fs ON kv.external_id = fs.external_id
WHERE kv.time >= now() - INTERVAL 30 DAY
GROUP BY date
ORDER BY date
JSON format:
{
  "query": "WITH first_seen AS ( SELECT external_id, min(time) as first_verification FROM key_verifications_v1 WHERE external_id != '' GROUP BY external_id ) SELECT toDate(kv.time) as date, countIf(kv.time = fs.first_verification) as new_users, countIf(kv.time > fs.first_verification) as returning_users FROM key_verifications_v1 kv JOIN first_seen fs ON kv.external_id = fs.external_id WHERE kv.time >= now() - INTERVAL 30 DAY GROUP BY date ORDER BY date"
}
SELECT
  date,
  verifications,
  avg(verifications) OVER (
    ORDER BY date
    ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
  ) as moving_avg_7d
FROM (
  SELECT
    time as date,
    SUM(count) as verifications
  FROM key_verifications_per_day_v1
  WHERE time >= now() - INTERVAL 60 DAY
  GROUP BY date
)
ORDER BY date
JSON format:
{
  "query": "SELECT date, verifications, avg(verifications) OVER ( ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW ) as moving_avg_7d FROM ( SELECT time as date, SUM(count) as verifications FROM key_verifications_per_day_v1 WHERE time >= now() - INTERVAL 60 DAY GROUP BY date ) ORDER BY date"
}

Using Aggregated Tables

For better performance on large time ranges, use pre-aggregated tables:
SELECT
  time,
  SUM(count) as total
FROM key_verifications_per_hour_v1
WHERE time >= toStartOfHour(now() - INTERVAL 7 DAY)
GROUP BY time
ORDER BY time
JSON format:
{
  "query": "SELECT time, SUM(count) as total FROM key_verifications_per_hour_v1 WHERE time >= toStartOfHour(now() - INTERVAL 7 DAY) GROUP BY time ORDER BY time"
}
SELECT
  time,
  SUM(count) as total
FROM key_verifications_per_day_v1
WHERE time >= toStartOfDay(now() - INTERVAL 30 DAY)
GROUP BY time
ORDER BY time
JSON format:
{
  "query": "SELECT time, SUM(count) as total FROM key_verifications_per_day_v1 WHERE time >= toStartOfDay(now() - INTERVAL 30 DAY) GROUP BY time ORDER BY time"
}
SELECT
  time,
  SUM(count) as total
FROM key_verifications_per_month_v1
WHERE time >= toStartOfMonth(now() - INTERVAL 12 MONTH)
GROUP BY time
ORDER BY time
JSON format:
{
  "query": "SELECT time, SUM(count) as total FROM key_verifications_per_month_v1 WHERE time >= toStartOfMonth(now() - INTERVAL 12 MONTH) GROUP BY time ORDER BY time"
}

Tips for Efficient Queries

  1. Always filter by time - Use indexes by including time filters
  2. Use aggregated tables - Hourly/daily/monthly tables for longer ranges
  3. Add LIMIT clauses - Prevent returning too much data
  4. Filter before grouping - Use WHERE instead of HAVING when possible

Next Steps