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. In NestJS, the standard approach is to use FileInterceptor from @nestjs/platform-express on specific routes, or to let the adapter handle multipart natively for the /api/persona/* routes.

Body size limits

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, configure multer’s limits option:
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.