Callback verification
Automatically verify agent callbacks, or build a standalone verifier for a custom route.
agent.handlers and agent.fetch verify callbacks before dispatching tools or hooks.
Each app process learns the organization and environment from its Cereal API key.
This works without an earlier sync in that process. The configured application origin
and route paths determine the expected audience.
Checks cover the signature, token lifetime, body integrity, audience, replay and organization/environment/agent/connection identity. For application tools, prefer these handlers and the framework adapters.
Standalone routes
Use @trycereal/sdk/verify for custom middleware or callback routes outside a defined
agent. Learn tenant context from the credential, then hold one verifier so its key
cache can be reused:
import { getCerealClient } from "@trycereal/sdk"
import { createCerealVerifier, CerealSignatureError } from "@trycereal/sdk/verify"
const context = await getCerealClient().me()
const verify = createCerealVerifier({
audience: "https://app.example.com/custom-hook",
purpose: "hook",
expect: {
org: context.organization.slug,
env: context.environment.slug,
agent: "support",
connection: "support"
}
})
export async function POST(request: Request) {
try {
const verified = await verify(request)
// Dispatch your callback using verified.body and verified.session.
return Response.json({ ok: true })
} catch (error) {
if (error instanceof CerealSignatureError)
return Response.json({ reason: error.reason }, { status: 401 })
throw error
}
}The audience must match the callback URL registered with Cereal. Agent and connection expectations identify the resources this custom endpoint serves. Never derive expected tenancy from an unverified incoming token. The verifier selects the organization's published key set from trusted configuration and asserts the signed claims.
verifyCerealRequest is the one-shot alternative. createCerealVerifier reuses its
key cache across requests. Both preserve the original request body for the caller.
The default replay store is per process; use a shared store when replicas must share
replay detection. See verification options.
| Failure | Meaning |
|---|---|
missing_token | No credential in the expected header |
invalid_signature / unknown_key | Signature or signing key could not be verified |
expired | Token lifetime has ended |
audience_mismatch | The token targets another endpoint |
body_hash_mismatch | Request bytes differ from the signed body |
purpose_mismatch | A tool signature arrived at a hook endpoint, or vice versa |
tenant_mismatch / agent_mismatch / connection_mismatch | The signed resource identity does not match the endpoint |
replayed | The token was already accepted by the replay store |