# Integration CLI Full Documentation > Give this URL to an AI assistant when it needs complete Integration CLI context in one file. Integration CLI validates VAT IDs from CSV files or mailbox-style folders. Use this file when an AI agent needs enough context to help configure, run, or troubleshoot the CLI. This file is for CLI usage only. It does not document direct Integration API endpoints; use the Integration API reference when you are building an HTTP integration. Prefer sharing the published URL for this file instead of uploading a downloaded copy. Downloaded copies can become outdated. ## Document Index 1. [Integration CLI](/cli/intro) - What Integration CLI does, when to use it, and which files a run creates. 2. [Getting Started](/cli/getting-started) - First CSV validation flow from mapping file and token to result CSV. 3. [Installation](/cli/installation) - Runtime, operating system packages, network hosts, and update guidance. 4. [Authentication](/cli/authentication) - Personal Access Tokens, environments, base URLs, and authentication errors. 5. [Check Command](/cli/commands/check) - Command syntax, arguments, options, examples, and validation rules. 6. [Mapping File](/cli/configuration/mapping-file) - YAML mapping file structure for columns, defaults, filters, output, and folder mode. 7. [CSV Input](/cli/configuration/csv-input) - CSV header mode, no-header mode, delimiters, encodings, skipped records, and passthrough columns. 8. [Result CSV](/cli/configuration/result-csv) - Result CSV paths, columns, shortcuts, status values, and determined corrections. 9. [Configuration Precedence](/cli/configuration/precedence) - How command-line flags, YAML, environment variables, and defaults combine. 10. [Dry Run](/cli/workflows/dry-run) - Validate CSV parsing and mapping without calling the API. 11. [Folder Mode](/cli/workflows/folder-mode) - Mailbox-style folder processing with processing, done, error, results, and logs folders. 12. [PDF Reports](/cli/workflows/pdf-reports) - PDF report creation, signing, save locations, timestamps, and email options. 13. [Resume And Idempotency](/cli/workflows/resume-and-idempotency) - Saved validation state, automatic resume, force-new behavior, and idempotency keys. 14. [Support Logs](/cli/workflows/support-logs) - Support log locations, privacy guarantees, and what to share with support. 15. [Exit Codes](/cli/reference/exit-codes) - Process exit codes and how automation should handle them. 16. [Troubleshooting](/cli/reference/troubleshooting) - Common configuration, CSV, authentication, API, resume, and folder-mode problems. --- # Integration CLI Source: docs-site/docs/cli/intro.md URL: /cli/intro Integration CLI is a command-line client for validating VAT IDs from CSV files or from a folder that receives CSV files automatically. Your ERP cannot connect to an API? No problem. With Integration CLI, you can integrate VAT ID verification into any system automatically, without development effort. Export your data as CSV and the CLI handles the rest: verify VAT IDs, validate company data, enrich company records, detect deviations, and return corrections. Once set up, everything runs automatically in the background. If you have any questions, contact Optimus support. Use it when you need to: - Validate a single CSV file and write a result CSV. - Run standard or qualified VAT ID checks. - Keep selected local columns, such as customer numbers, in the result file. - Save PDF reports when requested. - Process a mailbox-style folder with `inbox`, `processing`, `done`, `error`, and `results` folders. - Resume interrupted validation operations without starting duplicate API work. The executable name is `optimus`. The current public command is: ```bash optimus check ``` `` can be a CSV file or a folder. :::tip[Recommended setup] Put stable settings such as column mapping, delimiters, output columns, PDF defaults, and folder mode options in `mapping.yml`. Use command-line flags for one-off choices such as `--env test`, `--dry-run`, `--out`, or `--verbose`. ::: ## How The Docs Are Organized - Start with [Getting started](./getting-started.md) for the shortest working CSV flow. - Use [AI Agent Docs](./ai-agent-docs.md) to download CLI-only `llms.txt` files for coding assistants and internal agents. - Use [Authentication](./authentication.md) to configure tokens and API targets. - Use [Check command](./commands/check.md) for command syntax and options. - Use [Mapping file](./configuration/mapping-file.md) for YAML configuration. - Use [Result CSV](./configuration/result-csv.md) to understand output columns and statuses. - Use [Folder mode](./workflows/folder-mode.md) for automated folder processing. - Use [Troubleshooting](./reference/troubleshooting.md) when a run fails. ## Files Created By A Run Depending on options, a run can create: | File | Purpose | | --- | --- | | `customers_result.csv` | Result CSV for a single input file when `--out` is not set. | | `customers.csv.optimus-state.json` | Saved validation state used for resume behavior. | | `logs/optimus-check-*.log` | Privacy-safe support log for the run. | | `*.pdf` | VAT validation report when PDF output is enabled. | | `error/*.err` | Folder mode error details for files that cannot be processed. | --- # Getting Started Source: docs-site/docs/cli/getting-started.md URL: /cli/getting-started This page shows the shortest safe path from an input CSV to a result CSV. The CLI is designed for systems that can export CSV files but cannot connect directly to an API. After setup, your ERP or job scheduler can export files, the CLI can validate them automatically, and the result CSV can be imported back into your process. ## Prerequisites You need: - The `optimus` command installed and available in your terminal. - An Optimus API token. - A CSV file with a VAT ID column. - A mapping file that tells the CLI which CSV columns to use. Verify the CLI is available: ```bash optimus --version ``` ## Create A Mapping File Create `mapping.yml` next to your CSV file: ```yaml columns: vatId: "VatId" name: "CompanyName" street: "Street" zip: "PostalCode" city: "City" customColumns: customer_number: "CustomerNumber" input: delimiter: ";" encoding: "utf-8" hasHeader: true output: delimiter: ";" encoding: "utf-8" bom: true defaults: checkType: standard retryDuration: None ``` Only `columns.vatId` is required. If name, street, zip, and city are provided, Optimus verifies each component against the responsible state authorities. `customColumns` are copied into the result CSV. They are not sent to the validation API. ## Prepare A CSV File For the mapping above, the input CSV can look like this: ```csv VatId;CompanyName;Street;PostalCode;City;CustomerNumber DE284700631;Optimus Software GmbH;Tal 44;80331;München;C-1001 DE000000000;Example GmbH;Main Street 1;10115;Berlin;C-1002 ``` ## Configure Your Token Use an environment variable so the token does not appear in command history: ```bash export OPTIMUS_TOKEN="" ``` On Windows PowerShell: ```powershell $env:OPTIMUS_TOKEN = "" ``` ## Run A Dry Run First Dry-run mode validates the file and mapping without calling the API: ```bash optimus check customers.csv --map mapping.yml --standard --dry-run ``` Use this before real validation when you are creating or changing a mapping file. The output shows the first 5 checkable rows that would be sent to the API, which helps confirm that column mappings select the expected CSV values. ## Run The Validation Run a standard check: ```bash optimus check customers.csv --map mapping.yml --standard ``` Run a qualified check: ```bash optimus check customers.csv --map mapping.yml --qualified ``` The check type can also come from `defaults.checkType` in the mapping file. If neither the command nor the mapping file sets it, the CLI reports a configuration error. ## Review The Result For `customers.csv`, the default result path is: ```text customers_result.csv ``` The result includes the input VAT ID, validation status, field match statuses, determined values when returned by the API, custom columns from your mapping, and `checked_at`. Example result: ```csv row;customer_number;vat_id;vat_id_status;name;name_status;name_determined;street;street_status;street_determined;zip;zip_status;zip_determined;city;city_status;city_determined;checked_at 1;C-1001;DE284700631;Valid;Optimus Software GmbH;Match;;Tal 44;Match;;80331;Match;;München;Match;;2026-05-13T09:15:00Z 2;C-1002;DE000000000;Invalid;Example GmbH;;;Main Street 1;;;10115;;;Berlin;;;2026-05-13T09:15:01Z ``` The run also writes a support log unless you use `--no-log`. --- # Installation Source: docs-site/docs/cli/installation.md URL: /cli/installation Install the Integration CLI using the distribution channel provided by Optimus for your environment. After installation, the command should be available as `optimus`. Verify the installation: ```bash optimus --version ``` On Windows, the executable is `optimus.exe`: ```powershell .\optimus.exe --version ``` Show command help: ```bash optimus --help optimus check --help ``` ## Runtime Requirements The CLI is built from a .NET 9 project. Current release builds are published as self-contained, single-file applications. The .NET runtime is embedded in the published executable, so the target machine does not need a separate .NET installation for the published CLI artifact. No installer is required. Place the executable in a folder that your automation can access and run it from there. End users normally do not need to know the project layout, but the source project is: ```text api/tools/Optimus.Cli/Optimus.Cli.csproj ``` ## Operating System Choose the package that matches the target operating system and CPU architecture. | Package | Executable | Target | | --- | --- | --- | | `optimus-cli--linux-x64.tar.gz` | `optimus` | 64-bit Linux | | `optimus-cli--win-x64.tar.gz` | `optimus.exe` | 64-bit Windows | | `optimus-cli--osx-x64.tar.gz` | `optimus` | macOS on Intel | | `optimus-cli--osx-arm64.tar.gz` | `optimus` | macOS on Apple Silicon | Each package also includes: ```text optimus-cli--.sha256 manifest.json ``` Use the checksum file to verify the downloaded archive when your installation process requires integrity checks. Do not use a package for a different runtime. For example, the `linux-x64` package will not run on Windows, and the `osx-x64` package is not the Apple Silicon package. ## Network Requirements The CLI requires outgoing HTTPS access on port `443` to the Optimus API host selected for the run. | Environment | Host | | --- | --- | | Production | `app.optimussoftware.de` | | Test | `dev.app.optimussoftware.de` | If a firewall, allowlist, or proxy is used, allow the host for the environment you run against. When `--base-url` or `OPTIMUS_BASE_URL` is set, allow the custom host instead. The CLI uses the standard .NET HTTP stack. In typical environments, proxy behavior follows the operating system or environment proxy configuration. ## Updating When Optimus provides a newer CLI version, replace the installed binary or package and verify the version again: ```bash optimus --version ``` If a command example from these docs does not work with your installed version, check the installed version first. --- # Authentication Source: docs-site/docs/cli/authentication.md URL: /cli/authentication Real validation runs require a bearer token. Dry runs do not call the API and do not require a token. ## Create A Token The CLI uses the same Personal Access Tokens as the Integration API. In the Optimus web app: 1. Open **Settings**. 2. Select the **API Interface** tab. 3. In **API Tokens**, click **Create Token**. 4. Enter a descriptive **Token Name**, such as `Nightly customer VAT check`. 5. Optionally add **Allowed IP ranges** for the machine or network that will run the CLI. 6. Click **Create Token**. 7. Copy the token immediately. The token secret is only shown once. After creation, Optimus shows the token prefix and masked characters, but not the full secret. Allowed IP ranges accept exact IPv4 addresses and IPv4 CIDR ranges. Leave the field empty only when the token may be used from any IP address. ## Configure The Token Set the token with `OPTIMUS_TOKEN`: ```bash export OPTIMUS_TOKEN="" ``` Or pass it directly: ```bash optimus check customers.csv --map mapping.yml --standard --token "" ``` The environment variable is preferred because it avoids putting the token directly in command history. Do not include real `tok_optimus_` token values in scripts committed to source control, screenshots, support tickets, or documentation examples. ## API Target The CLI resolves the API target in this order: 1. `--base-url` 2. `OPTIMUS_BASE_URL` 3. `--env` or `OPTIMUS_ENV` 4. Production URL Use the production API: ```bash optimus check customers.csv --map mapping.yml --standard --env prod ``` Production uses: ```text https://app.optimussoftware.de/ ``` Use the test API: ```bash optimus check customers.csv --map mapping.yml --standard --env test ``` Test uses: ```text https://dev.app.optimussoftware.de/ ``` Override the full base URL: ```bash optimus check customers.csv --map mapping.yml --standard --base-url "https://example.test/" ``` `--base-url` must be an absolute URL. ## Authentication Errors | Message | Meaning | Fix | | --- | --- | --- | | `No token configured. Set --token or the OPTIMUS_TOKEN environment variable.` | The command would call the API but no token was available. | Set `OPTIMUS_TOKEN` or pass `--token`. | | `Token is invalid or expired.` | The API rejected the token. | Create a new token in **Settings > API Interface > API Tokens** and update the CLI environment. | | `Token is invalid or expired.` | The token is restricted to allowed IP ranges and the CLI is running from another IP address. | Edit the token IP ranges or create a token for the machine running the CLI. | | `Quota exhausted. Please check your license.` | The account does not have remaining entitlement for the request. | Check license and quota. | Support logs do not write tokens. --- # Check Command Source: docs-site/docs/cli/commands/check.md URL: /cli/commands/check `optimus check` validates VAT IDs from a CSV file or from a folder. ## Syntax ```bash optimus check [options] ``` `` is required. It can point to: - A CSV file for single-file mode. - A folder for folder mode. ## Examples Validate one CSV file with a mapping file: ```bash optimus check customers.csv --map mapping.yml --standard ``` Run a qualified check and request a PDF report: ```bash optimus check customers.csv --map mapping.yml --qualified --pdf ``` Run without a mapping file by naming the VAT ID column directly: ```bash optimus check customers.csv --col-vat-id VatId --standard --token "" ``` Process a folder: ```bash optimus check C:\inbox\ --map mapping.yml ``` Validate parsing and mapping without calling the API: ```bash optimus check customers.csv --map mapping.yml --standard --dry-run ``` Dry-run output includes a preview of the first 5 checkable rows that would be sent to the API. It does not create support logs. ## Arguments | Argument | Description | | --- | --- | | `` | Path to a CSV file or folder. | ## Options | Option | Value | Default | Description | | --- | --- | --- | --- | | `--map` | Path | not set | Path to the YAML mapping file. | | `--out` | Path | `_result.csv` in single-file mode | Path to the result CSV. Single-file mode only. | | `--token` | String | `OPTIMUS_TOKEN` | Bearer token for API calls. | | `--env` | `test` or `prod` | `prod` | API environment, unless a base URL is set. | | `--base-url` | Absolute URL | depends on environment | Full API base URL override. | | `--col-vat-id` | Column name or index | not set | Column containing VAT IDs. Required unless mapped in YAML. | | `--col-name` | Column name or index | not set | Company name column. | | `--col-street` | Column name or index | not set | Street column. | | `--col-zip` | Column name or index | not set | Postal code column. | | `--col-city` | Column name or index | not set | City column. | | `--in-delimiter` | String | auto-detected or YAML | Input CSV delimiter. | | `--in-encoding` | `utf-8`, `windows-1252`, `iso-8859-1` | `utf-8` | Input CSV encoding. | | `--no-header` | Flag | false | Treat mappings as 1-based column indexes instead of header names. | | `--skip-rows` | Number | `0` | Rows to skip before reading the header or records. | | `--out-delimiter` | String | input delimiter or `;` | Result CSV delimiter. | | `--out-encoding` | `utf-8`, `windows-1252`, `iso-8859-1` | `utf-8` | Result CSV encoding. | | `--no-bom` | Flag | false | Write output without a BOM. | | `--out-columns` | Comma-separated list | default result columns | Select result CSV columns. | | `--pdf` | Flag | false | Request a PDF report. | | `--no-pdf` | Flag | false | Disable PDF output even when YAML enables it. | | `--sign` | Flag | false | Digitally sign the PDF. Requires PDF output. | | `--no-sign` | Flag | false | Disable signing even when YAML enables it. | | `--pdf-dir` | Path | output directory or input directory | Folder for saved PDFs. | | `--pdf-timestamp` | Flag | false | Add timestamp to PDF file names. | | `--transliteration` | Flag | false | Enable transliteration for the validation request. | | `--notify` | Flag | false | Ask the API to send a notification email. | | `--email-pdf` | Flag | false | Ask the API to send the PDF by email. Requires PDF output. | | `--company-vat-id` | VAT ID | not set | Own VAT ID used for validation. | | `--standard` | Flag | not set | Request standard verification. | | `--qualified` | Flag | not set | Request qualified verification. | | `--retry-duration` | Duration | `None` | Retry duration: `None`, `OneHour`, `TwoHours`, `FourHours`, `EightHours`, `TwentyFourHours`. | | `--force-new` | Flag | false | Start a new validation operation and replace saved resume state. | | `--dry-run` | Flag | false | Validate file and mapping, print the first 5 checkable API rows, do not create support logs, and do not call the API. | | `--pattern` | Glob | `*.csv` | File pattern for folder mode. | | `--min-age` | Seconds | `0` | Minimum file age before folder mode picks up a file. | | `--on-duplicate` | `skip`, `overwrite`, `rename` | `skip` | Duplicate file handling for folder mode moves. | | `--retry` | Flag | false | Retry files that previously moved to the folder-mode `error` directory. | | `-v`, `--verbose` | Flag | false | Show detailed output. | | `-q`, `--quiet` | Flag | false | Only print errors. | | `--log-dir` | Path | mode-specific `logs` folder | Folder for support logs. | | `--no-log` | Flag | false | Disable the support log for this run. | ## Validation Rules - `` is required. - `--env` must be `test` or `prod`. - `--verbose` and `--quiet` cannot be used together. - `--sign` requires PDF output and cannot be used with `--no-pdf`. - `--standard` and `--qualified` cannot be used together. - A check type is required through `--standard`, `--qualified`, or `defaults.checkType` in the mapping file. - `vatId` must be mapped through `--col-vat-id` or `columns.vatId`. - `--out` is not accepted in folder mode. --- # Mapping File Source: docs-site/docs/cli/configuration/mapping-file.md URL: /cli/configuration/mapping-file The mapping file is a YAML file passed with `--map`. It tells the CLI which CSV columns to read and which defaults to apply. ## Minimal Mapping ```yaml columns: vatId: "VatId" defaults: checkType: standard ``` `columns.vatId` is required. The check type is also required, either in YAML or on the command line. ## Full Example ```yaml columns: vatId: "VatId" name: "CompanyName" street: "Street" zip: "PostalCode" city: "City" customColumns: customer_number: "CustomerNumber" cost_center: "CostCenter" input: delimiter: ";" encoding: "utf-8" hasHeader: true skipRows: 0 quoteChar: "\"" trimWhitespace: true output: delimiter: ";" encoding: "utf-8" bom: true columns: - row - customer_number - vat_id - vat_id_status - checked_at defaults: checkType: standard retryDuration: None pdf: false sign: false transliteration: false notify: false sendPdfByEmail: false filter: skipEmptyVatId: true folder: pattern: "*.csv" minAge: 0 onDuplicate: skip retry: false ``` ## Top-Level Keys | Key | Type | Default | Description | | --- | --- | --- | --- | | `columns` | Object | empty | API validation field mappings. | | `customColumns` | Object | empty | Local passthrough columns copied to the result CSV. | | `input` | Object | see below | Input CSV parsing options. | | `output` | Object | see below | Result CSV writing options. | | `defaults` | Object | see below | Default check and API options. | | `filter` | Object | see below | Row skip options. | | `folder` | Object | see below | Folder mode options. | ## `columns` | Key | Type | Default | Description | | --- | --- | --- | --- | | `vatId` | String | required | Input column containing the VAT ID. | | `name` | String | not set | Company name column. | | `street` | String | not set | Street column. | | `zip` | String | not set | Postal code column. | | `city` | String | not set | City column. | Use header names when the CSV has a header. Use 1-based column indexes when `--no-header` or `input.hasHeader: false` is used. ## `customColumns` `customColumns` maps result CSV column names to input CSV columns. ```yaml customColumns: customer_number: "CustomerNumber" ``` These values are copied into the result CSV. They are not sent to the API and do not affect resume hashes. Custom output names cannot be empty and cannot conflict with reserved result columns such as `vat_id_status`. ## `input` | Key | Type | Default | Description | | --- | --- | --- | --- | | `delimiter` | String | auto-detected | Input CSV delimiter. If not configured by CLI or YAML, the CLI auto-detects it. | | `encoding` | String | `utf-8` | Supported values: `utf-8`, `windows-1252`, `iso-8859-1`. | | `hasHeader` | Boolean | `true` | Whether the CSV has a header row. | | `skipRows` | Number | `0` | Rows to skip before the header or records. | | `quoteChar` | Single character | `"` | Quote character used by the CSV parser. | | `trimWhitespace` | Boolean | `true` | Trim whitespace around parsed fields. | ## `output` | Key | Type | Default | Description | | --- | --- | --- | --- | | `delimiter` | String | `;` | Result CSV delimiter. | | `encoding` | String | `utf-8` | Supported values: `utf-8`, `windows-1252`, `iso-8859-1`. | | `bom` | Boolean | `true` | Write a BOM for the output encoding. | | `columns` | List | default result columns | Select result CSV columns or shortcuts. | ## `defaults` | Key | Type | Default | Description | | --- | --- | --- | --- | | `checkType` | `standard` or `qualified` | not set | Default check type. Required unless set by CLI option. | | `transliteration` | Boolean | `false` | Enable transliteration. | | `pdf` | Boolean | `false` | Request PDF output. | | `sign` | Boolean | `false` | Digitally sign the PDF. Requires PDF output. | | `pdfDir` | String | not set | Folder for saved PDFs. | | `pdfTimestamp` | Boolean | `false` | Add timestamp to PDF file names. | | `companyVatId` | String | not set | Own VAT ID used for validation. | | `notify` | Boolean | `false` | Ask the API to send a notification email. | | `sendPdfByEmail` | Boolean | `false` | Ask the API to send the PDF by email. Requires PDF output. | | `retryDuration` | Duration | `None` | `None`, `OneHour`, `TwoHours`, `FourHours`, `EightHours`, `TwentyFourHours`. | ## `filter` | Key | Type | Default | Description | | --- | --- | --- | --- | | `skipEmptyVatId` | Boolean | `true` | Skip rows where the VAT ID is empty. | | `skipPattern` | Regex string | not set | Skip rows where the VAT ID matches the regex. | Skipped rows are written to the result CSV with status `SKIPPED`. ## `folder` | Key | Type | Default | Description | | --- | --- | --- | --- | | `pattern` | Glob | `*.csv` | Files selected from the folder root. | | `minAge` | Number | `0` | Minimum file age in seconds before processing. | | `onDuplicate` | `skip`, `overwrite`, `rename` | `skip` | Duplicate file handling for folder mode moves. `skip` keeps the existing destination, `overwrite` replaces it, and `rename` keeps both files with a timestamp. | | `retry` | Boolean | `false` | Move failed CSV files from `error` back to the inbox for another attempt. Retried files start a new validation operation. | | `cleanupDoneAfterDays` | Number | not set | Delete old files and state files from `done`. | --- # CSV Input Source: docs-site/docs/cli/configuration/csv-input.md URL: /cli/configuration/csv-input The CLI reads CSV files with the mapping you provide through YAML or `--col-*` options. ## Header Mode By default, the CLI expects a header row and mappings use header names: ```yaml columns: vatId: "VatId" name: "CompanyName" ``` Example CSV: ```csv VatId;CompanyName;Street;PostalCode;City DE123456789;Example GmbH;Main Street 1;80331;Munich ``` The CLI validates that every mapped column exists in the header. ## No-Header Mode Use `--no-header` when the CSV has no header row: ```bash optimus check customers.csv --no-header --col-vat-id 1 --col-name 2 --standard ``` In no-header mode, mapped columns must be 1-based indexes: ```yaml columns: vatId: "1" name: "2" ``` Run `--dry-run` after changing no-header mappings. The preview shows the first 5 checkable rows that would be sent to the API, so you can confirm each index points to the expected value. ## Delimiters Set the input delimiter explicitly when needed: ```bash optimus check customers.csv --map mapping.yml --in-delimiter ";" ``` Or in YAML: ```yaml input: delimiter: ";" ``` When no delimiter is configured by CLI or YAML, the reader can auto-detect it. ## Encodings Supported input encodings are: - `utf-8` - `windows-1252` - `iso-8859-1` Set the encoding with: ```bash optimus check customers.csv --map mapping.yml --standard --in-encoding windows-1252 ``` Or: ```yaml input: encoding: windows-1252 ``` ## Skipping Rows Before The Header Use `--skip-rows` when the file has metadata rows before the header: ```bash optimus check customers.csv --map mapping.yml --standard --skip-rows 2 ``` YAML equivalent: ```yaml input: skipRows: 2 ``` ## Skipped Records By default, rows with empty VAT IDs are skipped: ```yaml filter: skipEmptyVatId: true ``` You can also skip VAT IDs that match a regular expression: ```yaml filter: skipPattern: "^TEST" ``` Skipped rows are still written to the result CSV with `vat_id_status` set to `SKIPPED`. ## Passthrough Columns Use `customColumns` for local values you want to keep in the result CSV: ```yaml customColumns: customer_number: "CustomerNumber" ``` Passthrough values are read before row skip filters, so skipped rows can still include your local identifiers in the result CSV. --- # Result CSV Source: docs-site/docs/cli/configuration/result-csv.md URL: /cli/configuration/result-csv The result CSV contains one row for each input row the CLI writes to output, including skipped rows. ## Default Output Path For `customers.csv`, the default single-file result path is: ```text customers_result.csv ``` Override it with: ```bash optimus check customers.csv --map mapping.yml --standard --out ./results/customers_checked.csv ``` In folder mode, result files are written to the folder's `results` directory. ## Default Columns When `output.columns` and `--out-columns` are not set, the CLI writes: 1. `row` 2. Configured custom columns in YAML order 3. Standard validation result columns Standard validation result columns are: ```text vat_id vat_id_status name name_status name_determined street street_status street_determined zip zip_status zip_determined city city_status city_determined checked_at ``` ## Selecting Columns Use `--out-columns`: ```bash optimus check customers.csv --map mapping.yml --standard --out-columns row,vat_id,vat_id_status,checked_at ``` Or YAML: ```yaml output: columns: - row - customer_number - vat_id - vat_id_status - checked_at ``` Custom columns must use the output name from `customColumns`, not the input CSV header. ## Column Shortcuts | Shortcut | Expands to | | --- | --- | | `all` | Default output: `row`, configured custom columns, and all standard result columns. | | `all_originals` | `row`, custom columns, `vat_id`, `name`, `street`, `zip`, `city`. | | `all_statuses` | `vat_id_status`, `name_status`, `street_status`, `zip_status`, `city_status`. | | `all_determined` | `name_determined`, `street_determined`, `zip_determined`, `city_determined`. | ## Status Values `vat_id_status` uses the record status returned by the API, for example: - `Valid` - `Invalid` - `Unavailable` For skipped rows, the CLI writes: - `SKIPPED` For request or response failures, the CLI can write: - `ERROR` - `TEMP_ERROR` Field status columns such as `name_status`, `street_status`, `zip_status`, and `city_status` use field match status values returned by the API, for example: - `Match` - `NoMatch` - `NotQueried` - `NotReturned` When the API returns a `NoMatch` field result with a correction value, the CLI writes the correction into the matching `*_determined` column. ## Output Encoding And Delimiter Set output format in YAML: ```yaml output: delimiter: ";" encoding: "utf-8" bom: true ``` Or through options: ```bash optimus check customers.csv --map mapping.yml --standard --out-delimiter ";" --out-encoding utf-8 --no-bom ``` If no output delimiter is set, the CLI uses the input delimiter. If that is also not set, it uses `;`. --- # Configuration Precedence Source: docs-site/docs/cli/configuration/precedence.md URL: /cli/configuration/precedence The CLI resolves configuration from command-line options, YAML, environment variables, and defaults. Command-line values take priority over mapping file values. The important rule is: the leftmost configured value wins. Environment variables are only supported for authentication and API target settings. ## General Rule For most check, CSV, output, PDF, filter, and folder settings: 1. Command-line option 2. YAML mapping file 3. Built-in default In short: ```text CLI flag -> YAML (--map) -> Default ``` Examples: - `--col-vat-id` overrides `columns.vatId`. - `--in-encoding` overrides `input.encoding`. - `--pdf` enables PDF even if `defaults.pdf` is false. - `--no-pdf` disables PDF even if `defaults.pdf` is true. - `--no-sign` disables signing even if `defaults.sign` is true. ## Recommended Usage Put fixed settings in the YAML mapping file: - CSV delimiter and encoding. - Column mapping. - Output column selection. - PDF defaults. - Folder mode settings such as pattern, minimum file age, and duplicate mode. Use command-line flags for one-off changes: - `--env test` - `--base-url` - `--out` - `--dry-run` - `--force-new` - `-v` or `--verbose` This keeps automated jobs repeatable while still letting you override behavior for a specific run. ## Authentication Token resolution: 1. `--token` 2. `OPTIMUS_TOKEN` 3. empty value Real API runs fail when the final token is empty. Dry runs do not require a token. ## API Target API target resolution: 1. `--base-url` 2. `OPTIMUS_BASE_URL` 3. `--env` 4. `OPTIMUS_ENV` 5. Production URL `--env` and `OPTIMUS_ENV` support: - `test` - `prod` For API target settings, the effective priority is: ```text CLI flag -> Environment variable -> Default ``` YAML does not currently define token, environment, or base URL values. ## Check Type Check type resolution: 1. `--standard` 2. `--qualified` 3. `defaults.checkType` The final value must be `Standard` or `Qualified`. The CLI accepts lowercase YAML values such as `standard` and `qualified`. ## Retry Duration Retry duration resolution: 1. `--retry-duration` 2. `defaults.retryDuration` 3. `None` Accepted values are: - `None` - `OneHour` - `TwoHours` - `FourHours` - `EightHours` - `TwentyFourHours` The CLI also normalizes short forms such as `1h`, `2h`, `4h`, `8h`, and `24h`. ## Output Columns Output column resolution: 1. `--out-columns` 2. `output.columns` 3. Default output columns Unknown output columns cause a configuration error unless the column is defined under `customColumns`. --- # Dry Run Source: docs-site/docs/cli/workflows/dry-run.md URL: /cli/workflows/dry-run Dry-run mode reads the CSV and validates the mapping without sending data to the API. It also prints a bounded preview of the first 5 checkable rows that would be sent to the API. Use it when: - You create a new mapping file. - A customer sends a new CSV layout. - You change delimiters, encodings, headers, or skipped rows. - You want to verify that mapped columns exist before using quota. - You want to confirm that `--no-header` or `input.hasHeader: false` index mappings select the expected values. ## Command ```bash optimus check customers.csv --map mapping.yml --standard --dry-run ``` Dry-run mode still requires a valid check type, so pass `--standard`, `--qualified`, or set `defaults.checkType` in YAML. ## What It Checks Dry-run mode checks: - The input path. - The YAML file can be loaded. - YAML values are valid. - Required configuration is present. - Mapped columns exist in the CSV header. - No-header mappings use valid 1-based indexes. - Rows can be read. - Skip filters can be applied. ## API Preview After validation, dry-run mode prints the first 5 checkable rows that would be sent to the API. The preview is shown after skip filters are applied, so skipped rows are not included. It contains the API input fields: - Source row number. - VAT ID. - Company name. - Street. - ZIP. - City. Example: ```text First 2 rows that would be sent to the API Row | VAT ID | Company | Street | ZIP | City 1 | DE123456789 | Acme GmbH | Main Street 1 | 10115 | Berlin 2 | DE987654321 | Beta GmbH | Side Street 2 | 80331 | Munich No API call executed (dry-run). ``` The preview is terminal output only. Dry-run mode does not create a support log. Use `--quiet` to suppress normal dry-run output and print only errors. ## What It Does Not Do Dry-run mode does not: - Require a token. - Call the API. - Create validation operations. - Create saved validation state. - Create support logs. - Download PDFs. - Write a result CSV. - In folder mode, create mailbox folders, retry files from `error/`, move files to `processing/`, `done/`, or `error/`, write `.err` files, or clean up old `done/` files. ## Typical Flow ```bash export OPTIMUS_TOKEN="" optimus check customers.csv --map mapping.yml --standard --dry-run optimus check customers.csv --map mapping.yml --standard ``` --- # Folder Mode Source: docs-site/docs/cli/workflows/folder-mode.md URL: /cli/workflows/folder-mode Folder mode processes CSV files from a folder using a mailbox-style structure. Run folder mode by passing a directory as ``: ```bash optimus check ./inbox --map mapping.yml --standard ``` ## Folder Structure The CLI creates these folders inside the folder you pass: ```text inbox/ processing/ done/ error/ results/ ``` Files are picked up from the root folder only, not from subdirectories. In `--dry-run`, folder mode reads matching files from the root folder in place. It does not create the mailbox folders, retry files from `error`, move files, write result or error files, clean up `done`, or create a support log. ## Processing Flow 1. The CLI creates `processing`, `done`, `error`, and `results` if they do not exist. 2. If `--retry` or `folder.retry: true` is set, failed CSV files from `error` are moved back to the root folder for another attempt. 3. The CLI selects files from the root folder using `pattern`. 4. Result files ending in `_result` are ignored. 5. Files younger than `minAge` seconds are ignored. 6. Each selected file is moved to `processing`. 7. The file is validated. 8. The result CSV is written to `results`. 9. Successful files and validation-error files move to `done`. 10. CLI, mapping, authentication, IO, temporary, or quota errors move the source file to `error` and create an `.err` file. ## Folder Options Command-line options: ```bash optimus check ./inbox --map mapping.yml --standard --pattern "*.csv" --min-age 30 ``` Retry files that previously moved to `error`: ```bash optimus check ./inbox --map mapping.yml --standard --retry ``` YAML options: ```yaml folder: pattern: "*.csv" minAge: 30 onDuplicate: skip retry: false cleanupDoneAfterDays: 30 ``` | Key | Default | Description | | --- | --- | --- | | `pattern` | `*.csv` | File pattern selected from the folder root. | | `minAge` | `0` | Minimum file age in seconds. | | `onDuplicate` | `skip` | What to do when moving a file would collide with an existing file in `done`, `error`, or the folder root during retry. See duplicate handling below. | | `retry` | `false` | Move failed CSV files from `error` back to the root folder for another attempt. Retried files start a new validation operation and replace their saved state. | | `cleanupDoneAfterDays` | not set | Delete old files and saved state from `done`. | ## Retrying Failed Files When a file fails because of a CLI, mapping, authentication, IO, temporary, or quota error, the CLI moves the source CSV to `error` and writes an `.err` file. After you fix the cause, run folder mode with `--retry` or set `folder.retry: true`. The CLI moves matching CSV files from `error` back to the root folder, removes the `.err` marker, and processes them again. Retry starts a new validation operation. It does not cancel any older remote operation. ## Duplicate Handling `onDuplicate` controls what happens when the CLI tries to move a CSV file and a file with the same name already exists at the destination: | Value | Behavior | | --- | --- | | `skip` | Keep the existing destination file. The current processed file stays in `processing` for manual review. During `--retry`, the failed file stays in `error`. | | `overwrite` | Replace the existing destination file and its `.optimus-state.json` sidecar. | | `rename` | Keep both files by adding a timestamp to the file being moved. | ## Result And Error Files For an input file named `customers.csv`, folder mode writes: ```text results/customers_result.csv ``` If a file cannot be processed, the CLI writes an error file: ```text error/customers.err ``` The `.err` file includes the source file name, exit code, timestamp, support log path when available, and a short error description. --- # PDF Reports Source: docs-site/docs/cli/workflows/pdf-reports.md URL: /cli/workflows/pdf-reports The CLI can request a PDF report from the API and save it after a completed validation operation. ## Request A PDF ```bash optimus check customers.csv --map mapping.yml --qualified --pdf ``` YAML default: ```yaml defaults: pdf: true ``` Disable PDF output even when YAML enables it: ```bash optimus check customers.csv --map mapping.yml --qualified --no-pdf ``` ## Signing Request a digitally signed PDF: ```bash optimus check customers.csv --map mapping.yml --qualified --pdf --sign ``` YAML default: ```yaml defaults: pdf: true sign: true ``` `--sign` requires PDF output. Use `--no-sign` to disable signing when YAML enables it. ## Save Location Set the PDF directory: ```bash optimus check customers.csv --map mapping.yml --qualified --pdf --pdf-dir ./pdf ``` YAML default: ```yaml defaults: pdfDir: ./pdf ``` When `pdfDir` is not set, the CLI saves PDFs: 1. In the output CSV directory when `--out` is set. 2. Otherwise in the input file directory. ## File Names The CLI uses the API-provided PDF file name when available. Otherwise it uses: ```text _report.pdf ``` Add a timestamp: ```bash optimus check customers.csv --map mapping.yml --qualified --pdf --pdf-timestamp ``` The timestamp format is: ```text yyyy-MM-dd_HHmmss ``` ## Email Options Ask the API to send a notification email: ```bash optimus check customers.csv --map mapping.yml --qualified --notify ``` Ask the API to send the PDF by email: ```bash optimus check customers.csv --map mapping.yml --qualified --pdf --email-pdf ``` `--email-pdf` requires PDF output. --- # Resume And Idempotency Source: docs-site/docs/cli/workflows/resume-and-idempotency.md URL: /cli/workflows/resume-and-idempotency Real validation runs create saved validation state next to the input CSV so interrupted runs can resume without starting duplicate API work. ## State File For: ```text customers.csv ``` The CLI writes: ```text customers.csv.optimus-state.json ``` The state file stores: - Request hash. - Idempotency key. - Operation ID when available. - Operation status. - Timestamps. - API base URL. - Result path. - PDF path. - Support log path. - Last general operation error when one occurs. The state file does not store tokens. ## Automatic Resume When the same file is processed again with the same relevant request options and API target, the CLI uses the saved state. In a non-interactive terminal, the CLI resumes automatically. In an interactive terminal, the CLI can ask whether to resume or start a new operation. ## Start A New Operation Use `--force-new` to ignore saved state and start a new validation operation: ```bash optimus check customers.csv --map mapping.yml --standard --force-new ``` When `--force-new` is used, the CLI creates a new idempotency key by appending a unique suffix. ## Idempotency Keys The CLI generates idempotency keys automatically from the validation request. Users do not need to create or pass these keys. This keeps retries and resume behavior tied to the exact CSV data, mapping, API target, and validation options used for the run. Folder mode generates one idempotency key per CSV file. ## When State Is Replaced The CLI starts a new operation when: - `--force-new` is passed. - The saved operation has expired. - The saved operation is no longer available from the API. - An interactive user confirms replacement for corrupt or mismatched state. If corrupt or mismatched state is found in a non-interactive run, the CLI reports an error and tells you to use `--force-new`. --- # Support Logs Source: docs-site/docs/cli/workflows/support-logs.md URL: /cli/workflows/support-logs `optimus check` writes one privacy-safe support log for every non-dry-run unless logging is disabled. Dry-run mode never creates a support log. ## Default Log Locations | Mode | Default log folder | | --- | --- | | Single-file mode | `/logs` | | Folder mode | `/logs` | | Missing path or early config error | `./logs` | Override the folder: ```bash optimus check customers.csv --map mapping.yml --standard --log-dir ./logs ``` Disable the support log: ```bash optimus check customers.csv --map mapping.yml --standard --no-log ``` ## File Name Log files are named like: ```text optimus-check-20260512T140000Z-a1b2c3d4.log ``` Each run also has a short run ID. ## What Logs Include Support logs can include: - Run ID. - Start time. - CLI version. - OS and .NET framework information. - Working directory. - Input path. - Mapping path. - Output path. - API target without query string or credentials. - Check type. - Flags such as quiet, verbose, PDF, signing, notification, and force-new. - Validation operation ID. - Idempotency key. - API statuses. - Result path. - PDF path. - Exit code. - General errors and stack traces for CLI errors. ## What Logs Do Not Include Support logs do not include: - Tokens. - Request bodies. - Response bodies. - CSV row values. - VAT IDs. - Company names. - Addresses. - Custom column values. If you contact support, include the support log path or the log file unless your internal policy says otherwise. --- # Exit Codes Source: docs-site/docs/cli/reference/exit-codes.md URL: /cli/reference/exit-codes Automation should use the process exit code to decide whether a run succeeded, failed permanently, or should be retried. | Exit code | Meaning | Typical handling | | --- | --- | --- | | `0` | Success, including runs with warnings. | Continue. Review result CSV when needed. | | `1` | CLI error: configuration, authentication, mapping, or IO problem. | Fix input, mapping, token, or paths before retrying. | | `2` | Validation error: at least one invalid row or response rows could not be matched. | Review result CSV. This is usually a completed business result, not an infrastructure retry. | | `3` | Temporary error: timeout, rate limit, server error, or `TEMP_ERROR`. | Retry later. | | `4` | Entitlement or quota exhausted. | Check license or quota before retrying. | ## API Error Mapping | API condition | Exit code | | --- | --- | | Connection timeout or connection error | `3` | | HTTP 400 | `1` | | HTTP 401 or 403 | `1` | | HTTP 402 | `4` | | HTTP 409 | `1` | | HTTP 429 | `3` | | HTTP 500 or higher | `3` | ## Result-Based Exit Codes After a result CSV is written: - Any `ERROR` row returns exit code `2`. - Any `Unavailable` or `TEMP_ERROR` row returns exit code `3` when there are no stronger errors. - Otherwise the command returns `0`. Folder mode returns the worst exit code from all files processed in that run. --- # Troubleshooting Source: docs-site/docs/cli/reference/troubleshooting.md URL: /cli/reference/troubleshooting Use this page to map common CLI messages to fixes. ## Configuration Errors | Message | Cause | Fix | | --- | --- | --- | | `Path is required.` | The command did not receive a file or folder path. | Pass `optimus check `. | | `Path not found: ...` | The path does not exist. | Check the path and working directory. | | `--env must be 'test' or 'prod'.` | The environment value is invalid. | Use `--env test` or `--env prod`. | | `--verbose and --quiet cannot be used together.` | Conflicting console output options. | Pick one option. | | `Check type is required...` | No check type was resolved. | Use `--standard`, `--qualified`, or `defaults.checkType`. | | `Column 'vatId' must be mapped...` | No VAT ID column was mapped. | Add `--col-vat-id` or `columns.vatId`. | | `--base-url must be an absolute URL.` | The URL is not absolute. | Use a full URL such as `https://example.test/`. | ## CSV And Mapping Errors | Message | Cause | Fix | | --- | --- | --- | | `Could not load YAML file...` | YAML is missing, unreadable, or invalid. | Check file path and YAML syntax. | | `Mapped column '...' was not found in the CSV header.` | Mapping references a header that does not exist. | Fix the header name or mapping file. | | `must be a 1-based column index when --no-header is used.` | No-header mode is using a name or invalid index. | Use `1`, `2`, `3`, and so on. | | `Unknown input encoding...` | Unsupported encoding. | Use `utf-8`, `windows-1252`, or `iso-8859-1`. | | `Unknown output encoding...` | Unsupported output encoding. | Use `utf-8`, `windows-1252`, or `iso-8859-1`. | | `Unknown output column...` | `output.columns` or `--out-columns` contains an unknown name. | Use a reserved output column, shortcut, or configured custom column. | | `Invalid regex in skipPattern...` | The filter regex is invalid. | Fix `filter.skipPattern`. | ## Authentication And API Errors | Message | Cause | Fix | | --- | --- | --- | | `No token configured...` | API run without a token. | Set `OPTIMUS_TOKEN` or use `--token`. | | `Token is invalid or expired.` | API rejected the token. | Create or request a new token. | | `Quota exhausted. Please check your license.` | API returned HTTP 402. | Check license or quota. | | `Rate limit reached. Please wait and try again.` | API returned HTTP 429. | Retry later. | | `Connection timeout...` | API did not respond in time. | Retry later or check network connectivity. | | `Server error (...)` | API returned HTTP 500 or higher. | Retry later. If it persists, contact support. | ## Resume State Problems | Message | Cause | Fix | | --- | --- | --- | | `Saved validation state does not match...` | The file, options, request hash, or API target changed. | Use `--force-new` if you want a new operation. | | `Saved validation state is unreadable...` | The state file is corrupt. | Use `--force-new` in an interactive run or remove the state file if appropriate. | | `Saved validation operation is no longer available...` | The API returned 404 for saved operation lookup. | The CLI starts a new operation automatically. | ## Folder Mode Problems | Symptom | Cause | Fix | | --- | --- | --- | | No files are processed. | No files match `pattern`, files are in subfolders, files end with `_result`, or files are younger than `minAge`. | Check folder root, file names, `pattern`, and `minAge`. | | File moved to `error`. | The file hit a CLI, mapping, authentication, IO, temporary, or quota error. | Open the `.err` file and support log, fix the cause, then run folder mode with `--retry`. | | File stays in `processing` with a duplicate destination message. | `onDuplicate` is `skip` and a file with the same name already exists in `done` or `error`. | Review the existing destination file. Then move/delete the processing file manually, or rerun with `--on-duplicate overwrite` or `--on-duplicate rename`. | | File stays in `processing`. | The run was interrupted while the file was being processed. | Make sure no CLI process is still running, then move the CSV and its `.optimus-state.json` sidecar back to the folder root before running folder mode again. | ## Support Logs When troubleshooting, run with verbose output and keep the support log: ```bash optimus check customers.csv --map mapping.yml --standard --verbose --log-dir ./logs ``` Support logs are designed not to contain tokens, CSV row values, VAT IDs, company names, addresses, or custom column values.