Routing API

Purpose and Scope

The Routing API is the public composition layer for putting Flue’s generated HTTP surface inside an application that you own. It answers two related questions: what must an authored application export, and what routes does the framework publish when that application mounts the Flue sub-application. The API is intentionally small. Import the composition entrypoint from @flue/runtime/routing, decide where the Flue routes belong in your HTTP tree, and then layer your own health checks, authentication, channel-specific policies, or prefixes around that mount. This page focuses on the reference contract rather than the broader routing guide.

Sources: apps/docs/src/content/docs/api/routing-api.md

Relevant Source Files

  • apps/docs/src/content/docs/api/routing-api.md — first-party API reference for app.ts, the Fetchable default-export contract, the flue() mount helper, published route shapes, module export gates, and accepted request bodies.

App Entry Point Contract

app.ts is optional. If a project does not provide it, Flue generates an application that mounts flue() at the root path. Once you add an authored entrypoint, that generated default is no longer responsible for publishing the framework routes. Your default export owns the request pipeline, so it must explicitly mount flue() somewhere if agents, workflows, runs, or channels should be reachable over HTTP. This makes the application boundary clear: Flue supplies the sub-application, while your entrypoint decides ordering, prefixing, middleware, and any application-owned routes that should sit beside it.

Sources: apps/docs/src/content/docs/api/routing-api.md

import { flue } from '@flue/runtime/routing';
import { Hono } from 'hono';
 
const app = new Hono();
app.route('/', flue());
export default app;

The default export is described structurally as Fetchable, not as a nominal class. Any object with a compatible fetch(request, env, ctx) method satisfies the contract, including a new Hono() instance. That matters because the same authored entrypoint can be hosted by different targets while preserving the same basic shape. On Cloudflare, env is where platform bindings arrive and ctx is the worker execution context. On Node, the docs describe env as the Hono Node adapter bindings for incoming and outgoing messages, while ctx is undefined. Application code should avoid assuming the same target-specific values everywhere.

Sources: apps/docs/src/content/docs/api/routing-api.md

interface Fetchable {
  fetch(request: Request, env?: unknown, ctx?: unknown): Response | Promise<Response>;
}

flue() Mounting and Resource Routing

flue() returns a Hono sub-application that contains Flue’s public HTTP API. The routes are relative to the prefix chosen by the application. If you call app.route('/', flue()), the documented paths are served at the root. If you mount the sub-application under another prefix, the same route set moves beneath that prefix. This distinction is important for deployments that reserve root paths for health checks, versioned APIs, tenant routers, or reverse-proxy conventions. Flue does not require the framework surface to be the whole service; it only requires the authored application to mount it where desired.

Sources: apps/docs/src/content/docs/api/routing-api.md

RoutePurpose
POST /agents/:name/:idStart a prompt on an HTTP-exposed agent instance and return 202 with stream coordinates.
POST /agents/:name/:id/abortAbort the selected instance’s in-flight and queued durable work and return 200 { aborted }.
GET /agents/:name/:idRead materialized history or projected updates for an agent instance.
HEAD /agents/:name/:idReturn canonical conversation-stream metadata.
POST /workflows/:nameStart an HTTP-exposed workflow run.
GET /runs/:runIdStream workflow-run events through the Durable Streams protocol.
GET /runs/:runId?metaRetrieve the workflow-run record as plain JSON.
HEAD /runs/:runIdReturn run stream metadata such as tail offset and closed status.
* /channels/:name/*Serve discovered channel handlers by channel name, method, and suffix.

Not every route listed above appears for every module. Agent prompt routes and workflow invocation routes are published only when the corresponding module exports route. Existing workflow run resources are separate: a workflow module must export runs to make those run resources available. Channel routing follows the discovered channel file instead; a channel file exports a named channel binding, and provider-declared handlers are mounted beneath /channels/<filename>. This export-gated design lets projects expose only the resources they intend to publish, rather than making every discovered agent or workflow automatically callable through HTTP.

Sources: apps/docs/src/content/docs/api/routing-api.md

Request Bodies and Runtime Semantics

The direct agent prompt route accepts the same unified delivered-message shape admitted by dispatch(). A normal chat turn has kind set to user, includes a string body, and may include image attachments for vision-capable models. Attachments carry image metadata and base64-encoded content, with the API reference noting a fourteen-mebibyte base64 character cap per image. Structured external events use kind set to signal, together with a type, body, and optional attributes or tag name. Workflow invocation is simpler at the routing layer: POST /workflows/:name receives the workflow input as its JSON body.

Sources: apps/docs/src/content/docs/api/routing-api.md

One subtle boundary is that direct agent prompts and dispatched agent inputs are not workflow runs. They can be durable work, and they can produce streams or projected updates, but they are addressed through the agent instance routes rather than the workflow run routes. Conversely, /runs/:runId belongs to workflow-run observation and metadata. Keeping these address spaces separate helps clients choose the correct polling, streaming, or metadata endpoint. If a frontend starts an agent prompt, it should retain the returned stream coordinates for that agent conversation; if it starts a workflow, it should track the returned run identifier.

Sources: apps/docs/src/content/docs/api/routing-api.md

Application Composition Patterns

Because an authored entrypoint owns the request pipeline, use it to express service-level behavior before or around the Flue mount. Common patterns include a public health route, authentication middleware for /agents/*, /workflows/*, and /channels/*, and a prefix that separates Flue resources from the rest of an application API. Resource-specific authorization still belongs close to the selected resource. For example, a direct agent route must verify that the caller may access the instance id they selected, and a workflow run reader should authorize access to the selected run before exposing stream metadata or history.

Sources: apps/docs/src/content/docs/api/routing-api.md

Channels are routed through the same mounted Flue sub-application, but they usually represent provider ingress rather than generic application endpoints. The channel file name becomes part of the route prefix, and the provider declares method-and-suffix handlers below that prefix. This lets examples such as webhook or interaction handlers live under stable /channels/... URLs while still allowing the application to add its own middleware before the Flue mount. When a channel callback dispatches to an agent, treat the provider verification, deduplication, and destination identity policy as application responsibilities around the framework’s durable admission path.

Sources: apps/docs/src/content/docs/api/routing-api.md

Reference Checklist and Next Steps

Use this checklist when reviewing a routing setup. If there is no authored app.ts, Flue’s generated app mounts the public API at /. If there is an authored app.ts, verify that it imports flue from @flue/runtime/routing, exports a compatible fetchable object, and calls app.route() or an equivalent Hono composition method to mount the sub-application. Then confirm that each intended agent or workflow exports the appropriate route binding, that workflow run resources are explicitly exposed when needed, and that discovered channels export their named channel binding. After that, add authentication and resource authorization in the authored application.

Sources: apps/docs/src/content/docs/api/routing-api.md