Apikee

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 apikee

Node 18+ required. Zero production dependencies.

<dependency>
  <groupId>dev.apikee</groupId>
  <artifactId>apikee-spring</artifactId>
  <version>0.1.0</version>
</dependency>
dotnet add package Apikee

Create 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 object
ApikeeKeyEngine 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

On this page