Skip to main content
@unkey/hono (version ) is a Hono middleware that the API key on each request and puts the result on the context. It needs hono 4.6 or later.
You need a root key with the permissions listed on this page. Create one in the dashboard under Settings > Root Keys, and pass it as Authorization: Bearer <root key>. See Permission reference for every permission.

Install

Protect routes

The middleware reads the bearer token from the Authorization header, calls keys.verifyKey, and puts the full result in c.get("unkey"), so your handler can read data.valid, data.code, data.keyId, data.meta, and the rest. A request with no key gets 401 {"error":"unauthorized"}.
Unless you pass handleInvalidKey, an invalid key doesn’t stop the request: the middleware stores the failed verification and calls the next handler. Check data.valid in your handler, or set handleInvalidKey to reject centrally.

Options

string
required
Root key used to call keys.verifyKey.
string
A permission query the key must satisfy for data.valid to be true, for example "documents.read".
string[]
Tags recorded with the verification for later filtering in analytics.
(c: Context) => string | undefined | Response
Read the key from somewhere else, such as a query parameter. Return a Response to stop there. Return nothing to get a 401.
(c: Context, result: UnkeyContext) => Response | Promise<Response>
Called when the key is present but data.valid is false. Return the response the client should get.
(c: Context, err: errors.APIError) => Response | Promise<Response>
Called only for unexpected responses from the verify call, such as a 502 from a proxy. Return the response the client should get. Without it, these become a Hono HTTPException with status 500.

Reject invalid keys centrally

onError doesn’t catch everything. A rejected root key (401), a throttled request (429), a 500, or a connection failure or timeout is thrown instead. Catch those in Hono’s app.onError if you want one response for every authentication failure.

Next steps

Verifying keys

What valid, code, permissions, and rate limits mean in the result.

@unkey/api

Call any other endpoint from the same app.
Last modified on September 29, 2026