upload
Upload files and folders for extraction
limai upload <extractionSchemaId> <path>Upload a single file or an entire folder for data extraction. Supports concurrent uploads, glob filtering, automatic processing, and waiting for results.
--concurrency <n>Number of concurrent uploads for folder uploads(default: 5)--processQueue files for extraction after upload--waitWait for all extractions to complete (implies --process)--output <file>Write results to a JSON file--glob <pattern>Filter files by glob pattern (folder uploads only)--allow-duplicatesUpload a file whose content the project already stores as a new document instead of skipping it--jsonOutput raw JSON--verboseEnable debug loggingBehavior
Single file: Uploads the file and optionally queues it for extraction.
Folder: Scans the directory for supported files, uploads them concurrently, and reports results.
When --wait is used, the CLI polls until all extraction jobs complete. --output then writes the extracted data for a single-file upload, and the per-file upload summary for a folder.
Duplicates
Each file's content is hashed and matched against the documents the project already stores. A match is skipped: no bytes are uploaded, nothing is queued for extraction, and the exit code stays 0, because a duplicate is not an error.
A single-file upload prints:
Duplicate of existing file <fileId> (<filename>); skipped. Pass --allow-duplicates to upload it as a new document, or run 'limai documents process <extractionSchemaId> <fileId>' to re-extract the existing one.When the match lives in another model the message names it instead, and drops the limai documents process suggestion — that command would fail here, so --allow-duplicates is the only way forward:
Duplicate of existing file <fileId> (<filename>) in model <modelId>; skipped. That document belongs to another model, so 'limai documents process' on this model would fail; pass --allow-duplicates to upload it into this model as a new document.With --json it reports {"fileId": "<existing id>", "filename": "...", "isDuplicate": true, "bytesUploaded": 0, "skipped": true, "existingDeploymentId": "<model id or null>", "existingInSameModel": true}.
On a folder upload each file's status can be duplicate, and the per-file JSON entry carries isDuplicate. The summary line reads:
Upload complete: <n> uploaded, <n> queued, <n> duplicates skipped, <n> failed (<n> total)followed by one line per duplicate:
Duplicate: <filename> matches existing file <fileId>or, for a match in another model:
Duplicate: <filename> matches existing file <fileId> in model <modelId>isDuplicate means the document is already stored in the project, not that it has been extracted. To extract the copy that is already there, run limai documents process <extractionSchemaId> <fileId> — which works only when the existing copy lives in the same model. With --allow-duplicates the file uploads as a new document instead and is processed normally when --process is passed.
Examples
Upload a single file
limai upload es_abc123 ./invoice.pdfUpload and extract immediately
limai upload es_abc123 ./invoice.pdf --processUpload, extract, and wait for results
limai upload es_abc123 ./invoice.pdf --wait --output results.jsonUpload a folder of PDFs
limai upload es_abc123 ./documents/ --glob "*.pdf"Bulk upload with higher concurrency
limai upload es_abc123 ./documents/ --concurrency 10 --processUpload folder, process, and wait for all
--output here writes the upload summary — one entry per file with its status, job ID and duplicate information — not the extracted data.
limai upload es_abc123 ./documents/ --wait --output batch-results.jsonUpload a second copy of a document the project already stores
limai upload es_abc123 ./invoice.pdf --allow-duplicates --process