main, but it passes the method and path on input.request. Your agent becomes its own router: one deploy, several endpoints.
What the agent receives
Routing example
Sync, async and streaming
async and stream are reserved words, but only as the first segment after the agent id. The mode segment is stripped before the path reaches your code, so one router serves all three modes:
Do not name one of your routes
async or stream.
Returning a raw body
By default the response is wrapped in the Runflow envelope ({ metadata, ... }). Add ?raw=true to return exactly what main returned:
- strings go out as
text/plain, without quotes - objects, arrays, numbers and booleans go out as JSON
- execution metadata moves to response headers:
X-Runflow-Execution-Id,X-Runflow-Duration-Ms,X-Runflow-Agent-Name,X-Runflow-Agent-Version,X-Runflow-Timestamp
Reading the request
- The body is not spread into the input. Only
body.messageis copied toinput.message. Read every other field frominput.request.body. - Headers and query values are arrays. Use
input.request.query?.status?.[0]andinput.request.headers?.['X-Trace-Id']?.[0]. Header names arrive in canonical form (X-Trace-Id, notx-trace-id). - Read cookies from the
Cookieheader. Thecookiesfield is typed as a map, but the platform currently sends an array of objects with capitalized keys ({ Name, Value, ... }).input.request.headers?.Cookie?.[0]has the raw string. - File uploads sent as
multipart/form-dataland oninput.attachments[]. See Multi-Modal.
Authentication and threads
- Send the agent token in the
X-Runflow-Tokenheader instead of?token=. The query string is delivered to the agent as is, so a token sent as a query param shows up ininput.request.query.token. - Send
X-Runflow-Thread-Idto pin the call to a specific memory thread. The value is scoped to your tenant.
Where input.request is available
To test a route locally, call
main with a hand-built request object:
Next Steps
Agents
Configure the agent behind the default route
Core Types
Full
AgentInput reference