IBM watsonx.ai - Examples

Examples

Simple Chat

Chat with a simple string message (automatically converted to a user message):

  • Java

  • XML

  • YAML

from("direct:simpleChat")
    .setBody(constant("What is the capital of France?"))
    .to("ibm-watsonx-ai:chat?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&modelId=ibm/granite-4-h-small&operation=chat")
    .log("Response: ${body}");
<route>
  <from uri="direct:simpleChat"/>
  <setBody>
    <constant>What is the capital of France?</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:chat?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;modelId=ibm/granite-4-h-small&amp;operation=chat"/>
  <log message="Response: ${body}"/>
</route>
- route:
    from:
      uri: direct:simpleChat
      steps:
        - setBody:
            constant: "What is the capital of France?"
        - to:
            uri: ibm-watsonx-ai:chat
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              modelId: ibm/granite-4-h-small
              operation: chat
        - log:
            message: "Response: ${body}"

Chat with System Message

Use a system message to control the assistant’s behavior:

  • Java

  • XML

  • YAML

from("direct:chatWithSystem")
    .setHeader("CamelIBMWatsonxAiSystemMessage",
        constant("You are a helpful assistant. Keep your answers brief."))
    .setBody(constant("What is the capital of Italy?"))
    .to("ibm-watsonx-ai:chat?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&modelId=ibm/granite-4-h-small&operation=chat")
    .log("Response: ${body}");
<route>
  <from uri="direct:chatWithSystem"/>
  <setHeader name="CamelIBMWatsonxAiSystemMessage">
    <constant>You are a helpful assistant. Keep your answers brief.</constant>
  </setHeader>
  <setBody>
    <constant>What is the capital of Italy?</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:chat?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;modelId=ibm/granite-4-h-small&amp;operation=chat"/>
  <log message="Response: ${body}"/>
</route>
- route:
    from:
      uri: direct:chatWithSystem
      steps:
        - setHeader:
            name: CamelIBMWatsonxAiSystemMessage
            constant: "You are a helpful assistant. Keep your answers brief."
        - setBody:
            constant: "What is the capital of Italy?"
        - to:
            uri: ibm-watsonx-ai:chat
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              modelId: ibm/granite-4-h-small
              operation: chat
        - log:
            message: "Response: ${body}"

Streaming Chat

Stream chat responses with a callback consumer:

Java-only: uses Consumer<String> callback and UserMessage SDK type
import com.ibm.watsonx.ai.chat.model.UserMessage;

from("direct:streamChat")
  .process(exchange -> {
      // Set up a consumer to handle streamed chunks
      Consumer<String> streamHandler = chunk -> {
          System.out.print(chunk);
      };
      exchange.getIn().setHeader("CamelIBMWatsonxAiStreamConsumer", streamHandler);
      exchange.getIn().setHeader("CamelIBMWatsonxAiMessages", List.of(
          UserMessage.text("Tell me a joke about programming")
      ));
  })
  .to("ibm-watsonx-ai:chat?apiKey=RAW(yourApiKey)" +
      "&baseUrl=https://us-south.ml.cloud.ibm.com" +
      "&projectId=yourProjectId" +
      "&modelId=ibm/granite-4-h-small" +
      "&operation=chatStreaming")
  .log("Full response: ${body}");

Streaming Chat with WebSocket

Stream chat responses to WebSocket clients in real-time, similar to ChatGPT’s streaming UI. This example uses the camel-vertx-websocket component to receive messages from clients and stream responses back token-by-token:

  • Java

from("vertx-websocket:localhost:8080/chat")
    // Store connection key for sending responses back to this specific client
    .setProperty("connectionKey", header(VertxWebsocketConstants.CONNECTION_KEY))
    .process(exchange -> {
        String connectionKey = exchange.getProperty("connectionKey", String.class);
        ProducerTemplate producer = exchange.getContext().createProducerTemplate();

        // Stream consumer that sends each token as a WebSocket message
        Consumer<String> streamHandler = chunk -> {
            producer.sendBodyAndHeader(
                "vertx-websocket:localhost:8080/chat",
                chunk,
                VertxWebsocketConstants.CONNECTION_KEY, connectionKey
            );
        };
        exchange.getIn().setHeader(WatsonxAiConstants.STREAM_CONSUMER, streamHandler);
    })
    .setHeader(WatsonxAiConstants.SYSTEM_MESSAGE, constant("You are a helpful assistant."))
    // The WebSocket message body becomes the user question
    .to("ibm-watsonx-ai:chat?apiKey=RAW(yourApiKey)" +
        "&baseUrl=https://us-south.ml.cloud.ibm.com" +
        "&projectId=yourProjectId" +
        "&modelId=ibm/granite-4-h-small" +
        "&operation=chatStreaming")
    // Send completion marker to client
    .process(exchange -> {
        String connectionKey = exchange.getProperty("connectionKey", String.class);
        exchange.getContext().createProducerTemplate().sendBodyAndHeader(
            "vertx-websocket:localhost:8080/chat",
            "[DONE]",
            VertxWebsocketConstants.CONNECTION_KEY, connectionKey
        );
    });

This pattern enables building real-time chat applications where:

  • WebSocket clients connect and send messages

  • Each token from the LLM is streamed back immediately

  • Clients receive a [DONE] marker when the response is complete

Requires the camel-vertx-websocket dependency. See the Vert.x WebSocket component documentation for more details.

Chat with Tool Calling

Enable the LLM to call external tools (like Wikipedia search) and incorporate results into the conversation. This example shows a fully declarative route with no processors required:

  • Java

  • YAML

import com.ibm.watsonx.ai.chat.ToolRegistry;
import com.ibm.watsonx.ai.chat.model.Tool;
import com.ibm.watsonx.ai.tool.ToolService;
import com.ibm.watsonx.ai.tool.builtin.WikipediaTool;

// Create ToolService for utility tools (requires wxUrl)
ToolService toolService = ToolService.builder()
    .apiKey(apiKey)
    .baseUrl("https://api.dataplatform.cloud.ibm.com/wx")
    .build();

// Create ToolRegistry with Wikipedia tool
ToolRegistry toolRegistry = ToolRegistry.builder()
    .register(new WikipediaTool(toolService))
    .build();

// Get tool schemas for chat
List<Tool> tools = toolRegistry.tools();

from("direct:chatWithTools")
    // Set system message, tools, and registry via headers (body is the user question)
    .setHeader("CamelIBMWatsonxAiSystemMessage",
        constant("You are a helpful assistant. Use available tools when needed."))
    .setHeader("CamelIBMWatsonxAiTools", constant(tools))
    .setHeader("CamelIBMWatsonxAiToolRegistry", constant(toolRegistry))
    // Send to chat
    .to("ibm-watsonx-ai:chat?apiKey=RAW(yourApiKey)" +
        "&baseUrl=https://us-south.ml.cloud.ibm.com" +
        "&projectId=yourProjectId" +
        "&modelId=ibm/granite-3-8b-instruct" +
        "&operation=chat")
    // Loop while LLM requests tool calls
    .loopDoWhile(simple("${header.CamelIBMWatsonxAiHasToolCalls} == true"))
        .log("Executing tool calls...")
        // Process tool calls using the dedicated operation
        .to("ibm-watsonx-ai:tools?operation=processToolCalls")
        // Continue conversation with tool results
        .to("ibm-watsonx-ai:chat?apiKey=RAW(yourApiKey)" +
            "&baseUrl=https://us-south.ml.cloud.ibm.com" +
            "&projectId=yourProjectId" +
            "&modelId=ibm/granite-3-8b-instruct" +
            "&operation=chat")
    .end()
    .log("Final response: ${body}");
- route:
    from:
      uri: direct:chatWithTools
      steps:
      - setHeader:
          name: CamelIBMWatsonxAiSystemMessage
          constant: "You are a helpful assistant. Use available tools when needed."
      - setHeader:
          name: CamelIBMWatsonxAiTools
          constant: "{{tools}}"
      - setHeader:
          name: CamelIBMWatsonxAiToolRegistry
          constant: "{{toolRegistry}}"
      - to:
          uri: ibm-watsonx-ai:chat
          parameters:
            apiKey: "RAW({{ibm.watsonx.api-key}})"
            baseUrl: "{{ibm.watsonx.base-url}}"
            projectId: "{{ibm.watsonx.project-id}}"
            modelId: ibm/granite-3-8b-instruct
            operation: chat
      - loop:
          id: loop-4459
          doWhile: true
          expression:
            simple:
              expression: ${header.CamelIBMWatsonxAiHasToolCalls} == true
          steps:
            - log:
                message: Executing tool calls...
            - to:
                uri: ibm-watsonx-ai:tools
                parameters:
                  operation: processToolCalls
            - to:
                uri: ibm-watsonx-ai:chat
                parameters:
                  apiKey: RAW({{ibm.watsonx.api-key}})
                  baseUrl: "{{ibm.watsonx.base-url}}"
                  modelId: ibm/granite-3-8b-instruct
                  operation: chat
                  projectId: "{{ibm.watsonx.project-id}}"
      - log:
          message: "Final response: ${body}"

The above route:

  1. Sets the system message via CamelIBMWatsonxAiSystemMessage header

  2. The message body becomes the user question automatically

  3. Sets tools and registry via headers for function calling

  4. Uses processToolCalls operation to execute tools and update the conversation

  5. Loops until the LLM provides a final answer without tool calls

Tool operations require the wxUrl configuration (e.g., https://api.dataplatform.cloud.ibm.com/wx), which is different from the ML baseUrl.

Text Embeddings

Generate embeddings for semantic search and similarity:

Java-only: uses List.of() for batch input and process lambda for typed result handling
from("direct:embed")
  .setBody(constant(List.of(
      "Apache Camel is an integration framework",
      "Quarkus is a Java framework"
  )))
  .to("ibm-watsonx-ai:embed?apiKey=RAW(yourApiKey)" +
      "&baseUrl=https://us-south.ml.cloud.ibm.com" +
      "&projectId=yourProjectId" +
      "&modelId=ibm/slate-125m-english-rtrvr" +
      "&operation=embedding")
  .process(exchange -> {
      List<List<Float>> embeddings = exchange.getMessage().getBody(List.class);
      System.out.println("Generated " + embeddings.size() + " embeddings");
      System.out.println("Embedding dimensions: " + embeddings.get(0).size());
  });

Single Text Embedding

Generate embedding for a single text input:

  • Java

  • XML

  • YAML

from("direct:embedSingle")
    .setBody(constant("Apache Camel makes integration easy"))
    .to("ibm-watsonx-ai:embed?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&modelId=ibm/slate-125m-english-rtrvr&operation=embedding")
    .log("Embedding vector size: ${header.CamelIBMWatsonxAiEmbeddings[0].size()}");
<route>
  <from uri="direct:embedSingle"/>
  <setBody>
    <constant>Apache Camel makes integration easy</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:embed?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;modelId=ibm/slate-125m-english-rtrvr&amp;operation=embedding"/>
  <log message="Embedding vector size: ${header.CamelIBMWatsonxAiEmbeddings[0].size()}"/>
</route>
- route:
    from:
      uri: direct:embedSingle
      steps:
        - setBody:
            constant: "Apache Camel makes integration easy"
        - to:
            uri: ibm-watsonx-ai:embed
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              modelId: ibm/slate-125m-english-rtrvr
              operation: embedding
        - log:
            message: "Embedding vector size: ${header.CamelIBMWatsonxAiEmbeddings[0].size()}"

Embedding with Vector Database (Qdrant)

Generate an embedding and store it in a Qdrant vector database for semantic search:

Java-only: uses Qdrant SDK types (Points.PointStruct, VectorsFactory, etc.) for vector construction
import org.apache.camel.component.qdrant.QdrantHeaders;
import org.apache.camel.component.qdrant.QdrantAction;
import io.qdrant.client.PointIdFactory;
import io.qdrant.client.VectorsFactory;
import io.qdrant.client.ValueFactory;
import io.qdrant.client.grpc.Points;

from("direct:embedAndStore")
  .setBody(constant("Apache Camel makes integration easy"))
  .to("ibm-watsonx-ai:embed?apiKey=RAW(yourApiKey)" +
      "&baseUrl=https://us-south.ml.cloud.ibm.com" +
      "&projectId=yourProjectId" +
      "&modelId=ibm/slate-125m-english-rtrvr" +
      "&operation=embedding")
  // Transform to Qdrant format and upsert
  .setHeader(QdrantHeaders.ACTION, constant(QdrantAction.UPSERT))
  .process(exchange -> {
      List<Float> embedding = exchange.getMessage().getBody(List.class);
      exchange.getMessage().setBody(
          Points.PointStruct.newBuilder()
              .setId(PointIdFactory.id(UUID.randomUUID()))
              .setVectors(VectorsFactory.vectors(embedding))
              .putPayload("text", ValueFactory.value("Apache Camel makes integration easy"))
              .build());
  })
  .to("qdrant:embeddings?host=localhost&port=6334")
  .log("Embedding stored with ID: ${header.CamelQdrantOperationID}");
This example requires the camel-qdrant dependency. See the Qdrant component documentation for more details.

Rerank Documents

Rerank documents by relevance to a query:

Java-only: uses process lambda with List.of() for document input
from("direct:rerank")
  .process(exchange -> {
      // Set the query to rank against
      exchange.getIn().setHeader("CamelIBMWatsonxAiRerankQuery",
          "What is the best integration framework?");
      // Set documents to rerank
      exchange.getIn().setBody(List.of(
          "Apache Camel provides enterprise integration patterns.",
          "Quarkus is great for microservices.",
          "Kubernetes orchestrates containers.",
          "Apache Kafka handles event streaming."
      ));
  })
  .to("ibm-watsonx-ai:rerank?apiKey=RAW(yourApiKey)" +
      "&baseUrl=https://us-south.ml.cloud.ibm.com" +
      "&projectId=yourProjectId" +
      "&modelId=cross-encoder/ms-marco-minilm-l-12-v2" +
      "&operation=rerank")
  .process(exchange -> {
      List results = exchange.getMessage().getBody(List.class);
      System.out.println("Reranked results: " + results);
  });

Rerank with Top N

Return only the top N most relevant documents:

Java-only: uses List.of() for document input
from("direct:rerankTopN")
  .setHeader("CamelIBMWatsonxAiRerankQuery", constant("Cloud computing platform"))
  .setHeader("CamelIBMWatsonxAiRerankTopN", constant(3))
  .setBody(constant(List.of(
      "AWS is a cloud computing platform.",
      "Azure provides cloud services.",
      "IBM Cloud offers cloud solutions.",
      "PostgreSQL is a database.",
      "Infinispan is an in-memory store."
  )))
  .to("ibm-watsonx-ai:rerank?apiKey=RAW(yourApiKey)" +
      "&baseUrl=https://us-south.ml.cloud.ibm.com" +
      "&projectId=yourProjectId" +
      "&modelId=cross-encoder/ms-marco-minilm-l-12-v2" +
      "&operation=rerank")
  .log("Top 3 results: ${body}");

Tokenization

Count tokens in text (useful for context window management):

  • Java

  • XML

  • YAML

from("direct:tokenize")
    .setBody(constant("Hello, how are you today?"))
    .to("ibm-watsonx-ai:tokenize?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&modelId=ibm/granite-4-h-small&operation=tokenize")
    .log("Token count: ${header.CamelIBMWatsonxAiTokenCount}")
    .log("Tokens: ${header.CamelIBMWatsonxAiTokens}");
<route>
  <from uri="direct:tokenize"/>
  <setBody>
    <constant>Hello, how are you today?</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:tokenize?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;modelId=ibm/granite-4-h-small&amp;operation=tokenize"/>
  <log message="Token count: ${header.CamelIBMWatsonxAiTokenCount}"/>
  <log message="Tokens: ${header.CamelIBMWatsonxAiTokens}"/>
</route>
- route:
    from:
      uri: direct:tokenize
      steps:
        - setBody:
            constant: "Hello, how are you today?"
        - to:
            uri: ibm-watsonx-ai:tokenize
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              modelId: ibm/granite-4-h-small
              operation: tokenize
        - log:
            message: "Token count: ${header.CamelIBMWatsonxAiTokenCount}"
        - log:
            message: "Tokens: ${header.CamelIBMWatsonxAiTokens}"

Content Detection (PII/HAP)

Detect personally identifiable information (PII) and harmful/abusive/profane (HAP) content:

  • Java

  • XML

  • YAML

from("direct:detect")
    .setBody(constant("Contact John Smith at john.smith@example.com or call 555-123-4567"))
    .to("ibm-watsonx-ai:detect?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&operation=detect&detectPii=true")
    .choice()
        .when(header("CamelIBMWatsonxAiDetected").isEqualTo(true))
            .log("PII detected! Count: ${header.CamelIBMWatsonxAiDetectionCount}")
            .log("Detection details: ${header.CamelIBMWatsonxAiDetectionResults}")
        .otherwise()
            .log("No PII detected in content")
    .end();
<route>
  <from uri="direct:detect"/>
  <setBody>
    <constant>Contact John Smith at john.smith@example.com or call 555-123-4567</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:detect?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;operation=detect&amp;detectPii=true"/>
  <choice>
    <when>
      <simple>${header.CamelIBMWatsonxAiDetected} == true</simple>
      <log message="PII detected! Count: ${header.CamelIBMWatsonxAiDetectionCount}"/>
      <log message="Detection details: ${header.CamelIBMWatsonxAiDetectionResults}"/>
    </when>
    <otherwise>
      <log message="No PII detected in content"/>
    </otherwise>
  </choice>
</route>
- route:
    from:
      uri: direct:detect
      steps:
        - setBody:
            constant: "Contact John Smith at john.smith@example.com or call 555-123-4567"
        - to:
            uri: ibm-watsonx-ai:detect
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              operation: detect
              detectPii: true
        - choice:
            when:
              - simple: "${header.CamelIBMWatsonxAiDetected} == true"
                steps:
                  - log:
                      message: "PII detected! Count: ${header.CamelIBMWatsonxAiDetectionCount}"
                  - log:
                      message: "Detection details: ${header.CamelIBMWatsonxAiDetectionResults}"
            otherwise:
              steps:
                - log:
                    message: "No PII detected in content"

Content Detection with HAP Threshold

Detect harmful content with a custom threshold:

  • Java

  • XML

  • YAML

from("direct:detectHap")
    .setBody(constant("Some text that might contain harmful content"))
    .to("ibm-watsonx-ai:detect?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&operation=detect&detectHap=true&detectionThreshold=0.5")
    .choice()
        .when(header("CamelIBMWatsonxAiDetected").isEqualTo(true))
            .log("ALERT: Harmful content detected!")
        .otherwise()
            .log("Content is safe")
    .end();
<route>
  <from uri="direct:detectHap"/>
  <setBody>
    <constant>Some text that might contain harmful content</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:detect?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;operation=detect&amp;detectHap=true&amp;detectionThreshold=0.5"/>
  <choice>
    <when>
      <simple>${header.CamelIBMWatsonxAiDetected} == true</simple>
      <log message="ALERT: Harmful content detected!"/>
    </when>
    <otherwise>
      <log message="Content is safe"/>
    </otherwise>
  </choice>
</route>
- route:
    from:
      uri: direct:detectHap
      steps:
        - setBody:
            constant: "Some text that might contain harmful content"
        - to:
            uri: ibm-watsonx-ai:detect
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              operation: detect
              detectHap: true
              detectionThreshold: 0.5
        - choice:
            when:
              - simple: "${header.CamelIBMWatsonxAiDetected} == true"
                steps:
                  - log:
                      message: "ALERT: Harmful content detected!"
            otherwise:
              steps:
                - log:
                    message: "Content is safe"

Content Detection with Custom Detectors

Provide custom detectors via header:

Java-only: uses watsonx.ai SDK detector types (Pii, Hap)
import com.ibm.watsonx.ai.detection.detector.Pii;
import com.ibm.watsonx.ai.detection.detector.Hap;

from("direct:detectCustom")
  .process(exchange -> {
      exchange.getIn().setBody("Check this email: user@domain.com");
      exchange.getIn().setHeader("CamelIBMWatsonxAiDetectors", List.of(
          Pii.ofDefaults(),
          Hap.builder().threshold(0.3).build()
      ));
  })
  .to("ibm-watsonx-ai:detect?apiKey=RAW(yourApiKey)" +
      "&baseUrl=https://us-south.ml.cloud.ibm.com" +
      "&projectId=yourProjectId" +
      "&operation=detect")
  .log("Detections: ${body}");

Text Extraction from Cloud Object Storage

Extract text from documents stored in IBM Cloud Object Storage:

This operation requires COS configuration including cosUrl, documentConnectionId, documentBucket, resultConnectionId, and resultBucket.
  • Java

  • XML

  • YAML

from("direct:extract")
    .setBody(constant("documents/report.pdf"))
    .to("ibm-watsonx-ai:extract?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&operation=textExtraction&cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&documentConnectionId=your-cos-connection-id&documentBucket=your-input-bucket&resultConnectionId=your-cos-connection-id&resultBucket=your-output-bucket")
    .log("Extraction job started: ${header.CamelIBMWatsonxAiExtractionId}")
    .log("Status: ${header.CamelIBMWatsonxAiExtractionStatus}");
<route>
  <from uri="direct:extract"/>
  <setBody>
    <constant>documents/report.pdf</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:extract?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;operation=textExtraction&amp;cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&amp;documentConnectionId=your-cos-connection-id&amp;documentBucket=your-input-bucket&amp;resultConnectionId=your-cos-connection-id&amp;resultBucket=your-output-bucket"/>
  <log message="Extraction job started: ${header.CamelIBMWatsonxAiExtractionId}"/>
  <log message="Status: ${header.CamelIBMWatsonxAiExtractionStatus}"/>
</route>
- route:
    from:
      uri: direct:extract
      steps:
        - setBody:
            constant: "documents/report.pdf"
        - to:
            uri: ibm-watsonx-ai:extract
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              operation: textExtraction
              cosUrl: "https://s3.us-south.cloud-object-storage.appdomain.cloud"
              documentConnectionId: your-cos-connection-id
              documentBucket: your-input-bucket
              resultConnectionId: your-cos-connection-id
              resultBucket: your-output-bucket
        - log:
            message: "Extraction job started: ${header.CamelIBMWatsonxAiExtractionId}"
        - log:
            message: "Status: ${header.CamelIBMWatsonxAiExtractionStatus}"

Fetch Text Extraction Results

Poll for extraction completion and get results:

  • Java

  • XML

  • YAML

from("direct:fetchExtraction")
    .setHeader("CamelIBMWatsonxAiExtractionId", constant("your-extraction-job-id"))
    .to("ibm-watsonx-ai:extract?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&operation=textExtractionFetch&cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&documentConnectionId=your-cos-connection-id&documentBucket=your-input-bucket&resultConnectionId=your-cos-connection-id&resultBucket=your-output-bucket")
    .log("Extraction status: ${header.CamelIBMWatsonxAiExtractionStatus}");
<route>
  <from uri="direct:fetchExtraction"/>
  <setHeader name="CamelIBMWatsonxAiExtractionId">
    <constant>your-extraction-job-id</constant>
  </setHeader>
  <to uri="ibm-watsonx-ai:extract?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;operation=textExtractionFetch&amp;cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&amp;documentConnectionId=your-cos-connection-id&amp;documentBucket=your-input-bucket&amp;resultConnectionId=your-cos-connection-id&amp;resultBucket=your-output-bucket"/>
  <log message="Extraction status: ${header.CamelIBMWatsonxAiExtractionStatus}"/>
</route>
- route:
    from:
      uri: direct:fetchExtraction
      steps:
        - setHeader:
            name: CamelIBMWatsonxAiExtractionId
            constant: "your-extraction-job-id"
        - to:
            uri: ibm-watsonx-ai:extract
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              operation: textExtractionFetch
              cosUrl: "https://s3.us-south.cloud-object-storage.appdomain.cloud"
              documentConnectionId: your-cos-connection-id
              documentBucket: your-input-bucket
              resultConnectionId: your-cos-connection-id
              resultBucket: your-output-bucket
        - log:
            message: "Extraction status: ${header.CamelIBMWatsonxAiExtractionStatus}"

Upload and Extract Local Files (Synchronous)

Upload a local file and get extracted text synchronously using textExtractionUploadAndFetch:

  • Java

  • XML

  • YAML

from("file:/path/to/documents?noop=true")
    .to("ibm-watsonx-ai:extract?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&operation=textExtractionUploadAndFetch&cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&documentConnectionId=your-cos-connection-id&documentBucket=your-input-bucket&resultConnectionId=your-cos-connection-id&resultBucket=your-output-bucket")
    .log("Extracted text: ${body}")
    .log("File processed: ${header.CamelFileName}");
<route>
  <from uri="file:/path/to/documents?noop=true"/>
  <to uri="ibm-watsonx-ai:extract?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;operation=textExtractionUploadAndFetch&amp;cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&amp;documentConnectionId=your-cos-connection-id&amp;documentBucket=your-input-bucket&amp;resultConnectionId=your-cos-connection-id&amp;resultBucket=your-output-bucket"/>
  <log message="Extracted text: ${body}"/>
  <log message="File processed: ${header.CamelFileName}"/>
</route>
- route:
    from:
      uri: file:/path/to/documents
      parameters:
        noop: true
      steps:
        - to:
            uri: ibm-watsonx-ai:extract
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              operation: textExtractionUploadAndFetch
              cosUrl: "https://s3.us-south.cloud-object-storage.appdomain.cloud"
              documentConnectionId: your-cos-connection-id
              documentBucket: your-input-bucket
              resultConnectionId: your-cos-connection-id
              resultBucket: your-output-bucket
        - log:
            message: "Extracted text: ${body}"
        - log:
            message: "File processed: ${header.CamelFileName}"

This operation:

  1. Automatically handles File, GenericFile (from file://, ftp://, sftp://), InputStream, or byte[] body types

  2. Uploads the file to COS

  3. Starts text extraction

  4. Polls until completion

  5. Returns the extracted text as the message body (also available in CamelIBMWatsonxAiExtractedText header)

Text Extraction with File Components

The text extraction operations integrate seamlessly with Camel file components:

Java-only: illustrative snippets showing various file source integrations
// From local file system
from("file:/documents/incoming?noop=true")
  .to("ibm-watsonx-ai:extract?operation=textExtractionUploadAndFetch...")
  .log("Extracted text from ${header.CamelFileName}: ${body}");

// From FTP/SFTP
from("sftp://server/documents?username=xxx&password=xxx")
  .to("ibm-watsonx-ai:extract?operation=textExtractionUploadAndFetch...")
  .log("Extracted: ${header.CamelIBMWatsonxAiExtractedText}");

// From AWS S3
from("aws2-s3://my-bucket?region=us-east-1&prefix=docs/")
  .to("ibm-watsonx-ai:extract?operation=textExtractionUploadAndFetch...")
  .log("Extracted text from S3 object");

// From Azure Blob Storage
from("azure-storage-blob://mycontainer?prefix=documents/")
  .to("ibm-watsonx-ai:extract?operation=textExtractionUploadAndFetch...")
  .log("Extracted text from blob");

Document Classification

Text classification operations allow you to classify documents using IBM watsonx.ai’s document processing capabilities. These operations require Cloud Object Storage (COS) configuration.

The COS connection in your watsonx.ai project must be configured with HMAC credentials (access_key_id and secret_access_key), not just IAM Service Credentials. See COS Connection Setup for details.

Classify Documents from Cloud Object Storage

Classify documents already stored in Cloud Object Storage:

  • Java

  • XML

  • YAML

from("direct:classify")
    .setBody(constant("documents/contract.pdf"))
    .to("ibm-watsonx-ai:classify?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&operation=textClassification&cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&documentConnectionId=your-cos-connection-id&documentBucket=your-input-bucket")
    .log("Classification job started: ${header.CamelIBMWatsonxAiClassificationId}");
<route>
  <from uri="direct:classify"/>
  <setBody>
    <constant>documents/contract.pdf</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:classify?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;operation=textClassification&amp;cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&amp;documentConnectionId=your-cos-connection-id&amp;documentBucket=your-input-bucket"/>
  <log message="Classification job started: ${header.CamelIBMWatsonxAiClassificationId}"/>
</route>
- route:
    from:
      uri: direct:classify
      steps:
        - setBody:
            constant: "documents/contract.pdf"
        - to:
            uri: ibm-watsonx-ai:classify
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              operation: textClassification
              cosUrl: "https://s3.us-south.cloud-object-storage.appdomain.cloud"
              documentConnectionId: your-cos-connection-id
              documentBucket: your-input-bucket
        - log:
            message: "Classification job started: ${header.CamelIBMWatsonxAiClassificationId}"

Upload and Classify Local Files (Synchronous)

Upload a local file and get classification results synchronously using textClassificationUploadAndFetch:

  • Java

  • XML

  • YAML

from("file:/path/to/documents?noop=true")
    .to("ibm-watsonx-ai:classify?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&operation=textClassificationUploadAndFetch&cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&documentConnectionId=your-cos-connection-id&documentBucket=your-input-bucket")
    .log("Document type: ${header.CamelIBMWatsonxAiClassificationResult}")
    .log("Document classified: ${header.CamelIBMWatsonxAiDocumentClassified}");
<route>
  <from uri="file:/path/to/documents?noop=true"/>
  <to uri="ibm-watsonx-ai:classify?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;operation=textClassificationUploadAndFetch&amp;cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&amp;documentConnectionId=your-cos-connection-id&amp;documentBucket=your-input-bucket"/>
  <log message="Document type: ${header.CamelIBMWatsonxAiClassificationResult}"/>
  <log message="Document classified: ${header.CamelIBMWatsonxAiDocumentClassified}"/>
</route>
- route:
    from:
      uri: file:/path/to/documents
      parameters:
        noop: true
      steps:
        - to:
            uri: ibm-watsonx-ai:classify
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              operation: textClassificationUploadAndFetch
              cosUrl: "https://s3.us-south.cloud-object-storage.appdomain.cloud"
              documentConnectionId: your-cos-connection-id
              documentBucket: your-input-bucket
        - log:
            message: "Document type: ${header.CamelIBMWatsonxAiClassificationResult}"
        - log:
            message: "Document classified: ${header.CamelIBMWatsonxAiDocumentClassified}"

This operation:

  1. Automatically handles File, GenericFile (from file://, ftp://, sftp://), InputStream, or byte[] body types

  2. Uploads the file to COS

  3. Starts classification

  4. Polls until completion

  5. Returns the classification result

Upload and Classify (Asynchronous with Polling)

For more control, use the async flow with textClassificationUpload and textClassificationFetch in a single route with polling loop:

Java-only: complex async polling pattern with loopDoWhile, delay, exchangeProperty, and `choice`
// Start classification and poll until complete
from("direct:startClassification")
  .to("ibm-watsonx-ai:classify?operation=textClassificationUpload" +
      "&apiKey=RAW(yourApiKey)" +
      "&baseUrl=https://us-south.ml.cloud.ibm.com" +
      "&projectId=yourProjectId" +
      "&cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud" +
      "&documentConnectionId=your-cos-connection-id" +
      "&documentBucket=your-input-bucket")
  .log("Classification started - ID: ${header.CamelIBMWatsonxAiClassificationId}")
  .setProperty("classificationId", header("CamelIBMWatsonxAiClassificationId"))
  // Poll until complete or failed
  .loopDoWhile(simple("${header.CamelIBMWatsonxAiClassificationStatus} != 'completed' && ${header.CamelIBMWatsonxAiClassificationStatus} != 'failed'"))
    .delay(2000)
    .setHeader("CamelIBMWatsonxAiClassificationId", exchangeProperty("classificationId"))
    .to("ibm-watsonx-ai:classify?operation=textClassificationFetch" +
        "&apiKey=RAW(yourApiKey)" +
        "&baseUrl=https://us-south.ml.cloud.ibm.com" +
        "&projectId=yourProjectId" +
        "&cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud" +
        "&documentConnectionId=your-cos-connection-id" +
        "&documentBucket=your-input-bucket")
    .log("Status: ${header.CamelIBMWatsonxAiClassificationStatus}")
  .end()
  .choice()
    .when(header("CamelIBMWatsonxAiClassificationStatus").isEqualTo("completed"))
      .log("Classification result: ${header.CamelIBMWatsonxAiClassificationResult}")
    .otherwise()
      .log("Classification failed: ${header.CamelIBMWatsonxAiErrorMessage}")
  .end();

Classification with File Components

The classification operations integrate seamlessly with Camel file components:

Java-only: illustrative snippets showing various file source integrations
// From local file system
from("file:/documents/incoming?noop=true")
  .to("ibm-watsonx-ai:classify?operation=textClassificationUploadAndFetch...")
  .log("Classified ${header.CamelFileName} as ${header.CamelIBMWatsonxAiClassificationResult}");

// From FTP/SFTP
from("sftp://server/documents?username=xxx&password=xxx")
  .to("ibm-watsonx-ai:classify?operation=textClassificationUploadAndFetch...")
  .log("Classified: ${header.CamelIBMWatsonxAiClassificationResult}");

// From AWS S3
from("aws2-s3://my-bucket?region=us-east-1&prefix=docs/")
  .to("ibm-watsonx-ai:classify?operation=textClassificationUploadAndFetch...")
  .log("Classified S3 object: ${header.CamelIBMWatsonxAiClassificationResult}");

// From Azure Blob Storage
from("azure-storage-blob://mycontainer?prefix=documents/")
  .to("ibm-watsonx-ai:classify?operation=textClassificationUploadAndFetch...")
  .log("Classified blob: ${header.CamelIBMWatsonxAiClassificationResult}");

Delete Classification Request

Clean up a classification job:

  • Java

  • XML

  • YAML

from("direct:deleteClassification")
    .setBody(constant("classification-job-id"))
    .to("ibm-watsonx-ai:classify?operation=textClassificationDeleteRequest&apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&documentConnectionId=your-cos-connection-id&documentBucket=your-input-bucket")
    .log("Delete success: ${header.CamelIBMWatsonxAiDeleteSuccess}");
<route>
  <from uri="direct:deleteClassification"/>
  <setBody>
    <constant>classification-job-id</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:classify?operation=textClassificationDeleteRequest&amp;apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;cosUrl=https://s3.us-south.cloud-object-storage.appdomain.cloud&amp;documentConnectionId=your-cos-connection-id&amp;documentBucket=your-input-bucket"/>
  <log message="Delete success: ${header.CamelIBMWatsonxAiDeleteSuccess}"/>
</route>
- route:
    from:
      uri: direct:deleteClassification
      steps:
        - setBody:
            constant: "classification-job-id"
        - to:
            uri: ibm-watsonx-ai:classify
            parameters:
              operation: textClassificationDeleteRequest
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              cosUrl: "https://s3.us-south.cloud-object-storage.appdomain.cloud"
              documentConnectionId: your-cos-connection-id
              documentBucket: your-input-bucket
        - log:
            message: "Delete success: ${header.CamelIBMWatsonxAiDeleteSuccess}"

Supported File Types

Text classification supports the following input file types:

  • Documents: PDF, DOC, DOCX, PPT, PPTX, XLSX

  • Images: BMP, GIF, JFIF, JPG, PNG, TIFF

  • Text: HTML, Markdown

For complete details on supported file formats, see:

Supported Foundation Models for Classification

  • mistral-small-3-1-24b-instruct-2503 (certified for key-value pair classification)

  • llama-4-maverick-17b-128e-instruct-fp8

  • mistral-medium-2505

For the latest list of supported models, see the IBM watsonx.ai Text Classification documentation.

Using Input Header

Provide input via header instead of body:

  • Java

  • XML

  • YAML

from("direct:headerInput")
    .setHeader("CamelIBMWatsonxAiInput", constant("What is machine learning?"))
    .to("ibm-watsonx-ai:gen?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&modelId=ibm/granite-13b-instruct-v2&operation=textGeneration")
    .log("Generated text: ${body}");
<route>
  <from uri="direct:headerInput"/>
  <setHeader name="CamelIBMWatsonxAiInput">
    <constant>What is machine learning?</constant>
  </setHeader>
  <to uri="ibm-watsonx-ai:gen?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;modelId=ibm/granite-13b-instruct-v2&amp;operation=textGeneration"/>
  <log message="Generated text: ${body}"/>
</route>
- route:
    from:
      uri: direct:headerInput
      steps:
        - setHeader:
            name: CamelIBMWatsonxAiInput
            constant: "What is machine learning?"
        - to:
            uri: ibm-watsonx-ai:gen
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              modelId: ibm/granite-13b-instruct-v2
              operation: textGeneration
        - log:
            message: "Generated text: ${body}"

Accessing Response Metadata

Access token counts and stop reason from response headers:

  • Java

  • XML

  • YAML

from("direct:metadata")
    .setBody(constant("Summarize the benefits of cloud computing"))
    .to("ibm-watsonx-ai:gen?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&projectId=yourProjectId&modelId=ibm/granite-13b-instruct-v2&operation=textGeneration")
    .log("Generated: ${body}")
    .log("Input tokens: ${header.CamelIBMWatsonxAiInputTokenCount}")
    .log("Output tokens: ${header.CamelIBMWatsonxAiOutputTokenCount}")
    .log("Stop reason: ${header.CamelIBMWatsonxAiStopReason}");
<route>
  <from uri="direct:metadata"/>
  <setBody>
    <constant>Summarize the benefits of cloud computing</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:gen?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;projectId=yourProjectId&amp;modelId=ibm/granite-13b-instruct-v2&amp;operation=textGeneration"/>
  <log message="Generated: ${body}"/>
  <log message="Input tokens: ${header.CamelIBMWatsonxAiInputTokenCount}"/>
  <log message="Output tokens: ${header.CamelIBMWatsonxAiOutputTokenCount}"/>
  <log message="Stop reason: ${header.CamelIBMWatsonxAiStopReason}"/>
</route>
- route:
    from:
      uri: direct:metadata
      steps:
        - setBody:
            constant: "Summarize the benefits of cloud computing"
        - to:
            uri: ibm-watsonx-ai:gen
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              projectId: yourProjectId
              modelId: ibm/granite-13b-instruct-v2
              operation: textGeneration
        - log:
            message: "Generated: ${body}"
        - log:
            message: "Input tokens: ${header.CamelIBMWatsonxAiInputTokenCount}"
        - log:
            message: "Output tokens: ${header.CamelIBMWatsonxAiOutputTokenCount}"
        - log:
            message: "Stop reason: ${header.CamelIBMWatsonxAiStopReason}"

Time Series Forecasting

Generate time series forecasts:

Java-only: uses watsonx.ai SDK types (InputSchema, ForecastData) for time series data construction
import com.ibm.watsonx.ai.timeseries.InputSchema;
import com.ibm.watsonx.ai.timeseries.ForecastData;

from("direct:forecast")
  .process(exchange -> {
      // Define the schema
      InputSchema schema = InputSchema.builder()
          .timestampColumn("date")
          .addIdColumn("series_id")
          .build();

      // Create forecast data
      ForecastData data = ForecastData.create()
          .addAll("date", "2024-01-01T00:00:00", "2024-01-02T00:00:00", "2024-01-03T00:00:00")
          .add("series_id", "S1", 3)
          .addAll("value", 10.5, 12.3, 11.8);

      exchange.getIn().setHeader("CamelIBMWatsonxAiForecastInputSchema", schema);
      exchange.getIn().setHeader("CamelIBMWatsonxAiForecastData", data);
  })
  .to("ibm-watsonx-ai:forecast?apiKey=RAW(yourApiKey)" +
      "&baseUrl=https://us-south.ml.cloud.ibm.com" +
      "&projectId=yourProjectId" +
      "&modelId=ibm/granite-ttm-1536-96-r2" +
      "&operation=forecast")
  .log("Forecast results: ${body}");

List Available Models

Explore the model catalog:

  • Java

  • XML

  • YAML

from("direct:listModels")
    .to("ibm-watsonx-ai:models?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&operation=listModels")
    .log("Available models: ${body}");
<route>
  <from uri="direct:listModels"/>
  <to uri="ibm-watsonx-ai:models?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;operation=listModels"/>
  <log message="Available models: ${body}"/>
</route>
- route:
    from:
      uri: direct:listModels
      steps:
        - to:
            uri: ibm-watsonx-ai:models
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              operation: listModels
        - log:
            message: "Available models: ${body}"

List Supported Tasks

Discover available tasks:

  • Java

  • XML

  • YAML

from("direct:listTasks")
    .to("ibm-watsonx-ai:tasks?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&operation=listTasks")
    .log("Available tasks: ${body}");
<route>
  <from uri="direct:listTasks"/>
  <to uri="ibm-watsonx-ai:tasks?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;operation=listTasks"/>
  <log message="Available tasks: ${body}"/>
</route>
- route:
    from:
      uri: direct:listTasks
      steps:
        - to:
            uri: ibm-watsonx-ai:tasks
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              operation: listTasks
        - log:
            message: "Available tasks: ${body}"

Deployment Chat

Chat using a deployed model:

  • Java

  • XML

  • YAML

from("direct:deploymentChat")
    .setBody(constant("What is the capital of France?"))
    .to("ibm-watsonx-ai:deploy?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&deploymentId=your-deployment-id&operation=deploymentChat")
    .log("Response: ${body}");
<route>
  <from uri="direct:deploymentChat"/>
  <setBody>
    <constant>What is the capital of France?</constant>
  </setBody>
  <to uri="ibm-watsonx-ai:deploy?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;deploymentId=your-deployment-id&amp;operation=deploymentChat"/>
  <log message="Response: ${body}"/>
</route>
- route:
    from:
      uri: direct:deploymentChat
      steps:
        - setBody:
            constant: "What is the capital of France?"
        - to:
            uri: ibm-watsonx-ai:deploy
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              deploymentId: your-deployment-id
              operation: deploymentChat
        - log:
            message: "Response: ${body}"

Run Utility Tool

Use watsonx.ai utility tools (experimental):

Java-only: uses process lambda with Map.of() for tool input and config
from("direct:runTool")
  .process(exchange -> {
      // Set tool name
      exchange.getIn().setHeader("CamelIBMWatsonxAiToolName", "GoogleSearch");
      // Set structured input
      exchange.getIn().setBody(Map.of("q", "Apache Camel integration framework"));
      // Optional: set config
      exchange.getIn().setHeader("CamelIBMWatsonxAiToolConfig", Map.of("maxResults", 5));
  })
  .to("ibm-watsonx-ai:tool?apiKey=RAW(yourApiKey)" +
      "&baseUrl=https://us-south.ml.cloud.ibm.com" +
      "&operation=runTool")
  .log("Tool result: ${body}");

List Available Tools

Discover available utility tools:

  • Java

  • XML

  • YAML

from("direct:listTools")
    .to("ibm-watsonx-ai:tools?apiKey=RAW(yourApiKey)&baseUrl=https://us-south.ml.cloud.ibm.com&operation=listTools")
    .log("Available tools: ${body}");
<route>
  <from uri="direct:listTools"/>
  <to uri="ibm-watsonx-ai:tools?apiKey=RAW(yourApiKey)&amp;baseUrl=https://us-south.ml.cloud.ibm.com&amp;operation=listTools"/>
  <log message="Available tools: ${body}"/>
</route>
- route:
    from:
      uri: direct:listTools
      steps:
        - to:
            uri: ibm-watsonx-ai:tools
            parameters:
              apiKey: "RAW(yourApiKey)"
              baseUrl: "https://us-south.ml.cloud.ibm.com"
              operation: listTools
        - log:
            message: "Available tools: ${body}"