DEV Community

Alex Spinov
Alex Spinov

Posted on

Unkey Has a Free API — API Key Management and Rate Limiting in Minutes

TL;DR

Unkey is an open-source API key management platform. Create, verify, and rate-limit API keys with sub-millisecond latency — no database setup needed. Free tier: 2,500 key verifications/month.

What Is Unkey?

Unkey provides API authentication infrastructure:

  • API key management — create, revoke, rotate keys
  • Rate limiting — per-key or global rate limits
  • Usage tracking — track API usage per key
  • Temporary keys — auto-expiring keys
  • Remaining uses — keys with limited usage count
  • Sub-millisecond verification — globally distributed
  • Free tier — 2,500 verifications/month

Quick Start

npm install @unkey/api
Enter fullscreen mode Exit fullscreen mode

Create an API Key

import { Unkey } from "@unkey/api";

const unkey = new Unkey({ rootKey: "unkey_YOUR_ROOT_KEY" });

// Create a key for a user
const { result } = await unkey.keys.create({
  apiId: "api_YOUR_API_ID",
  prefix: "myapp",
  ownerId: "user_123",
  meta: { plan: "pro", email: "user@example.com" },
  ratelimit: {
    type: "fast",
    limit: 100,
    refillRate: 10,
    refillInterval: 1000, // 10 requests per second
  },
  remaining: 10000, // 10K total uses
  expires: Date.now() + 30 * 24 * 60 * 60 * 1000, // 30 days
});

console.log(`Key: ${result.key}`); // myapp_abc123...
Enter fullscreen mode Exit fullscreen mode

Verify a Key

// In your API middleware
const { result } = await unkey.keys.verify({
  apiId: "api_YOUR_API_ID",
  key: req.headers["x-api-key"],
});

if (!result.valid) {
  return new Response("Unauthorized", { status: 401 });
}

// Access key metadata
console.log(result.ownerId);  // "user_123"
console.log(result.meta);     // { plan: "pro", ... }
console.log(result.remaining); // 9999
console.log(result.ratelimit); // { remaining: 95, reset: ... }
Enter fullscreen mode Exit fullscreen mode

Express Middleware

import { verifyKey } from "@unkey/api";

const authMiddleware = async (req, res, next) => {
  const key = req.headers["x-api-key"];
  if (!key) return res.status(401).json({ error: "API key required" });

  const { result, error } = await verifyKey({
    key,
    apiId: "api_YOUR_API_ID",
  });

  if (error || !result.valid) {
    return res.status(401).json({
      error: result?.code || "Invalid API key",
    });
  }

  req.apiKey = result;
  next();
};

app.get("/api/data", authMiddleware, (req, res) => {
  res.json({ data: "secret stuff", plan: req.apiKey.meta.plan });
});
Enter fullscreen mode Exit fullscreen mode

Rate Limiting (Standalone)

import { Ratelimit } from "@unkey/ratelimit";

const limiter = new Ratelimit({
  rootKey: "unkey_YOUR_ROOT_KEY",
  namespace: "api",
  limit: 100,
  duration: "60s",
});

// In your handler
const { success, remaining, reset } = await limiter.limit(userId);

if (!success) {
  return new Response("Rate limited", {
    status: 429,
    headers: {
      "X-RateLimit-Remaining": remaining.toString(),
      "X-RateLimit-Reset": reset.toString(),
    },
  });
}
Enter fullscreen mode Exit fullscreen mode

Unkey vs Alternatives

Feature Unkey Custom (Redis) Clerk Auth0
API keys Yes Manual No Yes
Rate limiting Built-in Manual No Add-on
Setup time 5 min Hours 30 min 30 min
Latency <1ms ~5ms N/A N/A
Key analytics Yes Manual N/A Basic
Free tier 2.5K/mo Self-host 10K MAU 7.5K MAU
Open source Yes N/A No No

Resources


Building an API that serves scraped data? My Apify tools extract web data — protect your data API with Unkey for key management and rate limiting. Questions? Email spinov001@gmail.com

Top comments (1)

Collapse
 
perkinsjr profile image
James Perkins

the free tier is 150k requests per month before needing to upgrade to the next tier.

Thanks for the coverage