File object, raw bytes, or a streaming body from a network response. Before passing anything to a provider, FileRouter resolves the input once into a canonical, provider-safe form. This resolution step is what lets compare() run multiple providers concurrently without consuming a one-shot stream more than once.
Accepted input types
You can pass any of the following as the first argument toparse() or compare():
HTTP URL
A
string starting with http:// or https://, or a URL object. FileRouter validates the URL and passes it directly to the provider — the document is never downloaded into your runtime.Local file path
A plain string file path (e.g.
"/tmp/report.pdf") or the explicit object { kind: "file", path: "/tmp/report.pdf" }. FileRouter reads the file from disk into bytes.File or Blob
A browser or Node.js
File or Blob instance. FileRouter preserves the filename and MIME type from the object when available.ArrayBuffer or typed array
An
ArrayBuffer or any ArrayBufferView (such as Uint8Array). Useful when you have already read bytes into memory.ReadableStream
A web
ReadableStream<Uint8Array>. FileRouter consumes the stream once and converts it to replayable bytes before dispatch.Explicit bytes object
The structured form
{ kind: "bytes", data, mimeType?, name? } lets you supply bytes alongside explicit metadata when you already know the filename and MIME type.ParseInput type from the SDK captures all of these forms:
parse-input-type.ts
How inputs are resolved
FileRouter resolves every input exactly once into one of two canonical, provider-safe representations before any provider call is made:- A validated HTTP URL — used when your input is already an
http://orhttps://URL. FileRouter validates the URL format and passes it directly to the provider. The file is never downloaded into your runtime. - Replayable bytes — used for everything else. The input (file, buffer, stream, or path) is read into an in-memory
Blobwith a normalized filename and resolved MIME type.
The one-time resolution is critical for
compare(). A ReadableStream can only be consumed once. FileRouter reads it into replayable bytes first, then fans the same bytes out to each provider concurrently — your stream is never partially consumed.MIME type resolution
FileRouter resolves the MIME type of your document deterministically using the following priority order:1
Explicit non-generic MIME type
If you supply a
mimeType directly (via a File, Blob, or the { kind: "bytes" } form) and it is a specific, non-generic type (not application/octet-stream), FileRouter uses it as-is.2
Filename extension
If the explicit MIME type is absent or generic, FileRouter infers the type from the filename extension — for example,
.pdf → application/pdf, .docx → application/vnd.openxmlformats-officedocument.wordprocessingml.document.3
Fallback to octet-stream
If neither step produces a specific type, FileRouter falls back to
application/octet-stream and lets the provider decide how to handle the bytes.Unknown file signatures
FileRouter does not reject a document simply because its binary signature is unrecognized. Text-based formats like CSV and Markdown have no reliable binary signature, and provider support for new formats evolves independently of FileRouter releases. If you send a.csv file, FileRouter resolves the MIME type from the extension and forwards it to your chosen provider.
You can check how FileRouter resolves the MIME type of any document locally — without sending it anywhere — using
inspectDocument() from @file_router/sdk/inspect. This function reports the resolved type, the extension-derived type, the detected binary signature type, and whether they conflict.Hosted uploads
When you use the hosted API (FileRouterClient), your document streams directly from the request body into private cloud storage. FileRouter never buffers the full file in memory during ingress.
Upload limit
The hosted endpoint accepts files up to 100 MB.
Streaming ingress
Your file streams directly to storage — it is never parsed as multipart or accumulated in memory by FileRouter during upload.