Skip to main content
Two routes accept file uploads, and the adapter parses them natively — zero extra dependencies:
  • POST /files — single-file upload, file part required (plus optional agentId/threadId form fields)
  • POST /knowledge/:id/documents — one or more files parts (plus optional agentId/threadId)
Both are always-on (/files) or capability-gated (/knowledge — enable capabilities.knowledge) routes of the runtime; the adapter’s job is only to translate the incoming multipart body into the runtime’s file/files/body fields.

Native parsing

When a multipart request arrives, the adapter reads the raw stream and parses it with Node’s built-in FormData (undici, shipped with Node 18+) — no multer, busboy, or formidable required:
The file part becomes RuntimeRequest.file ({filename, content, contentType}); any other form fields (agentId, threadId) land on RuntimeRequest.body and flow through to the SDK upload call.

Using multer yourself

The adapter coexists with multer. If your own middleware already parsed the multipart body, the adapter detects the parsed req.file/req.files and honors them instead of reading the stream again:
One warning: if a body parser ran without capturing the file (e.g. express.json() on a multipart request, or a multer instance configured to discard), the adapter detects that the stream was already consumed and responds 400 INVALID_REQUEST — it can’t reconstruct the body. Keep multer on the same route or path prefix as the adapter mount, and don’t put a generic body parser in front of multipart routes.

Body size limits

Like the runtime’s own reference bridge, the adapter buffers request bodies (JSON and multipart) in memory with no size limit of its own. Enforce one with your own middleware when you need it:
For multipart specifically, either let multer enforce its limits (it returns 413 on limits.fileSize overflow) or add an express.raw({ type: 'multipart/form-data', limit: ... }) guard ahead of the mount. Choose limits that match your product — typical chat attachments are 1–25 MB.

Downloads are binary

The mirror image: GET /files/:id streams the file back through as raw bytes (kind: 'binary'), chunk by chunk, with the correct Content-Type. The adapter handles Content-Disposition-style headers from the runtime verbatim.