Hono 4.13.13 deprecates app.mount(): mount a Sume webhook sub-app
Hono 4.13.13 deprecates app.mount() in favor of Mount Middleware. A Sume webhook receiver written as a Hono sub-app uses app.route() and keeps its raw body.

Hono 4.13.13, released 2026-10-04, adds hono/mount as Mount Middleware and deprecates app.mount(). That method mounts a foreign fetch-style app. A Sume webhook receiver is a Hono route, so it uses app.route() and does not depend on mount at all. The fix for a receiver is to keep the verifier in its own sub-app and read the raw body inside it.
What changed in 4.13.13
The release notes name the new middleware and the deprecation. They do not say when app.mount() will be removed. Earlier notes (4.13.10) say hono/<adapter> imports are removed in v5, so plan for one clean-up pass.
| Version | Date | Change that matters here |
|---|---|---|
| 4.13.10 | 2026-09-28 | Adapters split into @hono/* packages |
| 4.13.11 | 2026-09-29 | serveStatic double-decode fix; % rejected unless allowPercentInPath: true |
| 4.13.12 | 2026-09-30 | Patch release |
| 4.13.13 | 2026-10-04 | hono/mount added; app.mount() deprecated |
Where a Sume receiver fits
A Sume job webhook carries job.completed, job.failed or job.canceled, signed over <timestamp>.<raw_body>. The verifier must see the exact bytes, so keep it in a sub-app with no body-parsing middleware ahead of it.
Mount order matters: register any JSON middleware on other sub-apps, not on the app that handles /hooks.
A sub-app for the receiver
app.route() is the supported way to compose Hono apps. The sub-app below refuses to run without a secret.
import { Hono } from "hono";
import { verifyWebhook } from "@sume-com/sdk";
export const hooks = new Hono<{ Bindings: { SUME_COM_WEBHOOK_SIGNING_SECRET?: string } }>();
hooks.post("/sume", async (c) => {
const secret = c.env?.SUME_COM_WEBHOOK_SIGNING_SECRET ?? globalThis.process?.env?.SUME_COM_WEBHOOK_SIGNING_SECRET;
if (!secret) return c.text("not configured", 500);
const body = await c.req.text();
if (!(await verifyWebhook({ body, headers: c.req.raw.headers, secret }))) {
return c.text("bad signature", 401);
}
const { event, job_id } = JSON.parse(body);
console.log(event, job_id);
return c.body(null, 204);
});
// in the main app: app.route("/hooks", hooks);After you deploy
Check the route with a signed dummy, then wait for a real job.
POST /v1/webhooks/test-deliveriessends a signedwebhook.testto the URL you give it.- Return a 2xx after you store the event; Sume retries up to 10 times at 30 second spacing.
- Use
POST /v1/jobs/{job_id}/webhook/redeliverto replay a real terminal event with a fresh signature.
Why a sub-app is the safer shape
A receiver has one job: read bytes, verify, store, answer. Putting it in its own Hono instance keeps that job away from middleware that other routes need, such as a JSON body parser, a CORS layer or a logger that reads the body. Any one of those can consume the stream before the verifier sees it, and then every signature check fails with no obvious cause.
With app.route("/hooks", hooks) the sub-app keeps its own middleware stack. Order inside the sub-app still counts, so register nothing before the handler that touches the body.
The 4.13.10 notes say hono/<adapter> imports are removed in v5, and 4.13.13 deprecates app.mount(). Neither affects a plain route. Search your code for both once, record the result in your upgrade notes, and move on. If you do use app.mount() to host another fetch-style app, read the 4.13.13 notes for the Mount Middleware replacement before you change anything.
Sources
Related posts
More in Developers
- Which Sume hosted MCP tools are read-only? 24 the docs label Read
The tools-and-gates page labels 24 hosted MCP tools as Read across five groups, plus meta and account tools. List and verify with tools_list.
- Can hosted MCP run a Sume Format? Call it over REST with an API key
The hosted MCP tools-and-gates inventory lists no Format-run tool. Run Formats with POST /v1/formats/{handle}/{slug}/runs and an API key that has formats:write.
- Hosted video instead of a GPU: a Python submit-poll-download script
Replace a local H3 or Wan pipeline with three HTTP calls. A Python script that submits a minimax-h3 job to Sume, polls it and saves the MP4, with job states.
- How many Sume jobs can one key poll at once? Reads per minute by plan
Polling every 2 seconds costs 30 reads per job per minute. Divide your plan's read budget by 30 to size the poller: 160 jobs on Free, 1600 on Scale.
Written by Sume