This is an automated email from the ASF dual-hosted git repository.

oscerd pushed a commit to branch camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-4.18.x by this push:
     new 5e6d0c947351 [backport camel-4.18.x] CAMEL-24422: camel-docling - make 
message body input-source interpretation explicit and configurable (#25744)
5e6d0c947351 is described below

commit 5e6d0c94735102e5ea9bc249dd27042cd9157cb8
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu Aug 27 06:40:17 2026 +0200

    [backport camel-4.18.x] CAMEL-24422: camel-docling - make message body 
input-source interpretation explicit and configurable (#25744)
    
    CAMEL-24422: camel-docling - make message body input-source interpretation 
explicit and configurable (#25596)
    
    DoclingProducer.getInputPath() decided what a String message body meant by
    inspecting its prefix: http:// or https:// was handed to Docling as a remote
    URL to fetch, a leading / or an embedded \ was read from the local 
filesystem,
    and anything else was converted as document content. The mode was chosen
    implicitly and the route author had no way to influence it.
    
    The two location readings are now opt-in:
    
    - allowUrlSource (default false) interprets a body starting with http:// or
      https:// as a URL.
    - allowFilePathSource (default false) interprets a body starting with / or
      containing \ as a local file path, including the single directory-or-file
      String body accepted by the batch operations.
    
    Refusing to interpret a body names the option that would enable it. A body
    that is neither a URL nor a path is still converted as content, unchanged.
    
    Only a bare String body is gated, because only it is ambiguous. The
    CamelDoclingInputFilePath header, File/byte[]/InputStream bodies and the
    explicit path collections used by the batch operations state their meaning
    already and keep working without an opt-in.
    
    A new inputBaseDirectory option bounds local input paths to a configured
    directory. It applies to the header, to file path bodies and to the batch
    paths, and covers all of them by resolving the path in one place. 
Containment
    normalizes lexically and compares on path-segment boundaries, so a sibling
    directory sharing a name prefix with the base is not accepted. When the base
    directory is set, relative paths resolve against it and the validated path 
is
    the one used downstream, so the path that was checked is the path that is 
read.
    
    The four independent copies of the http:// / https:// prefix test in
    getInputPath, addSourceToRequest, addSourceToChunkRequest and
    extractMetadataUsingApi now call a single isRemoteSource() helper, so new
    handling cannot be added to some of them and missed in others.
    
    validateFileSize is renamed to validateFileSizeIfPresent: it was wrapped in
    Files.exists() and so silently skipped a path that resolved to nothing, 
while
    reading at the call site as though a check had happened. Local input paths 
now
    go through validateLocalInputPath, which requires the path to exist and 
reports
    a missing one as File not found before Docling is invoked.
    
    Adds DoclingInputSourceValidationTest. The existing custom-argument test and
    the integration tests pass the input location in the body and have been 
updated
    to opt in, which is the same migration users perform.
    
    Signed-off-by: Andrea Cosentino <[email protected]>
    Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
---
 .../apache/camel/catalog/components/docling.json   |   22 +-
 .../camel/catalog/docs/docling-component.adoc      | 1330 ++++++++++++++++++++
 .../docling/DoclingComponentConfigurer.java        |   18 +
 .../docling/DoclingConfigurationConfigurer.java    |   18 +
 .../docling/DoclingEndpointConfigurer.java         |   18 +
 .../docling/DoclingEndpointUriFactory.java         |    5 +-
 .../apache/camel/component/docling/docling.json    |   22 +-
 .../src/main/docs/docling-component.adoc           |   49 +-
 .../component/docling/DoclingConfiguration.java    |   47 +
 .../camel/component/docling/DoclingProducer.java   |  127 +-
 .../docling/DoclingCustomArgsValidationTest.java   |    5 +-
 .../docling/DoclingInputSourceValidationTest.java  |  263 ++++
 .../integration/DoclingServeProducerIT.java        |   22 +-
 .../integration/ExtractStructuredDataIT.java       |    2 +-
 .../docling/integration/MetadataExtractionIT.java  |   12 +-
 .../docling/integration/OcrExtractionIT.java       |    8 +-
 .../dsl/DoclingComponentBuilderFactory.java        |   62 +
 .../dsl/DoclingEndpointBuilderFactory.java         |   91 ++
 18 files changed, 2064 insertions(+), 57 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/docling.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/docling.json
index 26a362b9f4f9..74e1c6949942 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/docling.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/docling.json
@@ -66,10 +66,13 @@
     "splitBatchResults": { "index": 39, "kind": "property", "displayName": 
"Split Batch Results", "group": "batch", "label": "batch", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Split batch results into 
individual exchanges (one per do [...]
     "includeMetadataInHeaders": { "index": 40, "kind": "property", 
"displayName": "Include Metadata In Headers", "group": "metadata", "label": 
"metadata", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Include metadata in 
message headers w [...]
     "includeRawMetadata": { "index": 41, "kind": "property", "displayName": 
"Include Raw Metadata", "group": "metadata", "label": "metadata", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Include raw metadata as 
returned by the parser" },
-    "apiKeyHeader": { "index": 42, "kind": "property", "displayName": "Api Key 
Header", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"X-API-Key", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Header name for API key 
authentication" },
-    "authenticationScheme": { "index": 43, "kind": "property", "displayName": 
"Authentication Scheme", "group": "security", "label": "security", "required": 
false, "type": "enum", "javaType": 
"org.apache.camel.component.docling.AuthenticationScheme", "enum": [ "NONE", 
"BEARER", "API_KEY" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "NONE", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", "configuration [...]
-    "authenticationToken": { "index": 44, "kind": "property", "displayName": 
"Authentication Token", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": true, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Authentication token for 
docling-serve API (Bearer token or API  [...]
-    "maxFileSize": { "index": 45, "kind": "property", "displayName": "Max File 
Size", "group": "security", "label": "security", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": 52428800, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Maximum file size in 
bytes for processing" }
+    "allowFilePathSource": { "index": 42, "kind": "property", "displayName": 
"Allow File Path Source", "group": "security", "label": "security", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Whether a String message 
body that starts with [...]
+    "allowUrlSource": { "index": 43, "kind": "property", "displayName": "Allow 
Url Source", "group": "security", "label": "security", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Whether a String message 
body that starts with http:\/\/  [...]
+    "apiKeyHeader": { "index": 44, "kind": "property", "displayName": "Api Key 
Header", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"X-API-Key", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Header name for API key 
authentication" },
+    "authenticationScheme": { "index": 45, "kind": "property", "displayName": 
"Authentication Scheme", "group": "security", "label": "security", "required": 
false, "type": "enum", "javaType": 
"org.apache.camel.component.docling.AuthenticationScheme", "enum": [ "NONE", 
"BEARER", "API_KEY" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "NONE", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", "configuration [...]
+    "authenticationToken": { "index": 46, "kind": "property", "displayName": 
"Authentication Token", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": true, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Authentication token for 
docling-serve API (Bearer token or API  [...]
+    "inputBaseDirectory": { "index": 47, "kind": "property", "displayName": 
"Input Base Directory", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "When set, every local 
input file path must resolve inside this d [...]
+    "maxFileSize": { "index": 48, "kind": "property", "displayName": "Max File 
Size", "group": "security", "label": "security", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": 52428800, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Maximum file size in 
bytes for processing" }
   },
   "headers": {
     "CamelDoclingOperation": { "index": 0, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": 
"DoclingOperations", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The operation to perform", 
"constantName": "org.apache.camel.component.docling.DoclingHeaders#OPERATION" },
@@ -143,9 +146,12 @@
     "splitBatchResults": { "index": 38, "kind": "parameter", "displayName": 
"Split Batch Results", "group": "batch", "label": "batch", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Split batch results into 
individual exchanges (one per d [...]
     "includeMetadataInHeaders": { "index": 39, "kind": "parameter", 
"displayName": "Include Metadata In Headers", "group": "metadata", "label": 
"metadata", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Include metadata in 
message headers  [...]
     "includeRawMetadata": { "index": 40, "kind": "parameter", "displayName": 
"Include Raw Metadata", "group": "metadata", "label": "metadata", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Include raw metadata as 
returned by the parser" },
-    "apiKeyHeader": { "index": 41, "kind": "parameter", "displayName": "Api 
Key Header", "group": "security", "label": "security", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"X-API-Key", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Header name for API key 
authentication" },
-    "authenticationScheme": { "index": 42, "kind": "parameter", "displayName": 
"Authentication Scheme", "group": "security", "label": "security", "required": 
false, "type": "enum", "javaType": 
"org.apache.camel.component.docling.AuthenticationScheme", "enum": [ "NONE", 
"BEARER", "API_KEY" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "NONE", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", "configuratio [...]
-    "authenticationToken": { "index": 43, "kind": "parameter", "displayName": 
"Authentication Token", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": true, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Authentication token for 
docling-serve API (Bearer token or API [...]
-    "maxFileSize": { "index": 44, "kind": "parameter", "displayName": "Max 
File Size", "group": "security", "label": "security", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "defaultValue": 52428800, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Maximum file size in 
bytes for processing" }
+    "allowFilePathSource": { "index": 41, "kind": "parameter", "displayName": 
"Allow File Path Source", "group": "security", "label": "security", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Whether a String message 
body that starts wit [...]
+    "allowUrlSource": { "index": 42, "kind": "parameter", "displayName": 
"Allow Url Source", "group": "security", "label": "security", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Whether a String message 
body that starts with http:\/\/ [...]
+    "apiKeyHeader": { "index": 43, "kind": "parameter", "displayName": "Api 
Key Header", "group": "security", "label": "security", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"X-API-Key", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Header name for API key 
authentication" },
+    "authenticationScheme": { "index": 44, "kind": "parameter", "displayName": 
"Authentication Scheme", "group": "security", "label": "security", "required": 
false, "type": "enum", "javaType": 
"org.apache.camel.component.docling.AuthenticationScheme", "enum": [ "NONE", 
"BEARER", "API_KEY" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "NONE", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", "configuratio [...]
+    "authenticationToken": { "index": 45, "kind": "parameter", "displayName": 
"Authentication Token", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": true, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Authentication token for 
docling-serve API (Bearer token or API [...]
+    "inputBaseDirectory": { "index": 46, "kind": "parameter", "displayName": 
"Input Base Directory", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "When set, every local 
input file path must resolve inside this  [...]
+    "maxFileSize": { "index": 47, "kind": "parameter", "displayName": "Max 
File Size", "group": "security", "label": "security", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "defaultValue": 52428800, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Maximum file size in 
bytes for processing" }
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/docling-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/docling-component.adoc
new file mode 100644
index 000000000000..0aef255d2be8
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/docling-component.adoc
@@ -0,0 +1,1330 @@
+= Docling Component
+:doctitle: Docling
+:shortname: docling
+:artifactid: camel-docling
+:description: Process documents using Docling library for parsing and 
conversion.
+:since: 4.15
+:supportlevel: Stable
+:tabs-sync-option:
+:component-header: Only producer is supported
+//Manually maintained attributes
+:group: AI
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The Docling component allows you to convert and process documents using 
https://github.com/DS4SD/docling[IBM's Docling AI document parser].
+Docling is a powerful Python library that can parse and convert various 
document formats including PDF, Word documents, PowerPoint presentations, and 
more into structured formats like Markdown, HTML, JSON, or plain text.
+
+Maven users will need to add the following dependency to their `pom.xml` for 
this component:
+
+[source,xml]
+----
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-docling</artifactId>
+    <version>x.x.x</version>
+    <!-- use the same version as your Camel core version -->
+</dependency>
+----
+
+== Prerequisites
+
+This component supports two modes of operation:
+
+1. **CLI Mode (default)**: Requires Docling to be installed on your system via 
pip:
++
+[source,bash]
+----
+pip install docling
+----
+
+2. **API Mode**: Requires a running docling-serve instance. The component uses 
the official https://github.com/docling-project/docling-java[docling-java] 
library for communication with docling-serve, providing robust API integration 
with native async support. You can run docling-serve using:
++
+[source,bash]
+----
+# Install docling-serve
+pip install docling-serve
+
+# Run docling-serve
+docling-serve --host 0.0.0.0 --port 5001
+----
++
+Or using Docker:
++
+[source,bash]
+----
+docker run -p 5001:5001 ghcr.io/docling-project/docling-serve:latest
+----
+
+== URI format
+
+----
+docling:operation[?options]
+----
+
+Where `operation` represents the document processing operation to perform.
+
+=== Supported Operations
+
+The component supports the following operations:
+
+[width="100%",cols="2,4",options="header"]
+|===
+| Operation | Description
+
+| `CONVERT_TO_MARKDOWN`
+| Convert document to Markdown format (default)
+
+| `CONVERT_TO_HTML`
+| Convert document to HTML format
+
+| `CONVERT_TO_JSON`
+| Convert document to JSON format. Returns a `DoclingDocument` object 
(`ai.docling.core.DoclingDocument`) in both API and CLI modes.
+
+| `EXTRACT_TEXT`
+| Extract plain text content from document
+
+| `EXTRACT_STRUCTURED_DATA`
+| Extract structured data with table structure recognition enabled by default. 
Returns a `DoclingDocument` object in both API and CLI modes. Additional 
enrichment features (code, formula, picture classification) can be enabled via 
configuration.
+
+| `EXTRACT_METADATA`
+| Extract document metadata (title, author, page count, creation date, etc.)
+
+| `SUBMIT_ASYNC_CONVERSION`
+| Submit an async conversion and return task ID (docling-serve only)
+
+| `CHECK_CONVERSION_STATUS`
+| Check the status of an async conversion task (docling-serve only)
+
+| `CHUNK_HYBRID`
+| Chunk document using HybridChunker — token-aware and structure-aware 
(docling-serve only)
+
+| `CHUNK_HIERARCHICAL`
+| Chunk document using HierarchicalChunker — structure-aware (docling-serve 
only)
+
+|===
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+include::partial$component-endpoint-headers.adoc[]
+// component options: END
+
+== Usage
+
+=== Input Types
+
+The component accepts the following input types in the message body:
+
+- `String` - Document content. It is only read as a location when the endpoint 
opts in - see <<_input_sources>> below
+- `byte[]` - Binary document content
+- `File` - File object
+- `InputStream` - Input stream containing document data
+
+For the batch operations the body may also be a `List<String>` or `String[]` 
of file paths, a `List<File>`
+or `File[]`, or a single directory path `String`.
+
+[#_input_sources]
+=== Input Sources
+
+A `String` body is ambiguous: it could be the document itself, a URL to fetch, 
or a path to read. By default
+the component treats it as the document, and the two location readings must be 
enabled explicitly:
+
+[cols="1,1,3", options="header"]
+|===
+| Option | Default | Effect when enabled
+
+| `allowUrlSource`
+| `false`
+| A body starting with `http://` or `https://` is handed to Docling as a 
remote URL to fetch.
+
+| `allowFilePathSource`
+| `false`
+| A body starting with `/`, or containing `\`, is read from the local 
filesystem. This also covers the single
+directory-or-file `String` body accepted by the batch operations.
+
+| `inputBaseDirectory`
+| _(none)_
+| When set, every local input path must resolve inside this directory once 
normalized. Applies to the
+`CamelDoclingInputFilePath` header, to file path bodies, and to the paths used 
by the batch operations.
+|===
+
+With both options left at their defaults, a body that is neither a URL nor a 
path is written to a temporary
+file and converted as document content, exactly as before.
+
+The `CamelDoclingInputFilePath` header is an explicit "the document lives 
here" signal from the route, so it
+keeps working without `allowFilePathSource`. It is still subject to 
`inputBaseDirectory` when one is set.
+Typed bodies - `File`, `byte[]`, `InputStream`, and the explicit path 
collections used by the batch
+operations - are unambiguous and are likewise unaffected.
+
+[source,java]
+----
+// the body is the document itself - no opt-in needed
+from("direct:content")
+    .to("docling:convert?operation=CONVERT_TO_MARKDOWN");
+
+// the body is a path, confined to /var/docs
+from("direct:paths")
+    
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&allowFilePathSource=true&inputBaseDirectory=/var/docs");
+----
+
+=== Output Behavior
+
+The component behavior depends on the `contentInBody` configuration option:
+
+- When `contentInBody=true` (default: false): The converted content is placed 
in the exchange body and the output file is automatically deleted
+- When `contentInBody=false`: The file path to the generated output file is 
returned in the exchange body
+
+== Examples
+
+=== Basic document conversion to Markdown
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:CONVERT_TO_MARKDOWN")
+    .to("file:///data/output");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:CONVERT_TO_MARKDOWN
+      - to:
+          uri: file:///data/output
+----
+====
+
+=== Convert to HTML with content in body
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:CONVERT_TO_HTML?contentInBody=true")
+    .process(exchange -> {
+        String htmlContent = exchange.getIn().getBody(String.class);
+        // Process the HTML content
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:CONVERT_TO_HTML
+          parameters:
+            contentInBody: true
+      - process:
+          ref: "htmlProcessor"
+----
+====
+
+=== Extract structured data from documents
+
+When using docling-serve API mode, `EXTRACT_STRUCTURED_DATA` returns a 
`DoclingDocument` object with table structure recognition enabled by default. 
In CLI mode, the JSON output is parsed into a `DoclingDocument`.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    
.to("docling:EXTRACT_STRUCTURED_DATA?useDoclingServe=true&contentInBody=true")
+    .process(exchange -> {
+        DoclingDocument doc = exchange.getIn().getBody(DoclingDocument.class);
+
+        // Access tables extracted from the document
+        List<DoclingDocument.TableItem> tables = doc.getTables();
+        for (DoclingDocument.TableItem table : tables) {
+            DoclingDocument.TableData data = table.getData();
+            log.info("Table: {}x{}", data.getNumRows(), data.getNumCols());
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:EXTRACT_STRUCTURED_DATA
+          parameters:
+            useDoclingServe: true
+            contentInBody: true
+      - process:
+          ref: "structuredDataProcessor"
+----
+====
+
+=== Convert with OCR disabled
+
+In CLI mode, use `enableOCR=false`. In API mode, setting `enableOCR=false` 
sends `doOcr(false)` to the server. You can also use the `doOcr` property 
directly for API mode control.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+// CLI mode
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:CONVERT_TO_MARKDOWN?enableOCR=false")
+    .to("file:///data/output");
+
+// API mode
+from("file:///data/documents?include=.*\\.pdf")
+    
.to("docling:CONVERT_TO_MARKDOWN?useDoclingServe=true&doOcr=false&contentInBody=true")
+    .to("file:///data/output");
+----
+
+YAML::
++
+[source,yaml]
+----
+# CLI mode
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:CONVERT_TO_MARKDOWN
+          parameters:
+            enableOCR: false
+      - to:
+          uri: file:///data/output
+
+# API mode
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:CONVERT_TO_MARKDOWN
+          parameters:
+            useDoclingServe: true
+            doOcr: false
+            contentInBody: true
+      - to:
+          uri: file:///data/output
+----
+====
+
+=== OCR and page headers/footers
+
+Docling recognizes page headers and footers (page numbers, copyright lines, 
running titles, footnotes, and similar
+content) during OCR, classifying them as page _furniture_ in docling's 
`FURNITURE` content layer.
+
+Since docling v1.30.0, page furniture (headers and footers) is included in the 
default body export (Markdown, text
+and HTML). Earlier versions excluded the `FURNITURE` layer, so header and 
footer text was omitted from the converted
+output even though the OCR engine read it correctly.
+
+=== Using headers to control processing
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .setHeader("CamelDoclingOperation", 
constant(DoclingOperations.CONVERT_TO_HTML))
+    .setHeader("CamelDoclingEnableOCR", constant(true))
+    .setHeader("CamelDoclingOCRLanguage", constant("es"))
+    .to("docling:CONVERT_TO_MARKDOWN")  // Operation will be overridden by 
header
+    .to("file:///data/output");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - setHeader:
+          name: "CamelDoclingOperation"
+          constant: "CONVERT_TO_HTML"
+      - setHeader:
+          name: "CamelDoclingEnableOCR"
+          constant: true
+      - setHeader:
+          name: "CamelDoclingOCRLanguage"
+          constant: "es"
+      - to:
+          uri: docling:CONVERT_TO_MARKDOWN  # Operation will be overridden by 
header
+      - to:
+          uri: file:///data/output
+----
+====
+
+=== Processing with custom arguments
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .process(exchange -> {
+        List<String> customArgs = Arrays.asList("--verbose", 
"--preserve-tables");
+        exchange.getIn().setHeader("CamelDoclingCustomArguments", customArgs);
+    })
+    .to("docling:CONVERT_TO_MARKDOWN")
+    .to("file:///data/output");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - setHeader:
+          name: "CamelDoclingCustomArguments"
+          expression:
+            method:
+              ref: "customArgsBean"
+              method: "createCustomArgs"
+      - to:
+          uri: docling:CONVERT_TO_MARKDOWN
+      - to:
+          uri: file:///data/output
+----
+====
+
+=== Custom argument validation
+
+When passing custom CLI arguments via the `CamelDoclingCustomArguments` 
header, the component enforces an **allowlist** of recognized docling CLI flags.
+Only the following flags are permitted:
+
+[width="100%",cols="2,4",options="header"]
+|===
+| Category | Allowed flags
+
+| Input/output format
+| `--from`, `--to`
+
+| Pipeline
+| `--pipeline`, `--vlm-model`, `--asr-model`
+
+| OCR
+| `--ocr`, `--no-ocr`, `--force-ocr`, `--no-force-ocr`, `--ocr-engine`, 
`--ocr-lang`, `--psm`
+
+| Tables
+| `--tables`, `--no-tables`, `--table-mode`
+
+| PDF
+| `--pdf-backend`, `--pdf-password`
+
+| Enrichment
+| `--enrich-code`, `--no-enrich-code`, `--enrich-formula`, 
`--no-enrich-formula`, `--enrich-picture-classes`, 
`--no-enrich-picture-classes`, `--enrich-picture-description`, 
`--no-enrich-picture-description`, `--enrich-chart-extraction`, 
`--no-enrich-chart-extraction`
+
+| Output formatting
+| `--image-export-mode`, `--show-layout`, `--no-show-layout`
+
+| Advanced
+| `--headers`, `--artifacts-path`, `--enable-remote-services`, 
`--no-enable-remote-services`, `--allow-external-plugins`, 
`--no-allow-external-plugins`, `--show-external-plugins`, 
`--no-show-external-plugins`, `--document-timeout`, `--device`, 
`--num-threads`, `--page-batch-size`
+
+| Debug
+| `--verbose`, `-v` / `-vv` / `-vvv`, `--debug-visualize-cells`, 
`--no-debug-visualize-cells`, `--debug-visualize-ocr`, 
`--no-debug-visualize-ocr`, `--debug-visualize-layout`, 
`--no-debug-visualize-layout`, `--debug-visualize-tables`, 
`--no-debug-visualize-tables`
+
+| Performance
+| `--abort-on-error`, `--no-abort-on-error`, `--profiling`, `--no-profiling`, 
`--save-profiling`, `--no-save-profiling`
+
+| Info
+| `--version`, `--help`, `--logo`
+
+|===
+
+The `--output` (`-o`) flag is **not permitted** because the output directory 
is managed by the producer.
+Use the `CamelDoclingOutputFilePath` header or endpoint configuration instead.
+
+Additionally, the following are rejected:
+
+- **Shell metacharacters**: `;`, `|`, `` ` ``, `$()` — blocked as 
defense-in-depth even though ProcessBuilder does not interpret them.
+- **Path traversal**: `../`, `..\`, and paths that resolve to traversal after 
normalization.
+- **Unknown flags**: any flag not in the allowlist above.
+
+=== Extracting document metadata
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:EXTRACT_METADATA")
+    .process(exchange -> {
+        DocumentMetadata metadata = 
exchange.getIn().getBody(DocumentMetadata.class);
+
+        // Access metadata fields
+        String title = metadata.getTitle();
+        String documentType = metadata.getDocumentType();
+        Integer pageCount = metadata.getPageCount();
+        String format = metadata.getFormat();
+
+        log.info("Document: {} ({}), Pages: {}, Format: {}",
+            title, documentType, pageCount, format);
+
+        // Metadata is also available in headers
+        String titleFromHeader = 
exchange.getIn().getHeader("CamelDoclingMetadataTitle", String.class);
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:EXTRACT_METADATA
+      - log:
+          message: "Document: ${header.CamelDoclingMetadataTitle} 
(${header.CamelDoclingMetadataDocumentType})"
+      - log:
+          message: "Pages: ${header.CamelDoclingMetadataPageCount}"
+      - process:
+          ref: "metadataProcessor"
+----
+====
+
+=== Extract metadata with all fields
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:EXTRACT_METADATA?includeRawMetadata=true")
+    .process(exchange -> {
+        DocumentMetadata metadata = 
exchange.getIn().getBody(DocumentMetadata.class);
+
+        log.info("Page Count: {}", metadata.getPageCount());
+
+        // Raw metadata from parser
+        Map<String, Object> rawMetadata = metadata.getRawMetadata();
+        log.info("Raw metadata: {}", rawMetadata);
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:EXTRACT_METADATA
+          parameters:
+            includeRawMetadata: true
+      - process:
+          ref: "fullMetadataProcessor"
+----
+====
+
+=== Route documents based on metadata
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:EXTRACT_METADATA")
+    .choice()
+        .when(simple("${header.CamelDoclingMetadataPageCount} > 100"))
+            .log("Large document with ${header.CamelDoclingMetadataPageCount} 
pages")
+            .to("file:///data/large-docs")
+        .when(simple("${header.CamelDoclingMetadataLanguage} == 'fr'"))
+            .log("French document")
+            .to("file:///data/french-docs")
+        .when(simple("${header.CamelDoclingMetadataAuthor} contains 'Smith'"))
+            .log("Document by Smith")
+            .to("file:///data/smith-docs")
+        .otherwise()
+            .to("file:///data/other-docs")
+    .end();
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:EXTRACT_METADATA
+      - choice:
+          when:
+            - expression:
+                simple:
+                  expression: "${header.CamelDoclingMetadataPageCount} > 100"
+              steps:
+                - log:
+                    message: "Large document with 
${header.CamelDoclingMetadataPageCount} pages"
+                - to:
+                    uri: file:///data/large-docs
+            - expression:
+                simple:
+                  expression: "${header.CamelDoclingMetadataLanguage} == 'fr'"
+              steps:
+                - log:
+                    message: "French document"
+                - to:
+                    uri: file:///data/french-docs
+            - expression:
+                simple:
+                  expression: "${header.CamelDoclingMetadataAuthor} contains 
'Smith'"
+              steps:
+                - log:
+                    message: "Document by Smith"
+                - to:
+                    uri: file:///data/smith-docs
+          otherwise:
+            steps:
+              - to:
+                  uri: file:///data/other-docs
+----
+====
+
+=== Extract metadata without headers
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:EXTRACT_METADATA?includeMetadataInHeaders=false")
+    .process(exchange -> {
+        DocumentMetadata metadata = 
exchange.getIn().getBody(DocumentMetadata.class);
+
+        // All metadata is in the body object only
+        // Headers are not populated with metadata fields
+        log.info("Metadata: {}", metadata);
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:EXTRACT_METADATA
+          parameters:
+            includeMetadataInHeaders: false
+      - process:
+          ref: "metadataBodyProcessor"
+----
+====
+
+=== Content in body vs file path output
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+// Get content directly in body (file is automatically deleted)
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:CONVERT_TO_MARKDOWN?contentInBody=true")
+    .process(exchange -> {
+        String markdownContent = exchange.getIn().getBody(String.class);
+        log.info("Converted content: {}", markdownContent);
+    });
+
+// Get file path (file is preserved)
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:CONVERT_TO_MARKDOWN?contentInBody=false")
+    .process(exchange -> {
+        String outputFilePath = exchange.getIn().getBody(String.class);
+        log.info("Output file saved at: {}", outputFilePath);
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+# Get content directly in body (file is automatically deleted)
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:CONVERT_TO_MARKDOWN
+          parameters:
+            contentInBody: true
+      - process:
+          ref: "contentProcessor"
+
+# Get file path (file is preserved)
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:CONVERT_TO_MARKDOWN
+          parameters:
+            contentInBody: false
+      - process:
+          ref: "filePathProcessor"
+----
+====
+
+=== Processor Bean Examples
+
+When using YAML DSL, the processor references used in the examples above would 
be implemented as Spring beans:
+
+._Java-only: Spring bean Processor implementation_
+
+[source,java]
+----
+@Component("htmlProcessor")
+public class HtmlProcessor implements Processor {
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        String htmlContent = exchange.getIn().getBody(String.class);
+        // Process the HTML content
+        log.info("Processing HTML content of length: {}", 
htmlContent.length());
+    }
+}
+
+@Component("structuredDataProcessor")
+public class StructuredDataProcessor implements Processor {
+    private static final Logger log = 
LoggerFactory.getLogger(StructuredDataProcessor.class);
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        DoclingDocument doc = exchange.getIn().getBody(DoclingDocument.class);
+        log.info("Document schema: {}, tables: {}", doc.getSchemaName(), 
doc.getTables().size());
+    }
+}
+
+@Component("contentProcessor")
+public class ContentProcessor implements Processor {
+    private static final Logger log = 
LoggerFactory.getLogger(ContentProcessor.class);
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        String markdownContent = exchange.getIn().getBody(String.class);
+        log.info("Converted content: {}", markdownContent);
+    }
+}
+
+@Component("filePathProcessor")
+public class FilePathProcessor implements Processor {
+    private static final Logger log = 
LoggerFactory.getLogger(FilePathProcessor.class);
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        String outputFilePath = exchange.getIn().getBody(String.class);
+        log.info("Output file saved at: {}", outputFilePath);
+    }
+}
+
+@Component("customArgsBean")
+public class CustomArgsBean {
+    public List<String> createCustomArgs() {
+        return Arrays.asList("--verbose", "--preserve-tables");
+    }
+}
+----
+
+== Document Chunking
+
+The component supports document chunking via docling-serve, which splits 
documents into semantically meaningful chunks suitable for RAG 
(Retrieval-Augmented Generation) pipelines, vector databases, and other NLP 
workflows. Unlike naive text splitting, docling chunking is structure-aware — 
it respects document headings, paragraphs, and tables — and the hybrid chunker 
is also token-aware, ensuring chunks fit within model token limits.
+
+NOTE: Both chunking operations require `useDoclingServe=true`. The Docling CLI 
does not expose chunking as a command — chunking is only available through the 
docling-serve REST API.
+
+`CHUNK_HYBRID` uses the HybridChunker, which is both structure-aware and 
token-aware. It respects document structure while ensuring each chunk stays 
within a configurable token limit. Best for RAG pipelines with embedding models 
that have fixed token windows. Configure it with the `chunkingTokenizer`, 
`chunkingMaxTokens`, and `chunkingMergePeers` options (see the endpoint options 
table above).
+
+`CHUNK_HIERARCHICAL` uses the HierarchicalChunker, which is structure-aware 
only. It splits at document structure boundaries (sections, paragraphs) without 
enforcing token limits. Best when chunk size is less important than preserving 
complete structural units.
+
+When `contentInBody=true`, the exchange body is set to a `List<Chunk>` 
(`ai.docling.serve.api.chunk.response.Chunk`), ready for use with Camel's 
`.split(body())` EIP. Each `Chunk` object provides:
+
+- `text` — the chunk text content
+- `chunkIndex` — zero-based position in the document
+- `filename` — source document filename
+- `headings` — list of heading strings leading to this chunk
+- `pageNumbers` — list of page numbers this chunk spans
+- `captions` — list of captions (e.g., table or figure captions)
+- `numTokens` — token count (hybrid chunker only)
+
+When `contentInBody=false`, the full `ChunkDocumentResponse` is returned.
+
+=== Basic Chunking
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .setHeader("CamelDoclingInputFilePath", simple("${file:absolute.path}"))
+    .to("docling:CHUNK_HYBRID?" +
+        "useDoclingServe=true&" +
+        "contentInBody=true&" +
+        "chunkingTokenizer=sentence-transformers/all-MiniLM-L6-v2&" +
+        "chunkingMaxTokens=128&" +
+        "chunkingMergePeers=true")
+    .split(body())
+        .log("Chunk ${body.chunkIndex}: ${body.text}")
+    .end();
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - setHeader:
+          name: CamelDoclingInputFilePath
+          expression:
+            simple:
+              expression: "${file:absolute.path}"
+      - to:
+          uri: docling:CHUNK_HYBRID
+          parameters:
+            useDoclingServe: true
+            contentInBody: true
+            chunkingTokenizer: "sentence-transformers/all-MiniLM-L6-v2"
+            chunkingMaxTokens: 128
+            chunkingMergePeers: true
+      - split:
+          expression:
+            simple:
+              expression: "${body}"
+          steps:
+            - log:
+                message: "Chunk ${body.chunkIndex}: ${body.text}"
+----
+====
+
+=== Chunking for RAG Pipelines
+
+A common use case is to chunk documents, generate embeddings, and store them 
in a vector database:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:ingest-pdf")
+    .setHeader("CamelDoclingInputFilePath", header("pdfFilePath"))
+    .to("docling:CHUNK_HYBRID?" +
+        "useDoclingServe=true&" +
+        "contentInBody=true&" +
+        "chunkingTokenizer={{embedding.tokenizer}}&" +
+        "chunkingMaxTokens={{embedding.max-tokens}}&" +
+        "chunkingMergePeers=true")
+    .split(body())
+        .setBody(simple("${body.text}"))
+        .to("openai:embeddings?embeddingModel={{embedding.model}}")
+        // store embedding in vector database
+        .to("direct:store-embedding")
+    .end();
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    id: ingest-pdf
+    from:
+      uri: direct:ingest-pdf
+    steps:
+      - setHeader:
+          name: CamelDoclingInputFilePath
+          expression:
+            simple:
+              expression: "${header.pdfFilePath}"
+      - to:
+          uri: docling:CHUNK_HYBRID
+          parameters:
+            useDoclingServe: true
+            contentInBody: true
+            chunkingTokenizer: "{{embedding.tokenizer}}"
+            chunkingMaxTokens: "{{embedding.max-tokens}}"
+            chunkingMergePeers: true
+      - split:
+          expression:
+            simple:
+              expression: "${body}"
+          steps:
+            - setBody:
+                expression:
+                  simple:
+                    expression: "${body.text}"
+            - to:
+                uri: openai:embeddings
+                parameters:
+                  embeddingModel: "{{embedding.model}}"
+            - to:
+                uri: direct:store-embedding
+----
+====
+
+=== Hierarchical Chunking
+
+Use hierarchical chunking when you want to preserve complete structural units 
without token limits:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .setHeader("CamelDoclingInputFilePath", simple("${file:absolute.path}"))
+    .to("docling:CHUNK_HIERARCHICAL?" +
+        "useDoclingServe=true&" +
+        "contentInBody=true")
+    .split(body())
+        .log("Section [${body.headings}] page ${body.pageNumbers}: 
${body.text}")
+    .end();
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - setHeader:
+          name: CamelDoclingInputFilePath
+          expression:
+            simple:
+              expression: "${file:absolute.path}"
+      - to:
+          uri: docling:CHUNK_HIERARCHICAL
+          parameters:
+            useDoclingServe: true
+            contentInBody: true
+      - split:
+          expression:
+            simple:
+              expression: "${body}"
+          steps:
+            - log:
+                message: "Section [${body.headings}] page ${body.pageNumbers}: 
${body.text}"
+----
+====
+
+== Advanced Processing Options (API Mode)
+
+When using docling-serve API mode (`useDoclingServe=true`), the component 
exposes advanced processing options that control how the server processes 
documents. These options are passed directly to the docling-serve API and 
provide fine-grained control over OCR, table recognition, enrichment features, 
and output formatting.
+
+=== OCR Options
+
+[width="100%",cols="2,1,4",options="header"]
+|===
+| Parameter | Default | Description
+
+| `doOcr`
+| _not set_
+| Enable OCR processing in docling-serve API mode. When not set, the server 
uses its own defaults. Set `enableOCR` to `false` to explicitly disable OCR.
+
+| `forceOcr`
+| _not set_
+| Force OCR processing even for digital documents (documents with selectable 
text).
+
+| `ocrEngine`
+| _not set_
+| OCR engine to use. Supported values: `AUTO`, `EASYOCR`, `OCRMAC`, 
`RAPIDOCR`, `TESSEROCR`, `TESSERACT`.
+
+|===
+
+NOTE: The `enableOCR` and `ocrLanguage` settings are primarily for CLI mode. 
In API mode, use `doOcr` to explicitly control OCR behavior. When `doOcr` is 
not set, the server uses its own defaults. Setting `enableOCR=false` will send 
`doOcr(false)` to the server to disable OCR.
+
+=== Table and Structure Options
+
+[width="100%",cols="2,1,4",options="header"]
+|===
+| Parameter | Default | Description
+
+| `doTableStructure`
+| _not set_
+| Enable table structure recognition. Automatically enabled for 
`EXTRACT_STRUCTURED_DATA` operations.
+
+| `tableMode`
+| _not set_
+| Table structure recognition mode. Supported values: `ACCURATE`, `FAST`.
+
+| `tableCellMatching`
+| _not set_
+| Enable table cell matching post-processing for better cell boundary 
detection.
+
+|===
+
+=== Enrichment Options
+
+[width="100%",cols="2,1,4",options="header"]
+|===
+| Parameter | Default | Description
+
+| `doCodeEnrichment`
+| _not set_
+| Enable code enrichment in document processing. Identifies and annotates code 
blocks.
+
+| `doFormulaEnrichment`
+| _not set_
+| Enable formula enrichment in document processing. Detects and processes 
mathematical formulas.
+
+| `doPictureClassification`
+| _not set_
+| Enable picture classification (e.g., chart, photo, diagram). May require 
additional ML models on the server.
+
+| `doPictureDescription`
+| _not set_
+| Enable picture description generation. May require a Vision Language Model 
(VLM) on the server.
+
+|===
+
+=== Pipeline and Output Options
+
+[width="100%",cols="2,1,4",options="header"]
+|===
+| Parameter | Default | Description
+
+| `pipeline`
+| _not set_
+| Processing pipeline to use. Supported values: `ASR`, `STANDARD`, `VLM`.
+
+| `pdfBackend`
+| _not set_
+| PDF parsing backend. Supported values: `DLPARSE_V1`, `DLPARSE_V2`, 
`DLPARSE_V4`, `PYPDFIUM2`.
+
+| `includeImages`
+| _not set_
+| Include images in the conversion output.
+
+| `imageExportMode`
+| _not set_
+| Image export mode for referenced images. Supported values: `EMBEDDED`, 
`PLACEHOLDER`, `REFERENCED`.
+
+| `imagesScale`
+| _not set_
+| Scale factor for exported images (e.g., `2.0` for double resolution).
+
+| `mdPageBreakPlaceholder`
+| _not set_
+| Placeholder string for page breaks in markdown output.
+
+| `abortOnError`
+| _not set_
+| Abort processing on error instead of continuing with partial results.
+
+| `documentTimeout`
+| _not set_
+| Document processing timeout in seconds (server-side timeout).
+
+|===
+
+=== Example: Advanced Processing Configuration
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:EXTRACT_STRUCTURED_DATA?" +
+        "useDoclingServe=true&" +
+        "doOcr=true&" +
+        "ocrEngine=TESSERACT&" +
+        "doTableStructure=true&" +
+        "tableMode=ACCURATE&" +
+        "doCodeEnrichment=true&" +
+        "pdfBackend=DLPARSE_V4&" +
+        "processTimeout=120000&" +     // 2 minutes for complex PDFs
+        "contentInBody=true")
+    .process(exchange -> {
+        DoclingDocument doc = exchange.getIn().getBody(DoclingDocument.class);
+        // Process the structured document
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:EXTRACT_STRUCTURED_DATA
+          parameters:
+            useDoclingServe: true
+            doOcr: true
+            ocrEngine: "TESSERACT"
+            doTableStructure: true
+            tableMode: "ACCURATE"
+            doCodeEnrichment: true
+            pdfBackend: "DLPARSE_V4"
+            processTimeout: 120000
+            contentInBody: true
+      - process:
+          ref: "structuredDataProcessor"
+----
+====
+
+== DoclingDocument Return Type
+
+When using docling-serve API mode, the `CONVERT_TO_JSON` and 
`EXTRACT_STRUCTURED_DATA` operations return a `DoclingDocument` object (from 
the `ai.docling.core` package) instead of a raw JSON string. This object 
provides type-safe access to the document structure.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/documents?include=.*\\.pdf")
+    .to("docling:CONVERT_TO_JSON?" +
+        "useDoclingServe=true&" +
+        "contentInBody=true")
+    .process(exchange -> {
+        DoclingDocument doc = exchange.getIn().getBody(DoclingDocument.class);
+
+        // Access document structure
+        String schemaName = doc.getSchemaName();
+
+        // Access tables
+        List<DoclingDocument.TableItem> tables = doc.getTables();
+        for (DoclingDocument.TableItem table : tables) {
+            DoclingDocument.TableData data = table.getData();
+            int rows = data.getNumRows();
+            int cols = data.getNumCols();
+            log.info("Table: {}x{}", rows, cols);
+        }
+
+        // Access pictures
+        List<DoclingDocument.PictureItem> pictures = doc.getPictures();
+        log.info("Found {} pictures", pictures.size());
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:CONVERT_TO_JSON
+          parameters:
+            useDoclingServe: true
+            contentInBody: true
+      - process:
+          ref: "doclingDocumentProcessor"
+----
+====
+
+== Error Handling
+
+The component handles various error scenarios:
+
+- **File size limit exceeded**: Files larger than `maxFileSize` are rejected
+- **Process timeout**: Long-running conversions are terminated after 
`processTimeout` milliseconds
+- **Invalid file formats**: Unsupported file formats result in processing 
errors
+- **Docling not found**: Missing Docling installation causes startup failures 
(CLI mode)
+- **Connection errors**: When using docling-serve API mode, connection 
failures to the API endpoint will result in errors
+- **Authentication errors**: Invalid or missing authentication credentials 
will result in 401 Unauthorized errors from the docling-serve API
+
+== Performance Considerations
+
+- **Process Timeout**: The `processTimeout` setting (default: 30000ms / 30 
seconds) controls both the CLI subprocess timeout and the HTTP read timeout for 
docling-serve API mode. For complex PDF documents that require OCR or 
enrichment processing, increase this value (e.g., `processTimeout=120000` for 2 
minutes).
+- OCR processing significantly increases processing time for scanned documents.
+- Consider using `contentInBody=true` when using docling-serve API mode to get 
results directly in the body.
+- The `maxFileSize` setting helps prevent resource exhaustion.
+- **API Mode vs CLI Mode**: The docling-serve API mode typically offers better 
performance and resource utilization for high-volume document processing, as it 
maintains a persistent server instance.
+- **Async Mode**: For large documents or high-volume processing, enable 
`useAsyncMode=true` to prevent blocking the Camel thread pool. The component 
will poll the docling-serve API for completion status while freeing up 
processing threads.
+- **Async Configuration**: Adjust `asyncPollInterval` (default 2000ms) and 
`asyncTimeout` (default 300000ms/5 minutes) based on your document size and 
processing requirements.
+- **Batch Processing**: When processing multiple documents, async mode allows 
better parallelization as the docling-serve instance can process multiple 
documents concurrently while Camel polls for results.
+- **Enrichment Features**: Enabling advanced options like 
`doPictureClassification` or `doPictureDescription` may require additional ML 
models on the server and can increase processing time.
+
+== Sub-Pages
+
+For more details on specific features, see:
+
+* xref:others:docling-batch-processing.adoc[Batch Processing] - Batch 
operations, queue-based processing, error handling, and result splitting
+* xref:others:docling-async-processing.adoc[Asynchronous Processing] - Async 
mode, custom timeouts, polling patterns, and parallel processing
+* xref:others:docling-serve.adoc[Using Docling-Serve API] - Remote API usage, 
URL processing, and authentication methods
+
+== HTTP Client Configuration
+
+When using docling-serve API mode, the component uses the 
https://github.com/docling-project/docling-java[docling-java] library which 
internally uses Java's built-in `HttpClient`. The HTTP client is configured 
with sensible defaults and connection management is handled automatically by 
the library.
+
+=== Timeout Configuration
+
+[width="100%",cols="2,1,4",options="header"]
+|===
+| Parameter | Default | Description
+
+| `processTimeout`
+| 30000
+| HTTP read timeout in milliseconds for synchronous API calls. Also used as 
the CLI subprocess timeout. Increase this for large or complex documents (e.g., 
120000 for 2 minutes).
+
+| `asyncPollInterval`
+| 2000
+| Poll interval in milliseconds when checking async task status.
+
+| `asyncTimeout`
+| 300000
+| Maximum time to wait for async conversion completion in milliseconds (5 
minutes).
+
+| `asyncTaskTtl`
+| 86400000
+| Time-to-live for pending async conversion tasks in milliseconds (24 hours). 
Tasks older than this will be automatically evicted from memory to prevent 
leaks. A background cleanup task runs periodically to remove expired entries.
+
+|===
+
+IMPORTANT: The default `processTimeout` of 30 seconds may not be sufficient 
for complex PDF documents, especially when OCR or enrichment options are 
enabled. For production use with PDF files, consider increasing 
`processTimeout` to at least 120000 (2 minutes).
+
+=== Configuration Examples
+
+==== Long-Running Document Processing
+
+For large documents that take a long time to process, increase the async 
timeout:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:///data/large-documents?include=.*\\.pdf")
+    .to("docling:CONVERT_TO_MARKDOWN?" +
+        "useDoclingServe=true&" +
+        "useAsyncMode=true&" +
+        "asyncPollInterval=5000&" +      // Check every 5 seconds
+        "asyncTimeout=600000&" +          // 10 minutes timeout
+        "contentInBody=true")
+    .to("file:///data/output");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:///data/large-documents
+      parameters:
+        include: ".*\\.pdf"
+    steps:
+      - to:
+          uri: docling:CONVERT_TO_MARKDOWN
+          parameters:
+            useDoclingServe: true
+            useAsyncMode: true
+            asyncPollInterval: 5000
+            asyncTimeout: 600000
+            contentInBody: true
+      - to:
+          uri: file:///data/output
+----
+====
+
+=== Best Practices
+
+1. **Use async mode for large documents**: Enable `useAsyncMode=true` for 
documents that may take longer to process. The docling-java library handles 
polling automatically.
+
+2. **Adjust poll interval appropriately**: For high-volume scenarios, increase 
`asyncPollInterval` to reduce polling overhead. For interactive use cases, a 
shorter interval provides faster feedback.
+
+3. **Set appropriate timeouts**: Adjust `asyncTimeout` based on your largest 
expected document size. The default 5 minutes is suitable for most documents.
+
+4. **Monitor with logging**: Use DEBUG level logging to monitor API calls and 
async task status.
+
diff --git 
a/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingComponentConfigurer.java
 
b/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingComponentConfigurer.java
index 5a13f84871a1..1c246c8fd60e 100644
--- 
a/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingComponentConfigurer.java
+++ 
b/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingComponentConfigurer.java
@@ -32,6 +32,10 @@ public class DoclingComponentConfigurer extends 
PropertyConfigurerSupport implem
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "abortonerror":
         case "abortOnError": 
getOrCreateConfiguration(target).setAbortOnError(property(camelContext, 
java.lang.Boolean.class, value)); return true;
+        case "allowfilepathsource":
+        case "allowFilePathSource": 
getOrCreateConfiguration(target).setAllowFilePathSource(property(camelContext, 
boolean.class, value)); return true;
+        case "allowurlsource":
+        case "allowUrlSource": 
getOrCreateConfiguration(target).setAllowUrlSource(property(camelContext, 
boolean.class, value)); return true;
         case "apikeyheader":
         case "apiKeyHeader": 
getOrCreateConfiguration(target).setApiKeyHeader(property(camelContext, 
java.lang.String.class, value)); return true;
         case "asyncpollinterval":
@@ -89,6 +93,8 @@ public class DoclingComponentConfigurer extends 
PropertyConfigurerSupport implem
         case "includeMetadataInHeaders": 
getOrCreateConfiguration(target).setIncludeMetadataInHeaders(property(camelContext,
 boolean.class, value)); return true;
         case "includerawmetadata":
         case "includeRawMetadata": 
getOrCreateConfiguration(target).setIncludeRawMetadata(property(camelContext, 
boolean.class, value)); return true;
+        case "inputbasedirectory":
+        case "inputBaseDirectory": 
getOrCreateConfiguration(target).setInputBaseDirectory(property(camelContext, 
java.lang.String.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
         case "maxfilesize":
@@ -128,6 +134,10 @@ public class DoclingComponentConfigurer extends 
PropertyConfigurerSupport implem
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "abortonerror":
         case "abortOnError": return java.lang.Boolean.class;
+        case "allowfilepathsource":
+        case "allowFilePathSource": return boolean.class;
+        case "allowurlsource":
+        case "allowUrlSource": return boolean.class;
         case "apikeyheader":
         case "apiKeyHeader": return java.lang.String.class;
         case "asyncpollinterval":
@@ -185,6 +195,8 @@ public class DoclingComponentConfigurer extends 
PropertyConfigurerSupport implem
         case "includeMetadataInHeaders": return boolean.class;
         case "includerawmetadata":
         case "includeRawMetadata": return boolean.class;
+        case "inputbasedirectory":
+        case "inputBaseDirectory": return java.lang.String.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
         case "maxfilesize":
@@ -225,6 +237,10 @@ public class DoclingComponentConfigurer extends 
PropertyConfigurerSupport implem
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "abortonerror":
         case "abortOnError": return 
getOrCreateConfiguration(target).getAbortOnError();
+        case "allowfilepathsource":
+        case "allowFilePathSource": return 
getOrCreateConfiguration(target).isAllowFilePathSource();
+        case "allowurlsource":
+        case "allowUrlSource": return 
getOrCreateConfiguration(target).isAllowUrlSource();
         case "apikeyheader":
         case "apiKeyHeader": return 
getOrCreateConfiguration(target).getApiKeyHeader();
         case "asyncpollinterval":
@@ -282,6 +298,8 @@ public class DoclingComponentConfigurer extends 
PropertyConfigurerSupport implem
         case "includeMetadataInHeaders": return 
getOrCreateConfiguration(target).isIncludeMetadataInHeaders();
         case "includerawmetadata":
         case "includeRawMetadata": return 
getOrCreateConfiguration(target).isIncludeRawMetadata();
+        case "inputbasedirectory":
+        case "inputBaseDirectory": return 
getOrCreateConfiguration(target).getInputBaseDirectory();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
         case "maxfilesize":
diff --git 
a/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingConfigurationConfigurer.java
 
b/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingConfigurationConfigurer.java
index c7e9be154563..91ac3233bebe 100644
--- 
a/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingConfigurationConfigurer.java
+++ 
b/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingConfigurationConfigurer.java
@@ -25,6 +25,10 @@ public class DoclingConfigurationConfigurer extends 
org.apache.camel.support.com
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "abortonerror":
         case "abortOnError": target.setAbortOnError(property(camelContext, 
java.lang.Boolean.class, value)); return true;
+        case "allowfilepathsource":
+        case "allowFilePathSource": 
target.setAllowFilePathSource(property(camelContext, boolean.class, value)); 
return true;
+        case "allowurlsource":
+        case "allowUrlSource": target.setAllowUrlSource(property(camelContext, 
boolean.class, value)); return true;
         case "apikeyheader":
         case "apiKeyHeader": target.setApiKeyHeader(property(camelContext, 
java.lang.String.class, value)); return true;
         case "asyncpollinterval":
@@ -79,6 +83,8 @@ public class DoclingConfigurationConfigurer extends 
org.apache.camel.support.com
         case "includeMetadataInHeaders": 
target.setIncludeMetadataInHeaders(property(camelContext, boolean.class, 
value)); return true;
         case "includerawmetadata":
         case "includeRawMetadata": 
target.setIncludeRawMetadata(property(camelContext, boolean.class, value)); 
return true;
+        case "inputbasedirectory":
+        case "inputBaseDirectory": 
target.setInputBaseDirectory(property(camelContext, java.lang.String.class, 
value)); return true;
         case "maxfilesize":
         case "maxFileSize": target.setMaxFileSize(property(camelContext, 
long.class, value)); return true;
         case "mdpagebreakplaceholder":
@@ -116,6 +122,10 @@ public class DoclingConfigurationConfigurer extends 
org.apache.camel.support.com
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "abortonerror":
         case "abortOnError": return java.lang.Boolean.class;
+        case "allowfilepathsource":
+        case "allowFilePathSource": return boolean.class;
+        case "allowurlsource":
+        case "allowUrlSource": return boolean.class;
         case "apikeyheader":
         case "apiKeyHeader": return java.lang.String.class;
         case "asyncpollinterval":
@@ -170,6 +180,8 @@ public class DoclingConfigurationConfigurer extends 
org.apache.camel.support.com
         case "includeMetadataInHeaders": return boolean.class;
         case "includerawmetadata":
         case "includeRawMetadata": return boolean.class;
+        case "inputbasedirectory":
+        case "inputBaseDirectory": return java.lang.String.class;
         case "maxfilesize":
         case "maxFileSize": return long.class;
         case "mdpagebreakplaceholder":
@@ -208,6 +220,10 @@ public class DoclingConfigurationConfigurer extends 
org.apache.camel.support.com
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "abortonerror":
         case "abortOnError": return target.getAbortOnError();
+        case "allowfilepathsource":
+        case "allowFilePathSource": return target.isAllowFilePathSource();
+        case "allowurlsource":
+        case "allowUrlSource": return target.isAllowUrlSource();
         case "apikeyheader":
         case "apiKeyHeader": return target.getApiKeyHeader();
         case "asyncpollinterval":
@@ -262,6 +278,8 @@ public class DoclingConfigurationConfigurer extends 
org.apache.camel.support.com
         case "includeMetadataInHeaders": return 
target.isIncludeMetadataInHeaders();
         case "includerawmetadata":
         case "includeRawMetadata": return target.isIncludeRawMetadata();
+        case "inputbasedirectory":
+        case "inputBaseDirectory": return target.getInputBaseDirectory();
         case "maxfilesize":
         case "maxFileSize": return target.getMaxFileSize();
         case "mdpagebreakplaceholder":
diff --git 
a/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingEndpointConfigurer.java
 
b/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingEndpointConfigurer.java
index 565d710c791e..c17797ad91a8 100644
--- 
a/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingEndpointConfigurer.java
+++ 
b/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingEndpointConfigurer.java
@@ -25,6 +25,10 @@ public class DoclingEndpointConfigurer extends 
PropertyConfigurerSupport impleme
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "abortonerror":
         case "abortOnError": 
target.getConfiguration().setAbortOnError(property(camelContext, 
java.lang.Boolean.class, value)); return true;
+        case "allowfilepathsource":
+        case "allowFilePathSource": 
target.getConfiguration().setAllowFilePathSource(property(camelContext, 
boolean.class, value)); return true;
+        case "allowurlsource":
+        case "allowUrlSource": 
target.getConfiguration().setAllowUrlSource(property(camelContext, 
boolean.class, value)); return true;
         case "apikeyheader":
         case "apiKeyHeader": 
target.getConfiguration().setApiKeyHeader(property(camelContext, 
java.lang.String.class, value)); return true;
         case "asyncpollinterval":
@@ -79,6 +83,8 @@ public class DoclingEndpointConfigurer extends 
PropertyConfigurerSupport impleme
         case "includeMetadataInHeaders": 
target.getConfiguration().setIncludeMetadataInHeaders(property(camelContext, 
boolean.class, value)); return true;
         case "includerawmetadata":
         case "includeRawMetadata": 
target.getConfiguration().setIncludeRawMetadata(property(camelContext, 
boolean.class, value)); return true;
+        case "inputbasedirectory":
+        case "inputBaseDirectory": 
target.getConfiguration().setInputBaseDirectory(property(camelContext, 
java.lang.String.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
         case "maxfilesize":
@@ -118,6 +124,10 @@ public class DoclingEndpointConfigurer extends 
PropertyConfigurerSupport impleme
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "abortonerror":
         case "abortOnError": return java.lang.Boolean.class;
+        case "allowfilepathsource":
+        case "allowFilePathSource": return boolean.class;
+        case "allowurlsource":
+        case "allowUrlSource": return boolean.class;
         case "apikeyheader":
         case "apiKeyHeader": return java.lang.String.class;
         case "asyncpollinterval":
@@ -172,6 +182,8 @@ public class DoclingEndpointConfigurer extends 
PropertyConfigurerSupport impleme
         case "includeMetadataInHeaders": return boolean.class;
         case "includerawmetadata":
         case "includeRawMetadata": return boolean.class;
+        case "inputbasedirectory":
+        case "inputBaseDirectory": return java.lang.String.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
         case "maxfilesize":
@@ -212,6 +224,10 @@ public class DoclingEndpointConfigurer extends 
PropertyConfigurerSupport impleme
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "abortonerror":
         case "abortOnError": return 
target.getConfiguration().getAbortOnError();
+        case "allowfilepathsource":
+        case "allowFilePathSource": return 
target.getConfiguration().isAllowFilePathSource();
+        case "allowurlsource":
+        case "allowUrlSource": return 
target.getConfiguration().isAllowUrlSource();
         case "apikeyheader":
         case "apiKeyHeader": return 
target.getConfiguration().getApiKeyHeader();
         case "asyncpollinterval":
@@ -266,6 +282,8 @@ public class DoclingEndpointConfigurer extends 
PropertyConfigurerSupport impleme
         case "includeMetadataInHeaders": return 
target.getConfiguration().isIncludeMetadataInHeaders();
         case "includerawmetadata":
         case "includeRawMetadata": return 
target.getConfiguration().isIncludeRawMetadata();
+        case "inputbasedirectory":
+        case "inputBaseDirectory": return 
target.getConfiguration().getInputBaseDirectory();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
         case "maxfilesize":
diff --git 
a/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingEndpointUriFactory.java
 
b/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingEndpointUriFactory.java
index d0b451ff909d..c5b710b8c9a9 100644
--- 
a/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingEndpointUriFactory.java
+++ 
b/components/camel-ai/camel-docling/src/generated/java/org/apache/camel/component/docling/DoclingEndpointUriFactory.java
@@ -23,8 +23,10 @@ public class DoclingEndpointUriFactory extends 
org.apache.camel.support.componen
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(45);
+        Set<String> props = new HashSet<>(48);
         props.add("abortOnError");
+        props.add("allowFilePathSource");
+        props.add("allowUrlSource");
         props.add("apiKeyHeader");
         props.add("asyncPollInterval");
         props.add("asyncTimeout");
@@ -52,6 +54,7 @@ public class DoclingEndpointUriFactory extends 
org.apache.camel.support.componen
         props.add("includeLayoutInfo");
         props.add("includeMetadataInHeaders");
         props.add("includeRawMetadata");
+        props.add("inputBaseDirectory");
         props.add("lazyStartProducer");
         props.add("maxFileSize");
         props.add("mdPageBreakPlaceholder");
diff --git 
a/components/camel-ai/camel-docling/src/generated/resources/META-INF/org/apache/camel/component/docling/docling.json
 
b/components/camel-ai/camel-docling/src/generated/resources/META-INF/org/apache/camel/component/docling/docling.json
index 26a362b9f4f9..74e1c6949942 100644
--- 
a/components/camel-ai/camel-docling/src/generated/resources/META-INF/org/apache/camel/component/docling/docling.json
+++ 
b/components/camel-ai/camel-docling/src/generated/resources/META-INF/org/apache/camel/component/docling/docling.json
@@ -66,10 +66,13 @@
     "splitBatchResults": { "index": 39, "kind": "property", "displayName": 
"Split Batch Results", "group": "batch", "label": "batch", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Split batch results into 
individual exchanges (one per do [...]
     "includeMetadataInHeaders": { "index": 40, "kind": "property", 
"displayName": "Include Metadata In Headers", "group": "metadata", "label": 
"metadata", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Include metadata in 
message headers w [...]
     "includeRawMetadata": { "index": 41, "kind": "property", "displayName": 
"Include Raw Metadata", "group": "metadata", "label": "metadata", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Include raw metadata as 
returned by the parser" },
-    "apiKeyHeader": { "index": 42, "kind": "property", "displayName": "Api Key 
Header", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"X-API-Key", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Header name for API key 
authentication" },
-    "authenticationScheme": { "index": 43, "kind": "property", "displayName": 
"Authentication Scheme", "group": "security", "label": "security", "required": 
false, "type": "enum", "javaType": 
"org.apache.camel.component.docling.AuthenticationScheme", "enum": [ "NONE", 
"BEARER", "API_KEY" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "NONE", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", "configuration [...]
-    "authenticationToken": { "index": 44, "kind": "property", "displayName": 
"Authentication Token", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": true, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Authentication token for 
docling-serve API (Bearer token or API  [...]
-    "maxFileSize": { "index": 45, "kind": "property", "displayName": "Max File 
Size", "group": "security", "label": "security", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": 52428800, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Maximum file size in 
bytes for processing" }
+    "allowFilePathSource": { "index": 42, "kind": "property", "displayName": 
"Allow File Path Source", "group": "security", "label": "security", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Whether a String message 
body that starts with [...]
+    "allowUrlSource": { "index": 43, "kind": "property", "displayName": "Allow 
Url Source", "group": "security", "label": "security", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Whether a String message 
body that starts with http:\/\/  [...]
+    "apiKeyHeader": { "index": 44, "kind": "property", "displayName": "Api Key 
Header", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"X-API-Key", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Header name for API key 
authentication" },
+    "authenticationScheme": { "index": 45, "kind": "property", "displayName": 
"Authentication Scheme", "group": "security", "label": "security", "required": 
false, "type": "enum", "javaType": 
"org.apache.camel.component.docling.AuthenticationScheme", "enum": [ "NONE", 
"BEARER", "API_KEY" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "NONE", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", "configuration [...]
+    "authenticationToken": { "index": 46, "kind": "property", "displayName": 
"Authentication Token", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": true, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Authentication token for 
docling-serve API (Bearer token or API  [...]
+    "inputBaseDirectory": { "index": 47, "kind": "property", "displayName": 
"Input Base Directory", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "When set, every local 
input file path must resolve inside this d [...]
+    "maxFileSize": { "index": 48, "kind": "property", "displayName": "Max File 
Size", "group": "security", "label": "security", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": 52428800, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Maximum file size in 
bytes for processing" }
   },
   "headers": {
     "CamelDoclingOperation": { "index": 0, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": 
"DoclingOperations", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The operation to perform", 
"constantName": "org.apache.camel.component.docling.DoclingHeaders#OPERATION" },
@@ -143,9 +146,12 @@
     "splitBatchResults": { "index": 38, "kind": "parameter", "displayName": 
"Split Batch Results", "group": "batch", "label": "batch", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Split batch results into 
individual exchanges (one per d [...]
     "includeMetadataInHeaders": { "index": 39, "kind": "parameter", 
"displayName": "Include Metadata In Headers", "group": "metadata", "label": 
"metadata", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Include metadata in 
message headers  [...]
     "includeRawMetadata": { "index": 40, "kind": "parameter", "displayName": 
"Include Raw Metadata", "group": "metadata", "label": "metadata", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Include raw metadata as 
returned by the parser" },
-    "apiKeyHeader": { "index": 41, "kind": "parameter", "displayName": "Api 
Key Header", "group": "security", "label": "security", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"X-API-Key", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Header name for API key 
authentication" },
-    "authenticationScheme": { "index": 42, "kind": "parameter", "displayName": 
"Authentication Scheme", "group": "security", "label": "security", "required": 
false, "type": "enum", "javaType": 
"org.apache.camel.component.docling.AuthenticationScheme", "enum": [ "NONE", 
"BEARER", "API_KEY" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "NONE", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", "configuratio [...]
-    "authenticationToken": { "index": 43, "kind": "parameter", "displayName": 
"Authentication Token", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": true, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Authentication token for 
docling-serve API (Bearer token or API [...]
-    "maxFileSize": { "index": 44, "kind": "parameter", "displayName": "Max 
File Size", "group": "security", "label": "security", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "defaultValue": 52428800, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Maximum file size in 
bytes for processing" }
+    "allowFilePathSource": { "index": 41, "kind": "parameter", "displayName": 
"Allow File Path Source", "group": "security", "label": "security", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Whether a String message 
body that starts wit [...]
+    "allowUrlSource": { "index": 42, "kind": "parameter", "displayName": 
"Allow Url Source", "group": "security", "label": "security", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Whether a String message 
body that starts with http:\/\/ [...]
+    "apiKeyHeader": { "index": 43, "kind": "parameter", "displayName": "Api 
Key Header", "group": "security", "label": "security", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"X-API-Key", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Header name for API key 
authentication" },
+    "authenticationScheme": { "index": 44, "kind": "parameter", "displayName": 
"Authentication Scheme", "group": "security", "label": "security", "required": 
false, "type": "enum", "javaType": 
"org.apache.camel.component.docling.AuthenticationScheme", "enum": [ "NONE", 
"BEARER", "API_KEY" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "NONE", "configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", "configuratio [...]
+    "authenticationToken": { "index": 45, "kind": "parameter", "displayName": 
"Authentication Token", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": true, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Authentication token for 
docling-serve API (Bearer token or API [...]
+    "inputBaseDirectory": { "index": 46, "kind": "parameter", "displayName": 
"Input Base Directory", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "When set, every local 
input file path must resolve inside this  [...]
+    "maxFileSize": { "index": 47, "kind": "parameter", "displayName": "Max 
File Size", "group": "security", "label": "security", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "defaultValue": 52428800, 
"configurationClass": 
"org.apache.camel.component.docling.DoclingConfiguration", 
"configurationField": "configuration", "description": "Maximum file size in 
bytes for processing" }
   }
 }
diff --git 
a/components/camel-ai/camel-docling/src/main/docs/docling-component.adoc 
b/components/camel-ai/camel-docling/src/main/docs/docling-component.adoc
index 05de3dc8a99f..01ad2d76bd44 100644
--- a/components/camel-ai/camel-docling/src/main/docs/docling-component.adoc
+++ b/components/camel-ai/camel-docling/src/main/docs/docling-component.adoc
@@ -113,11 +113,58 @@ include::partial$component-endpoint-headers.adoc[]
 
 The component accepts the following input types in the message body:
 
-- `String` - File path or document content
+- `String` - Document content. It is only read as a location when the endpoint 
opts in - see <<_input_sources>> below
 - `byte[]` - Binary document content
 - `File` - File object
 - `InputStream` - Input stream containing document data
 
+For the batch operations the body may also be a `List<String>` or `String[]` 
of file paths, a `List<File>`
+or `File[]`, or a single directory path `String`.
+
+[#_input_sources]
+=== Input Sources
+
+A `String` body is ambiguous: it could be the document itself, a URL to fetch, 
or a path to read. By default
+the component treats it as the document, and the two location readings must be 
enabled explicitly:
+
+[cols="1,1,3", options="header"]
+|===
+| Option | Default | Effect when enabled
+
+| `allowUrlSource`
+| `false`
+| A body starting with `http://` or `https://` is handed to Docling as a 
remote URL to fetch.
+
+| `allowFilePathSource`
+| `false`
+| A body starting with `/`, or containing `\`, is read from the local 
filesystem. This also covers the single
+directory-or-file `String` body accepted by the batch operations.
+
+| `inputBaseDirectory`
+| _(none)_
+| When set, every local input path must resolve inside this directory once 
normalized. Applies to the
+`CamelDoclingInputFilePath` header, to file path bodies, and to the paths used 
by the batch operations.
+|===
+
+With both options left at their defaults, a body that is neither a URL nor a 
path is written to a temporary
+file and converted as document content, exactly as before.
+
+The `CamelDoclingInputFilePath` header is an explicit "the document lives 
here" signal from the route, so it
+keeps working without `allowFilePathSource`. It is still subject to 
`inputBaseDirectory` when one is set.
+Typed bodies - `File`, `byte[]`, `InputStream`, and the explicit path 
collections used by the batch
+operations - are unambiguous and are likewise unaffected.
+
+[source,java]
+----
+// the body is the document itself - no opt-in needed
+from("direct:content")
+    .to("docling:convert?operation=CONVERT_TO_MARKDOWN");
+
+// the body is a path, confined to /var/docs
+from("direct:paths")
+    
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&allowFilePathSource=true&inputBaseDirectory=/var/docs");
+----
+
 === Output Behavior
 
 The component behavior depends on the `contentInBody` configuration option:
diff --git 
a/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingConfiguration.java
 
b/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingConfiguration.java
index c33ee819dd98..f833800024dc 100644
--- 
a/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingConfiguration.java
+++ 
b/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingConfiguration.java
@@ -68,6 +68,29 @@ public class DoclingConfiguration implements Cloneable {
     @Metadata(description = "Maximum file size in bytes for processing", 
defaultValue = "52428800")
     private long maxFileSize = 50 * 1024 * 1024; // 50MB
 
+    @UriParam(label = "security")
+    @Metadata(description = "Whether a String message body that starts with 
http:// or https:// is interpreted as a"
+                            + " remote URL for Docling to fetch. When 
disabled, such a body is rejected instead of"
+                            + " being fetched. This does not affect the 
CamelDoclingInputFilePath header, nor bodies"
+                            + " of any other type.",
+              defaultValue = "false")
+    private boolean allowUrlSource;
+
+    @UriParam(label = "security")
+    @Metadata(description = "Whether a String message body that starts with / 
or contains \\ is interpreted as a"
+                            + " local filesystem path to read. When disabled, 
such a body is rejected instead of"
+                            + " being read. This does not affect the 
CamelDoclingInputFilePath header, nor File,"
+                            + " byte[] or explicit path collection bodies used 
by the batch operations.",
+              defaultValue = "false")
+    private boolean allowFilePathSource;
+
+    @UriParam(label = "security")
+    @Metadata(description = "When set, every local input file path must 
resolve inside this directory once"
+                            + " normalized. Applies to the 
CamelDoclingInputFilePath header, to file path message"
+                            + " bodies, and to the paths used by the batch 
operations. When empty, no directory"
+                            + " restriction is applied.")
+    private String inputBaseDirectory;
+
     @UriParam
     @Metadata(description = "Include the content of the output file in the 
exchange body and delete the output file",
               defaultValue = "false")
@@ -284,6 +307,30 @@ public class DoclingConfiguration implements Cloneable {
         this.maxFileSize = maxFileSize;
     }
 
+    public boolean isAllowUrlSource() {
+        return allowUrlSource;
+    }
+
+    public void setAllowUrlSource(boolean allowUrlSource) {
+        this.allowUrlSource = allowUrlSource;
+    }
+
+    public boolean isAllowFilePathSource() {
+        return allowFilePathSource;
+    }
+
+    public void setAllowFilePathSource(boolean allowFilePathSource) {
+        this.allowFilePathSource = allowFilePathSource;
+    }
+
+    public String getInputBaseDirectory() {
+        return inputBaseDirectory;
+    }
+
+    public void setInputBaseDirectory(String inputBaseDirectory) {
+        this.inputBaseDirectory = inputBaseDirectory;
+    }
+
     public boolean isContentInBody() {
         return contentInBody;
     }
diff --git 
a/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java
 
b/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java
index d54886ff815d..49e911c2c14b 100644
--- 
a/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java
+++ 
b/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java
@@ -495,7 +495,7 @@ public class DoclingProducer extends DefaultProducer {
 
         try {
             // Extract basic file information for file paths
-            if (!inputPath.startsWith("http://";) && 
!inputPath.startsWith("https://";)) {
+            if (!isRemoteSource(inputPath)) {
                 File file = new File(inputPath);
                 if (file.exists()) {
                     metadata.setFileName(file.getName());
@@ -816,7 +816,27 @@ public class DoclingProducer extends DefaultProducer {
     }
 
     @SuppressWarnings("unchecked")
-    private List<String> extractDocumentList(Exchange exchange) {
+    private List<String> extractDocumentList(Exchange exchange) throws 
IOException {
+        return containBatchPaths(extractDocumentPaths(exchange));
+    }
+
+    /**
+     * Applies the {@code inputBaseDirectory} restriction to every path of a 
batch. When no base directory is configured
+     * the paths are returned untouched.
+     */
+    private List<String> containBatchPaths(List<String> paths) throws 
IOException {
+        String base = configuration.getInputBaseDirectory();
+        if (base == null || base.isEmpty()) {
+            return paths;
+        }
+        List<String> contained = new ArrayList<>(paths.size());
+        for (String path : paths) {
+            contained.add(resolveWithinInputBaseDirectory(path).toString());
+        }
+        return contained;
+    }
+
+    private List<String> extractDocumentPaths(Exchange exchange) {
         Object body = exchange.getIn().getBody();
 
         // Handle List<String>
@@ -875,6 +895,15 @@ public class DoclingProducer extends DefaultProducer {
 
         // Handle single String (directory path to scan)
         if (body instanceof String path) {
+            // as in getInputPath, a bare String body is ambiguous - reading 
it as a location must be opted into.
+            // Typed bodies (List<String>, String[], List<File>, File[]) are 
explicit path collections and are
+            // handled above without a gate.
+            if (!configuration.isAllowFilePathSource()) {
+                throw new IllegalArgumentException(
+                        "Batch message body is a String path but 
allowFilePathSource is disabled."
+                                                   + " Set 
allowFilePathSource=true, or pass the documents as a List<String>,"
+                                                   + " String[], List<File> or 
File[] body.");
+            }
             File dir = new File(path);
             if (dir.isDirectory()) {
                 File[] files = dir.listFiles();
@@ -1288,7 +1317,7 @@ public class DoclingProducer extends DefaultProducer {
 
     private void addSourceToRequest(ConvertDocumentRequest.Builder 
requestBuilder, String inputSource) throws IOException {
         // Check if input is a URL or file path
-        if (inputSource.startsWith("http://";) || 
inputSource.startsWith("https://";)) {
+        if (isRemoteSource(inputSource)) {
             requestBuilder.source(
                     HttpSource.builder()
                             .url(URI.create(inputSource))
@@ -1474,7 +1503,11 @@ public class DoclingProducer extends DefaultProducer {
         String inputPath = 
exchange.getIn().getHeader(DoclingHeaders.INPUT_FILE_PATH, String.class);
 
         if (inputPath != null) {
-            validateFileSize(inputPath);
+            // the header is an explicit "the document lives here" signal from 
the route, so it keeps its
+            // meaning - but a local path is still bound by inputBaseDirectory 
when one is configured
+            if (!isRemoteSource(inputPath)) {
+                return validateLocalInputPath(inputPath);
+            }
             return inputPath;
         }
 
@@ -1484,20 +1517,28 @@ public class DoclingProducer extends DefaultProducer {
             body = wf.getBody();
         }
         if (body instanceof String content) {
-            // Check if it's a URL (http:// or https://) or a file path
-            if (content.startsWith("http://";) || 
content.startsWith("https://";)) {
-                // Return URL as-is, no validation needed
-                return content;
-            } else if (content.startsWith("/") || content.contains("\\")) {
-                // It's a file path
-                validateFileSize(content);
+            // A String body is ambiguous: it may be the document itself, a 
location to fetch, or a path to
+            // read. Only the content reading is unconditional; the two 
location readings must be opted into.
+            if (isRemoteSource(content)) {
+                if (!configuration.isAllowUrlSource()) {
+                    throw new IllegalArgumentException(
+                            "Message body starts with http:// or https:// but 
allowUrlSource is disabled."
+                                                       + " Set 
allowUrlSource=true to have Docling fetch it, or pass the document itself as 
the body.");
+                }
                 return content;
+            } else if (isLocalPathSource(content)) {
+                if (!configuration.isAllowFilePathSource()) {
+                    throw new IllegalArgumentException(
+                            "Message body looks like a file path but 
allowFilePathSource is disabled."
+                                                       + " Set 
allowFilePathSource=true to have Docling read it, or pass the document itself 
as the body.");
+                }
+                return validateLocalInputPath(content);
             } else {
                 // Treat as content to be written to a temp file
                 Path tempFile = Files.createTempFile("docling-", ".tmp");
                 Files.write(tempFile, content.getBytes());
                 registerTempFileCleanup(exchange, tempFile);
-                validateFileSize(tempFile.toString());
+                validateFileSizeIfPresent(tempFile.toString());
                 return tempFile.toString();
             }
         } else if (body instanceof byte[] content) {
@@ -1509,8 +1550,7 @@ public class DoclingProducer extends DefaultProducer {
             registerTempFileCleanup(exchange, tempFile);
             return tempFile.toString();
         } else if (body instanceof File file) {
-            validateFileSize(file.getAbsolutePath());
-            return file.getAbsolutePath();
+            return validateLocalInputPath(file.getAbsolutePath());
         }
 
         throw new InvalidPayloadException(exchange, String.class);
@@ -1530,7 +1570,64 @@ public class DoclingProducer extends DefaultProducer {
         });
     }
 
-    private void validateFileSize(String filePath) throws IOException {
+    /**
+     * Returns whether the given input source is a remote location that 
Docling should fetch itself, rather than
+     * something to be read from the local filesystem.
+     */
+    private static boolean isRemoteSource(String inputSource) {
+        return inputSource.startsWith("http://";) || 
inputSource.startsWith("https://";);
+    }
+
+    /**
+     * Returns whether the given String body looks like a local filesystem 
path rather than document content.
+     */
+    private static boolean isLocalPathSource(String content) {
+        return content.startsWith("/") || content.contains("\\");
+    }
+
+    /**
+     * Validates a local filesystem path used as Docling input: it must stay 
inside {@code inputBaseDirectory} when one
+     * is configured, it must exist, and it must not exceed {@code 
maxFileSize}.
+     *
+     * @return the normalized path, as a string
+     */
+    private String validateLocalInputPath(String filePath) throws IOException {
+        Path path = resolveWithinInputBaseDirectory(filePath);
+        if (!Files.exists(path)) {
+            throw new IOException("File not found: " + filePath);
+        }
+        validateFileSizeIfPresent(path.toString());
+        return path.toString();
+    }
+
+    /**
+     * Normalizes the given path and, when {@code inputBaseDirectory} is 
configured, verifies that it stays inside that
+     * directory. Normalization is lexical and the comparison is made on 
path-segment boundaries, so a sibling directory
+     * sharing a name prefix with the base directory is not accepted.
+     */
+    private Path resolveWithinInputBaseDirectory(String filePath) throws 
IOException {
+        String base = configuration.getInputBaseDirectory();
+        if (base == null || base.isEmpty()) {
+            // no directory restriction: normalize lexically only, and leave 
relative paths relative so that
+            // they keep resolving the way they did before - against the CLI 
working directory, when one is set
+            return Paths.get(filePath).normalize();
+        }
+        Path baseDir = Paths.get(base).toAbsolutePath().normalize();
+        // resolve relative paths against the base directory itself, so that 
the path checked here is exactly
+        // the path used downstream regardless of the process working directory
+        Path path = baseDir.resolve(Paths.get(filePath)).normalize();
+        if (!path.startsWith(baseDir)) {
+            throw new IOException("Input path resolves outside of 
inputBaseDirectory (" + baseDir + "): " + filePath);
+        }
+        return path;
+    }
+
+    /**
+     * Enforces {@code maxFileSize} on the given path <em>if the path 
currently resolves to something on disk</em>. A
+     * path that does not exist is not an error here - callers that require 
the input to exist must use
+     * {@link #validateLocalInputPath(String)} instead.
+     */
+    private void validateFileSizeIfPresent(String filePath) throws IOException 
{
         Path path = Paths.get(filePath);
         if (Files.exists(path)) {
             long fileSize = Files.size(path);
diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingCustomArgsValidationTest.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingCustomArgsValidationTest.java
index 43551f68d3ad..0e309ed36833 100644
--- 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingCustomArgsValidationTest.java
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingCustomArgsValidationTest.java
@@ -276,9 +276,10 @@ class DoclingCustomArgsValidationTest extends 
CamelTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() {
-                // CLI mode (useDoclingServe=false is the default)
+                // CLI mode (useDoclingServe=false is the default). These 
tests hand the input file path in
+                // the message body, which has to be opted into via 
allowFilePathSource.
                 from("direct:cli-convert")
-                        .to("docling:convert?operation=CONVERT_TO_MARKDOWN");
+                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&allowFilePathSource=true");
             }
         };
     }
diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingInputSourceValidationTest.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingInputSourceValidationTest.java
new file mode 100644
index 000000000000..7bc5681a333d
--- /dev/null
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingInputSourceValidationTest.java
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.docling;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+/**
+ * Tests that a String message body is only interpreted as a remote URL or as 
a local filesystem path when the route has
+ * explicitly opted in, and that local input paths honour {@code 
inputBaseDirectory} when one is configured.
+ */
+class DoclingInputSourceValidationTest extends CamelTestSupport {
+
+    @TempDir
+    Path tempDir;
+
+    // ------------------------------------------------------------------ URL 
bodies
+
+    @Test
+    void urlBodyIsRejectedByDefault() {
+        assertThatThrownBy(() -> template.requestBody("direct:default", 
"http://example.org/doc.pdf";))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("allowUrlSource");
+    }
+
+    @Test
+    void httpsUrlBodyIsRejectedByDefault() {
+        assertThatThrownBy(() -> template.requestBody("direct:default", 
"https://example.org/doc.pdf";))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("allowUrlSource");
+    }
+
+    @Test
+    void urlBodyPassesValidationWhenAllowed() {
+        // validation lets it through; the failure that follows comes from 
executing the (absent) docling binary,
+        // which is what proves the input-source check was not the thing that 
rejected it
+        assertThatThrownBy(() -> template.requestBody("direct:allow-url", 
"http://example.org/doc.pdf";))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isNotInstanceOf(IllegalArgumentException.class);
+    }
+
+    // ------------------------------------------------------------ file path 
bodies
+
+    @Test
+    void filePathBodyIsRejectedByDefault() throws Exception {
+        Path input = Files.writeString(tempDir.resolve("input.txt"), "hello");
+
+        assertThatThrownBy(() -> template.requestBody("direct:default", 
input.toString()))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("allowFilePathSource");
+    }
+
+    @Test
+    void windowsStyleFilePathBodyIsRejectedByDefault() {
+        assertThatThrownBy(() -> template.requestBody("direct:default", 
"C:\\docs\\input.pdf"))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("allowFilePathSource");
+    }
+
+    @Test
+    void filePathBodyPassesValidationWhenAllowed() throws Exception {
+        Path input = Files.writeString(tempDir.resolve("input.txt"), "hello");
+
+        assertThatThrownBy(() -> template.requestBody("direct:allow-path", 
input.toString()))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isNotInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    void missingFilePathBodyIsRejectedEvenWhenAllowed() {
+        // a path that does not resolve to anything on disk used to pass the 
size check silently
+        assertThatThrownBy(() -> template.requestBody("direct:allow-path", 
tempDir.resolve("absent.txt").toString()))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IOException.class)
+                .hasMessageContaining("File not found");
+    }
+
+    @Test
+    void plainContentBodyIsNotAffected() {
+        // neither a URL nor a path: still treated as the document itself, 
with no opt-in required
+        assertThatThrownBy(() -> template.requestBody("direct:default", "just 
some document text"))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isNotInstanceOf(IllegalArgumentException.class);
+    }
+
+    // ------------------------------------------------------- 
inputBaseDirectory jail
+
+    @Test
+    void filePathInsideInputBaseDirectoryIsAccepted() throws Exception {
+        Path input = Files.writeString(baseDir().resolve("inside.txt"), 
"hello");
+
+        // the docling binary is absent so execution still fails, but it must 
not fail on the jail check
+        assertThatThrownBy(() -> template.requestBody("direct:jailed", 
input.toString()))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .hasMessageNotContaining("inputBaseDirectory");
+    }
+
+    @Test
+    void filePathOutsideInputBaseDirectoryIsRejected() throws Exception {
+        Path outside = Files.writeString(tempDir.resolve("outside.txt"), 
"hello");
+
+        assertThatThrownBy(() -> template.requestBody("direct:jailed", 
outside.toString()))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IOException.class)
+                .hasMessageContaining("inputBaseDirectory");
+    }
+
+    @Test
+    void traversalOutOfInputBaseDirectoryIsRejected() throws Exception {
+        Files.writeString(tempDir.resolve("outside.txt"), "hello");
+        String traversal = 
baseDir().resolve("..").resolve("outside.txt").toString();
+
+        assertThatThrownBy(() -> template.requestBody("direct:jailed", 
traversal))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IOException.class)
+                .hasMessageContaining("inputBaseDirectory");
+    }
+
+    @Test
+    void siblingDirectorySharingANamePrefixIsRejected() throws Exception {
+        // "<base>-evil" shares a string prefix with "<base>" but is not 
inside it; a plain String.startsWith
+        // comparison would wrongly accept this
+        Path sibling = Files.createDirectories(tempDir.resolve("base-evil"));
+        Path input = Files.writeString(sibling.resolve("input.txt"), "hello");
+
+        assertThatThrownBy(() -> template.requestBody("direct:jailed", 
input.toString()))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IOException.class)
+                .hasMessageContaining("inputBaseDirectory");
+    }
+
+    // ------------------------------------------------------------------- 
header path
+
+    @Test
+    void headerPathIsNotGatedByAllowFilePathSource() throws Exception {
+        Path input = Files.writeString(tempDir.resolve("header-input.txt"), 
"hello");
+
+        // the header is an explicit "the document lives here" signal, so it 
keeps working without opting in
+        assertThatThrownBy(() -> 
template.requestBodyAndHeader("direct:default", null,
+                DoclingHeaders.INPUT_FILE_PATH, input.toString()))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isNotInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    void headerPathOutsideInputBaseDirectoryIsRejected() throws Exception {
+        Path outside = 
Files.writeString(tempDir.resolve("header-outside.txt"), "hello");
+
+        assertThatThrownBy(() -> 
template.requestBodyAndHeader("direct:jailed", null,
+                DoclingHeaders.INPUT_FILE_PATH, outside.toString()))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IOException.class)
+                .hasMessageContaining("inputBaseDirectory");
+    }
+
+    // ------------------------------------------------------------ batch 
operations
+
+    @Test
+    void batchStringBodyIsRejectedByDefault() {
+        assertThatThrownBy(() -> template.requestBody("direct:batch", 
tempDir.toString()))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("allowFilePathSource");
+    }
+
+    @Test
+    void batchTypedPathListIsNotGated() throws Exception {
+        Path input = Files.writeString(tempDir.resolve("batch-input.txt"), 
"hello");
+
+        // an explicit List<String> of paths cannot be mistaken for document 
content, so it needs no opt-in
+        assertThatThrownBy(() -> template.requestBody("direct:batch", 
List.of(input.toString())))
+                .isInstanceOf(CamelExecutionException.class)
+                .cause()
+                .isNotInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    void configurationDefaultsAreClosed() {
+        DoclingConfiguration configuration = new DoclingConfiguration();
+
+        assertThat(configuration.isAllowUrlSource()).isFalse();
+        assertThat(configuration.isAllowFilePathSource()).isFalse();
+        assertThat(configuration.getInputBaseDirectory()).isNull();
+    }
+
+    private Path baseDir() throws IOException {
+        return Files.createDirectories(tempDir.resolve("base"));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                String missingBinary = 
tempDir.resolve("no-such-docling").toString();
+
+                from("direct:default")
+                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&doclingCommand=" + 
missingBinary);
+
+                from("direct:allow-url")
+                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&allowUrlSource=true&doclingCommand="
+                            + missingBinary);
+
+                from("direct:allow-path")
+                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&allowFilePathSource=true&doclingCommand="
+                            + missingBinary);
+
+                from("direct:jailed")
+                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&allowFilePathSource=true"
+                            + "&inputBaseDirectory=" + baseDir() + 
"&doclingCommand=" + missingBinary);
+
+                // batch operations are docling-serve only; the serve call 
fails against the unused default
+                // endpoint, which is enough to show the input-source check 
let the body through
+                from("direct:batch")
+                        
.to("docling:convert?operation=BATCH_CONVERT_TO_MARKDOWN&useDoclingServe=true");
+            }
+        };
+    }
+}
diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/DoclingServeProducerIT.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/DoclingServeProducerIT.java
index 34e9ebb596f7..5c32bb9f8141 100644
--- 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/DoclingServeProducerIT.java
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/DoclingServeProducerIT.java
@@ -352,16 +352,16 @@ class DoclingServeProducerIT extends DoclingITestSupport {
             public void configure() throws Exception {
                 // Synchronous conversion routes
                 from("direct:convert-markdown-serve")
-                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true");
+                        
.to("docling:convert?allowFilePathSource=true&operation=CONVERT_TO_MARKDOWN&contentInBody=true");
 
                 from("direct:convert-html-serve")
-                        
.to("docling:convert?operation=CONVERT_TO_HTML&contentInBody=true");
+                        
.to("docling:convert?allowFilePathSource=true&operation=CONVERT_TO_HTML&contentInBody=true");
 
                 from("direct:convert-json-serve")
-                        
.to("docling:convert?operation=CONVERT_TO_JSON&contentInBody=true");
+                        
.to("docling:convert?allowFilePathSource=true&operation=CONVERT_TO_JSON&contentInBody=true");
 
                 from("direct:convert-url-serve")
-                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true");
+                        
.to("docling:convert?allowUrlSource=true&operation=CONVERT_TO_MARKDOWN&contentInBody=true");
 
                 from("direct:convert-and-write")
                         
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true")
@@ -369,23 +369,23 @@ class DoclingServeProducerIT extends DoclingITestSupport {
 
                 // Asynchronous conversion routes
                 from("direct:convert-async-markdown")
-                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=120000");
+                        
.to("docling:convert?allowFilePathSource=true&operation=CONVERT_TO_MARKDOWN&contentInBody=true&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=120000");
 
                 from("direct:convert-async-html")
-                        
.to("docling:convert?operation=CONVERT_TO_HTML&contentInBody=true&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=120000");
+                        
.to("docling:convert?allowFilePathSource=true&operation=CONVERT_TO_HTML&contentInBody=true&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=120000");
 
                 from("direct:convert-async-json")
-                        
.to("docling:convert?operation=CONVERT_TO_JSON&contentInBody=true&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=120000");
+                        
.to("docling:convert?allowFilePathSource=true&operation=CONVERT_TO_JSON&contentInBody=true&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=120000");
 
                 from("direct:convert-async-url")
-                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=120000");
+                        
.to("docling:convert?allowUrlSource=true&operation=CONVERT_TO_MARKDOWN&contentInBody=true&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=120000");
 
                 from("direct:convert-async-custom-timeout")
-                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true&useAsyncMode=true&asyncPollInterval=500&asyncTimeout=300000");
+                        
.to("docling:convert?allowFilePathSource=true&operation=CONVERT_TO_MARKDOWN&contentInBody=true&useAsyncMode=true&asyncPollInterval=500&asyncTimeout=300000");
 
                 // Custom async workflow routes
                 from("direct:submit-async")
-                        
.to("docling:convert?operation=SUBMIT_ASYNC_CONVERSION");
+                        
.to("docling:convert?allowFilePathSource=true&operation=SUBMIT_ASYNC_CONVERSION");
 
                 from("direct:check-status")
                         
.to("docling:convert?operation=CHECK_CONVERSION_STATUS");
@@ -394,7 +394,7 @@ class DoclingServeProducerIT extends DoclingITestSupport {
                 // This uses built-in async mode instead of manual polling to 
avoid complexity
                 from("direct:custom-polling-workflow")
                         .log("Starting custom polling workflow for file: 
${header.CamelDoclingInputFilePath}")
-                        
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true&" +
+                        
.to("docling:convert?allowFilePathSource=true&operation=CONVERT_TO_MARKDOWN&contentInBody=true&"
 +
                             
"useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=120000");
 
             }
diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/ExtractStructuredDataIT.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/ExtractStructuredDataIT.java
index 68268dd4b334..a5c8843bda88 100644
--- 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/ExtractStructuredDataIT.java
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/ExtractStructuredDataIT.java
@@ -130,7 +130,7 @@ class ExtractStructuredDataIT extends DoclingITestSupport {
             @Override
             public void configure() throws Exception {
                 from("direct:extract-structured-data")
-                        
.to("docling:convert?operation=EXTRACT_STRUCTURED_DATA&contentInBody=true");
+                        
.to("docling:convert?allowFilePathSource=true&operation=EXTRACT_STRUCTURED_DATA&contentInBody=true");
             }
         };
     }
diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/MetadataExtractionIT.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/MetadataExtractionIT.java
index d419182e04f7..f66eeef2fb97 100644
--- 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/MetadataExtractionIT.java
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/MetadataExtractionIT.java
@@ -252,29 +252,29 @@ class MetadataExtractionIT extends DoclingITestSupport {
             public void configure() throws Exception {
                 // Basic metadata extraction
                 from("direct:extract-metadata")
-                        .to("docling:extract?operation=EXTRACT_METADATA");
+                        
.to("docling:extract?allowFilePathSource=true&operation=EXTRACT_METADATA");
 
                 // Metadata extraction with headers enabled (default)
                 from("direct:extract-metadata-with-headers")
-                        .to("docling:extract?operation=EXTRACT_METADATA")
+                        
.to("docling:extract?allowFilePathSource=true&operation=EXTRACT_METADATA")
                         .to("mock:afterMetadataExtraction");
 
                 // Metadata extraction without headers
                 from("direct:extract-metadata-no-headers")
-                        
.to("docling:extract?operation=EXTRACT_METADATA&includeMetadataInHeaders=false")
+                        
.to("docling:extract?allowFilePathSource=true&operation=EXTRACT_METADATA&includeMetadataInHeaders=false")
                         .to("mock:afterMetadataExtraction");
 
                 // Metadata extraction with raw metadata
                 from("direct:extract-metadata-with-raw")
-                        
.to("docling:extract?operation=EXTRACT_METADATA&includeRawMetadata=true");
+                        
.to("docling:extract?allowFilePathSource=true&operation=EXTRACT_METADATA&includeRawMetadata=true");
 
                 // Metadata extraction from URL
                 from("direct:extract-metadata-url")
-                        .to("docling:extract?operation=EXTRACT_METADATA");
+                        
.to("docling:extract?allowUrlSource=true&operation=EXTRACT_METADATA");
 
                 // Metadata extraction to verify headers are populated
                 from("direct:extract-metadata-verify-headers")
-                        
.to("docling:extract?operation=EXTRACT_METADATA&includeMetadataInHeaders=true")
+                        
.to("docling:extract?allowFilePathSource=true&operation=EXTRACT_METADATA&includeMetadataInHeaders=true")
                         .log("Headers should contain metadata fields")
                         .to("mock:afterMetadataExtraction");
             }
diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
index 70755164bf96..54e0da0d3eb2 100644
--- 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
@@ -304,19 +304,19 @@ class OcrExtractionIT extends CamelTestSupport {
             public void configure() throws Exception {
                 // OCR text extraction route
                 from("direct:ocr-extract-text")
-                        
.to("docling:ocr?operation=EXTRACT_TEXT&enableOCR=true&ocrLanguage=en");
+                        
.to("docling:ocr?allowFilePathSource=true&operation=EXTRACT_TEXT&enableOCR=true&ocrLanguage=en");
 
                 // OCR to Markdown conversion
                 from("direct:ocr-convert-markdown")
-                        
.to("docling:ocr?operation=CONVERT_TO_MARKDOWN&enableOCR=true&ocrLanguage=en");
+                        
.to("docling:ocr?allowFilePathSource=true&operation=CONVERT_TO_MARKDOWN&enableOCR=true&ocrLanguage=en");
 
                 // OCR to JSON conversion
                 from("direct:ocr-convert-json")
-                        
.to("docling:ocr?operation=CONVERT_TO_JSON&enableOCR=true&ocrLanguage=en");
+                        
.to("docling:ocr?allowFilePathSource=true&operation=CONVERT_TO_JSON&enableOCR=true&ocrLanguage=en");
 
                 // OCR with async mode
                 from("direct:ocr-async-extract")
-                        
.to("docling:ocr?operation=EXTRACT_TEXT&enableOCR=true&ocrLanguage=en&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=180000");
+                        
.to("docling:ocr?allowFilePathSource=true&operation=EXTRACT_TEXT&enableOCR=true&ocrLanguage=en&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=180000");
             }
         };
     }
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/DoclingComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/DoclingComponentBuilderFactory.java
index 369368cc6262..50df3b8a4993 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/DoclingComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/DoclingComponentBuilderFactory.java
@@ -767,6 +767,47 @@ public interface DoclingComponentBuilderFactory {
         }
     
         
+        /**
+         * Whether a String message body that starts with / or contains \ is
+         * interpreted as a local filesystem path to read. When disabled, such 
a
+         * body is rejected instead of being read. This does not affect the
+         * CamelDoclingInputFilePath header, nor File, byte or explicit path
+         * collection bodies used by the batch operations.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: security
+         * 
+         * @param allowFilePathSource the value to set
+         * @return the dsl builder
+         */
+        default DoclingComponentBuilder allowFilePathSource(boolean 
allowFilePathSource) {
+            doSetProperty("allowFilePathSource", allowFilePathSource);
+            return this;
+        }
+    
+        
+        /**
+         * Whether a String message body that starts with http:// or https:// 
is
+         * interpreted as a remote URL for Docling to fetch. When disabled, 
such
+         * a body is rejected instead of being fetched. This does not affect 
the
+         * CamelDoclingInputFilePath header, nor bodies of any other type.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: security
+         * 
+         * @param allowUrlSource the value to set
+         * @return the dsl builder
+         */
+        default DoclingComponentBuilder allowUrlSource(boolean allowUrlSource) 
{
+            doSetProperty("allowUrlSource", allowUrlSource);
+            return this;
+        }
+    
+        
         /**
          * Header name for API key authentication.
          * 
@@ -816,6 +857,24 @@ public interface DoclingComponentBuilderFactory {
             return this;
         }
     
+        /**
+         * When set, every local input file path must resolve inside this
+         * directory once normalized. Applies to the CamelDoclingInputFilePath
+         * header, to file path message bodies, and to the paths used by the
+         * batch operations. When empty, no directory restriction is applied.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: security
+         * 
+         * @param inputBaseDirectory the value to set
+         * @return the dsl builder
+         */
+        default DoclingComponentBuilder inputBaseDirectory(java.lang.String 
inputBaseDirectory) {
+            doSetProperty("inputBaseDirectory", inputBaseDirectory);
+            return this;
+        }
+    
         
         /**
          * Maximum file size in bytes for processing.
@@ -895,9 +954,12 @@ public interface DoclingComponentBuilderFactory {
             case "splitBatchResults": 
getOrCreateConfiguration((DoclingComponent) 
component).setSplitBatchResults((boolean) value); return true;
             case "includeMetadataInHeaders": 
getOrCreateConfiguration((DoclingComponent) 
component).setIncludeMetadataInHeaders((boolean) value); return true;
             case "includeRawMetadata": 
getOrCreateConfiguration((DoclingComponent) 
component).setIncludeRawMetadata((boolean) value); return true;
+            case "allowFilePathSource": 
getOrCreateConfiguration((DoclingComponent) 
component).setAllowFilePathSource((boolean) value); return true;
+            case "allowUrlSource": getOrCreateConfiguration((DoclingComponent) 
component).setAllowUrlSource((boolean) value); return true;
             case "apiKeyHeader": getOrCreateConfiguration((DoclingComponent) 
component).setApiKeyHeader((java.lang.String) value); return true;
             case "authenticationScheme": 
getOrCreateConfiguration((DoclingComponent) 
component).setAuthenticationScheme((org.apache.camel.component.docling.AuthenticationScheme)
 value); return true;
             case "authenticationToken": 
getOrCreateConfiguration((DoclingComponent) 
component).setAuthenticationToken((java.lang.String) value); return true;
+            case "inputBaseDirectory": 
getOrCreateConfiguration((DoclingComponent) 
component).setInputBaseDirectory((java.lang.String) value); return true;
             case "maxFileSize": getOrCreateConfiguration((DoclingComponent) 
component).setMaxFileSize((long) value); return true;
             default: return false;
             }
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DoclingEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DoclingEndpointBuilderFactory.java
index e411b051f1d3..574c25119f89 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DoclingEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/DoclingEndpointBuilderFactory.java
@@ -469,6 +469,80 @@ public interface DoclingEndpointBuilderFactory {
             doSetProperty("includeRawMetadata", includeRawMetadata);
             return this;
         }
+        /**
+         * Whether a String message body that starts with / or contains \ is
+         * interpreted as a local filesystem path to read. When disabled, such 
a
+         * body is rejected instead of being read. This does not affect the
+         * CamelDoclingInputFilePath header, nor File, byte or explicit path
+         * collection bodies used by the batch operations.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: security
+         * 
+         * @param allowFilePathSource the value to set
+         * @return the dsl builder
+         */
+        default DoclingEndpointBuilder allowFilePathSource(boolean 
allowFilePathSource) {
+            doSetProperty("allowFilePathSource", allowFilePathSource);
+            return this;
+        }
+        /**
+         * Whether a String message body that starts with / or contains \ is
+         * interpreted as a local filesystem path to read. When disabled, such 
a
+         * body is rejected instead of being read. This does not affect the
+         * CamelDoclingInputFilePath header, nor File, byte or explicit path
+         * collection bodies used by the batch operations.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: security
+         * 
+         * @param allowFilePathSource the value to set
+         * @return the dsl builder
+         */
+        default DoclingEndpointBuilder allowFilePathSource(String 
allowFilePathSource) {
+            doSetProperty("allowFilePathSource", allowFilePathSource);
+            return this;
+        }
+        /**
+         * Whether a String message body that starts with http:// or https:// 
is
+         * interpreted as a remote URL for Docling to fetch. When disabled, 
such
+         * a body is rejected instead of being fetched. This does not affect 
the
+         * CamelDoclingInputFilePath header, nor bodies of any other type.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: security
+         * 
+         * @param allowUrlSource the value to set
+         * @return the dsl builder
+         */
+        default DoclingEndpointBuilder allowUrlSource(boolean allowUrlSource) {
+            doSetProperty("allowUrlSource", allowUrlSource);
+            return this;
+        }
+        /**
+         * Whether a String message body that starts with http:// or https:// 
is
+         * interpreted as a remote URL for Docling to fetch. When disabled, 
such
+         * a body is rejected instead of being fetched. This does not affect 
the
+         * CamelDoclingInputFilePath header, nor bodies of any other type.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: security
+         * 
+         * @param allowUrlSource the value to set
+         * @return the dsl builder
+         */
+        default DoclingEndpointBuilder allowUrlSource(String allowUrlSource) {
+            doSetProperty("allowUrlSource", allowUrlSource);
+            return this;
+        }
         /**
          * Header name for API key authentication.
          * 
@@ -532,6 +606,23 @@ public interface DoclingEndpointBuilderFactory {
             doSetProperty("authenticationToken", authenticationToken);
             return this;
         }
+        /**
+         * When set, every local input file path must resolve inside this
+         * directory once normalized. Applies to the CamelDoclingInputFilePath
+         * header, to file path message bodies, and to the paths used by the
+         * batch operations. When empty, no directory restriction is applied.
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: security
+         * 
+         * @param inputBaseDirectory the value to set
+         * @return the dsl builder
+         */
+        default DoclingEndpointBuilder inputBaseDirectory(String 
inputBaseDirectory) {
+            doSetProperty("inputBaseDirectory", inputBaseDirectory);
+            return this;
+        }
         /**
          * Maximum file size in bytes for processing.
          * 

Reply via email to