Quickstart
Create and validate your first apikee key in under 2 minutes.
Quickstart
Get from zero to a protected API endpoint in under 2 minutes.
Install
pip install apikee
# With FastAPI support
pip install "apikee[fastapi]"
# All extras (FastAPI, Flask, msgpack, encrypted server channel)
pip install "apikee[all]"npm install apikee
# or
pnpm add apikeeNode 18+ required. Zero production dependencies.
<dependency>
<groupId>dev.apikee</groupId>
<artifactId>apikee-spring</artifactId>
<version>0.1.0</version>
</dependency>dotnet add package ApikeeCreate and verify a key
from apikee import Apikee
apikee = Apikee(secrets=["your-signing-secret"])
# Create a signed key with embedded claims
key = apikee.create(
tenant="acme-corp",
scopes=["read", "write"],
expires_in=timedelta(days=90),
meta={"plan": "pro"},
)
# → "apikee_4xKm...Zp9.8aFc...3d"
# Verify locally — zero I/O
claims = apikee.verify(key)
print(claims.tenant) # "acme-corp"
print(claims.scopes) # ["read", "write"]
print(claims.expires_at) # datetime(...)import { Apikee } from 'apikee'
const apikee = new Apikee({ secrets: ['your-signing-secret'] })
const key = await apikee.create('acme-corp', {
scopes: ['read', 'write'],
expiresIn: '90d',
meta: { plan: 'pro' },
})
// → "apikee_4xKm...Zp9.8aFc...3d"
const claims = apikee.verify(key)
console.log(claims.tenant) // "acme-corp"
console.log(claims.scopes) // ["read", "write"]
console.log(claims.expiresAt) // Date objectApikeeKeyEngine engine = new ApikeeKeyEngine(List.of("your-signing-secret"));
String key = engine.create(
KeyOptions.builder()
.tenant("acme-corp")
.scopes(List.of("read", "write"))
.expiresAt(Instant.now().plus(Duration.ofDays(90)))
.meta(Map.of("plan", "pro"))
.build()
);
ApikeeClaims claims = engine.verify(key);
claims.tenant(); // "acme-corp"
claims.scopes(); // ["read", "write"]var engine = new ApikeeKeyEngine(["your-signing-secret"]);
string key = engine.Create(new KeyOptions {
Tenant = "acme-corp",
Scopes = ["read", "write"],
ExpiresIn = "90d",
Meta = new Dictionary<string, object> { ["plan"] = "pro" },
});
ApikeeClaims claims = engine.Verify(key);
claims.Tenant // "acme-corp"
claims.Scopes // ["read", "write"]Protect an API
from apikee.fastapi import SecuredFastAPI, ApikeeDepends
from apikee import ApikeeClaims
app = SecuredFastAPI(secrets=["your-signing-secret"])
# ↑ Middleware + Swagger security scheme applied automatically
@app.get("/data")
def get_data(claims: ApikeeClaims = ApikeeDepends()):
return {"tenant": claims.tenant}Open /docs — every endpoint has a 🔒 lock.
from flask import Flask
from apikee.flask import init_apikee, apikee_required, get_claims
app = Flask(__name__)
init_apikee(app, secrets=["your-signing-secret"])
@app.get("/data")
@apikee_required
def get_data():
return {"tenant": get_claims().tenant}import express from 'express'
import { apikeeMiddleware } from 'apikee/express'
const app = express()
app.use(apikeeMiddleware({ secrets: ['your-signing-secret'] }))
app.get('/data', (req, res) =>
res.json({ tenant: req.apikee!.tenant })
)import { apikeePlugin } from 'apikee/fastify'
import { Apikee } from 'apikee'
const apikee = new Apikee({ secrets: ['your-signing-secret'] })
await fastify.register(apikeePlugin, { apikee })
fastify.get('/data', async (req) => ({
tenant: req.apikee!.tenant,
}))import { Hono } from 'hono'
import { apikeeMiddleware } from 'apikee/hono'
const app = new Hono()
app.use('*', apikeeMiddleware({ secrets: ['your-signing-secret'] }))
app.get('/data', (c) => c.json({ tenant: c.get('apikee').tenant }))# application.yml — zero Java code needed
apikee:
secrets:
- your-signing-secret@GetMapping("/data")
public Map<String, Object> data(HttpServletRequest req) {
ApikeeClaims claims = (ApikeeClaims) req.getAttribute("apikee.claims");
return Map.of("tenant", claims.tenant());
}// Program.cs
builder.Services.AddApikee(o => o.Secrets = ["your-signing-secret"]);
builder.Services.AddSwaggerGen(c => c.AddApikeeSecurityDefinition());
app.UseApikee();
// Controller
[Apikee]
public class DataController : ControllerBase {
[HttpGet("/data")]
public IActionResult Get() {
var claims = (ApikeeClaims) HttpContext.Items["apikee.claims"]!;
return Ok(new { claims.Tenant });
}
}That's it for local mode. No database, no network calls, no config beyond a signing secret.
Next steps
- Core concepts — understand the key format and validation pipeline
- Two modes — when to use local vs server mode
- Scopes guide — how to implement role-based access control
- Developer platform — connect to apikee.dev for production features

