What you'll build#
A Hono app with API key authentication using the @unkey/hono middleware. All routes (or specific ones) require a valid API key.
Time to complete: ~5 minutes
Prerequisites#
- Unkey account (free)
- Keyspace created in your Unkey dashboard
- Node.js 18+ or Bun
Want to skip ahead?
Clone the complete example and run it locally.
Create a Hono app#
Choose your preferred runtime (Node.js, Bun, Cloudflare Workers, etc.)
Install the Unkey middleware#
Add your root key#
Create a .env file:
.env
Note
The Hono middleware verifies keys directly against your root key.
Add the middleware#
Update src/index.ts:
src/index.ts
Run your app#
Test it#
Create a test key in your Unkey dashboard, then:
Test with valid key
You should see:
Without a key, you'll get a 401:
Test without key
Protecting specific routes#
Instead of protecting all routes, you can apply the middleware to specific paths:
src/index.ts
What's in the context?#
After verification, c.get("unkey") contains:
| Field | Type | Description |
|---|---|---|
valid | boolean | Whether the key passed all checks |
code | string | Status code (VALID, NOT_FOUND, RATE_LIMITED, etc.) |
keyId | string | The key's unique identifier |
name | string? | Human-readable name of the key |
meta | object? | Custom metadata associated with the key |
expires | number? | Unix timestamp (in milliseconds) when the key will expire. (if set) |
credits | number? | Remaining uses (if usage limits set) |
enabled | boolean | Whether the key is enabled |
roles | string[]? | Named role(s) assigned to the key, each representing a set of permissions |
permissions | string[]? | List of individual permissions granted to the key |
identity | object? | Identity info if externalId was set when creating the key |
ratelimits | object[]? | Rate limit states (if rate limiting configured) |
Middleware options#
Next steps#
Troubleshooting#
Getting 401 even with a valid key?
- Ensure the key hasn't expired or been revoked - Verify the header format:
Authorization: Bearer YOUR_KEY
Environment variables not loading?
- For Node.js: Install
dotenvand addimport 'dotenv/config'at the top - For Bun:.envis loaded automatically - For Cloudflare Workers: Usewrangler secretorwrangler.toml
Deploying to Cloudflare Workers?
Use wrangler secrets for your root key:
Then access it from your Hono bindings. Add UNKEY_ROOT_KEY to your Bindings type and read it via ctx.env.UNKEY_ROOT_KEY or env.UNKEY_ROOT_KEY in your handlers.