{"id":140514,"date":"2026-01-30T18:59:58","date_gmt":"2026-01-30T16:59:58","guid":{"rendered":"https:\/\/www.javacodegeeks.com\/?p=140514"},"modified":"2026-01-30T19:00:01","modified_gmt":"2026-01-30T17:00:01","slug":"an-introduction-to-using-simple-openai-in-java","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html","title":{"rendered":"An Introduction to Using simple-openai in Java"},"content":{"rendered":"<p>Modern Java applications increasingly utilise large language models for tasks such as text generation and structured data extraction; however, provider-specific SDKs can make switching vendors difficult. The <a href=\"https:\/\/github.com\/sashirestela\/simple-openai\" target=\"_blank\" rel=\"noreferrer noopener\">simple-openai<\/a> library solves this by offering a unified, type-safe Java client for OpenAI-compatible APIs across multiple providers. In this article, we build small Java apps using simple openai with Google Gemini and a free API key, following the same patterns that also apply to OpenAI and other compatible platforms.<\/p>\n<h2 class=\"wp-block-heading\">1. What is simple-openai?<\/h2>\n<p>simple-openai is a lightweight, community-driven Java HTTP client built around the OpenAI-compatible API specification. Instead of working with raw endpoints and JSON payloads, developers interact with strongly typed request and response objects that map directly to LLM features such as chat and structured outputs.<\/p>\n<p>Although the API surface follows OpenAI\u2019s standard format, the library is not limited to a single vendor. With the right configuration, the same code can communicate with Google Gemini, Azure OpenAI, Mistral, DeepSeek, Anyscale, and other compatible providers. This design keeps most application code independent of any specific model vendor, making it easier to adapt to pricing changes, regional availability, or new model releases over time.<\/p>\n<h3 class=\"wp-block-heading\">1.1 Key Capabilities of the Library<\/h3>\n<p>The goal of <em>simple-openai<\/em> is not only to wrap HTTP calls, but also to provide broad coverage of modern LLM features in a consistent Java API. It supports a wide range of functionality typically required in production systems, including text generation, embeddings, multimodal inputs, and structured data extraction.<\/p>\n<p>Beyond basic requests, the library also focuses on developer experience. It supports non-blocking calls using Java\u2019s <code>CompletableFuture<\/code>, making it suitable for reactive or highly concurrent applications. For scenarios where responses need to be consumed incrementally, such as chat UIs or streaming dashboards, streaming endpoints are also exposed through convenient abstractions.<\/p>\n<p>Another important feature is the ability to integrate custom business logic into LLM workflows using function calling and structured outputs. Instead of treating the model as a black box that only returns free-form text, applications can guide the model to return predictable JSON objects or trigger application-side functions as part of a conversation.<\/p>\n<p>In addition, the library supports multiple OpenAI-compatible providers. While not every provider exposes the same feature set, the shared API model means that switching vendors often requires only configuration changes rather than rewriting integration code.<\/p>\n<h2 class=\"wp-block-heading\">2. Project Setup and Dependencies<\/h2>\n<p>Before interacting with any LLM provider, we need a basic Java project with the required dependencies.<\/p>\n<pre class=\"brush:xml\">\n        &lt;dependency&gt;\n            &lt;groupId&gt;io.github.sashirestela&lt;\/groupId&gt;\n            &lt;artifactId&gt;simple-openai&lt;\/artifactId&gt;\n            &lt;version&gt;3.22.2&lt;\/version&gt;\n        &lt;\/dependency&gt;\n<\/pre>\n<p>This configuration adds the simple-openai client. The client handles HTTP communication internally, so no extra networking libraries are required.<\/p>\n<h2 class=\"wp-block-heading\">3. Configuring the Client for Google Gemini<\/h2>\n<p>To keep the examples easy to run, we will connect to Google Gemini using its OpenAI-compatible gateway and a free API key.<\/p>\n<div class=\"tip\"><strong>Tip<\/strong><br \/>To get a free Google Gemini API key, visit <a href=\"https:\/\/aistudio.google.com\/\">Google AI Studio<\/a> and sign in with your Google account. Click on &#8220;Get API key&#8221; in the left sidebar, then click &#8220;Create API key&#8221; to generate a key in a new or existing Google Cloud project.<\/div>\n<p><strong>Environment Variable<\/strong><\/p>\n<pre class=\"brush:bash\">\nexport GEMINI_API_KEY=your_free_gemini_api_key_here\n<\/pre>\n<p><strong>Client Factory<\/strong><\/p>\n<pre class=\"brush:java\">\npublic class OpenAIClientFactory {\n\n    private OpenAIClientFactory() {\n        throw new IllegalStateException(\"Utility class\");\n    }\n\n    public static SimpleOpenAIGeminiGoogle createGeminiClient() {\n        String apiKey = System.getenv(\"GEMINI_API_KEY\");\n\n        return SimpleOpenAIGeminiGoogle.builder()\n                .apiKey(apiKey)\n                .build();\n    }\n}\n<\/pre>\n<p>This factory class centralizes the creation of the Gemini client and keeps provider-specific configuration out of the rest of the application. It reads the API key from the GEMINI_API_KEY environment variable to avoid hard-coding sensitive credentials in source code. <\/p>\n<p>The <code>SimpleOpenAIGeminiGoogle.builder()<\/code> method applies the builder pattern, allowing the client to be configured in a clear and extensible way before it is created. By exposing a single <code>createGeminiClient<\/code> method, the application can obtain a fully configured client wherever it is needed, while making it easy to switch providers or adjust settings later without changing the calling code.<\/p>\n<h2 class=\"wp-block-heading\">4. Sending a Chat Prompt<\/h2>\n<p>Conversational text generation is the most common entry point into LLM integration. In this example, we send a short prompt to the model and display its response in the console.<\/p>\n<pre class=\"brush:java\">\npublic class ChatDemo {\n\n    public static void main(String[] args) throws ExecutionException, InterruptedException {\n\n        SimpleOpenAIGeminiGoogle client = OpenAIClientFactory.createGeminiClient();\n\n        ChatRequest request = ChatRequest.builder()\n                .model(\"gemini-2.5-flash\")\n                .messages(List.of(\n                        ChatMessage.SystemMessage.of(\"You are a helpful Java tutor.\"),\n                        ChatMessage.UserMessage.of(\"Explain what a record is in Java.\")\n                ))\n                .temperature(0.7)\n                .build();\n\n        var response = client.chatCompletions().create(request);\n        var answer = response.join();\n\n        System.out.println(\"Model response:\");\n        System.out.println(answer.firstContent());\n    }\n}\n<\/pre>\n<p>This class defines a simple console application that demonstrates how to send a chat prompt to a Gemini model using the simple-openai client. The first step inside <code>main<\/code> is obtaining a configured client instance from <code>OpenAIClientFactory.createGeminiClient()<\/code>. By delegating client creation to a factory, the application keeps authentication details and provider-specific configuration in one place. This also makes it easier to change providers or update settings without modifying the rest of the code that uses the client.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>Next, a <code>ChatRequest<\/code> is built using the builder pattern. The request specifies the model name, in this case <code>gemini-2.5-flash<\/code>, and provides a list of messages that form the conversation context. The <code>temperature<\/code> parameter controls how creative or deterministic the response should be, with moderate randomness set to <code>0.7<\/code>. The <code>build()<\/code> call finalizes the request object.<\/p>\n<p>The request is then sent using <code>client.chatCompletions().create(request)<\/code>, which returns an asynchronous result. Calling <code>join()<\/code> waits for the model to finish generating a response and retrieves the completed value.<\/p>\n<p>Finally, the code outputs the first piece of generated content from the model using <code>answer.firstContent()<\/code>. This extracts the main text produced by the assistant from the structured response object, making it easy to display within the application.<\/p>\n<p><strong>Sample Output<\/strong><\/p>\n<pre class=\"brush:plain\">\nModel response:\nOkay, let's break down what a Java `record` is.\n\n## What is a Java Record?\n\nA `record` in Java is a special kind of **class** designed specifically for **modeling immutable data**. Its primary purpose is to dramatically reduce the boilerplate code traditionally required for classes that are simply data carriers.\n\nThink of it as a concise way to declare **data-only classes** where the state is transparent and immutable.\n\n.....\n<\/pre>\n<p>The Gemini model generates all responses in accordance with the prompt provided in the chat request. The content of the response explains what a Java record is, focusing on its purpose as an immutable data carrier.<\/p>\n<h2 class=\"wp-block-heading\">5. Streaming Chat Responses<\/h2>\n<p>While a standard chat completion waits for the full response before returning, streaming allows the application to receive tokens as the model generates them. This is useful for building responsive user interfaces or any experience where partial output should be displayed immediately instead of waiting for the entire answer. <\/p>\n<p>With simple-openai, streaming follows the same request structure as normal chat completion, but the response is consumed as a stream of events rather than a single completed result.<\/p>\n<pre class=\"brush:java\">\npublic class ChatStreamingDemo {\n\n    public static void main(String[] args) {\n\n        var client = OpenAIClientFactory.createGeminiClient();\n\n        var request = ChatRequest.builder()\n                .model(\"gemini-2.5-flash\")\n                .messages(List.of(\n                        ChatMessage.SystemMessage.of(\"You are a helpful Java tutor.\"),\n                        ChatMessage.UserMessage.of(\"Explain what a record is in Java.\")\n                ))\n                .temperature(0.7)\n                .build();\n\n        var response = client.chatCompletions().createStream(request);\n        var answer = response.join();\n\n        answer.filter(chatResponse -&gt; !chatResponse.getChoices().isEmpty())\n                .map(Chat::firstContent)\n                .forEach(System.out::print);\n\n        System.out.println(\"\");\n    }\n}\n<\/pre>\n<p>The call to <code>client.chatCompletions().createStream(request)<\/code> sends the request using a streaming-capable API. Instead of returning a single completed response, it returns an asynchronous stream of partial chat responses. Calling <code>join()<\/code> waits until the stream is available and returns an object that can be processed using standard stream style operations.<\/p>\n<p>The next lines process each chunk of the streamed response. The <code>filter<\/code> step ignores any events that do not contain generated choices. The map(Chat::firstContent) step extracts the text content from each partial response, and forEach(System.out::print) immediately prints each piece to the console. This causes the model\u2019s answer to appear gradually, giving the effect of real-time text generation.<\/p>\n<h2 class=\"wp-block-heading\">6. Enforcing Structured Output<\/h2>\n<p>Free-form text is not always suitable for automation. When applications need predictable results, structured outputs allow the model to return JSON that matches a predefined schema.<\/p>\n<p><strong>Data Record<\/strong><\/p>\n<pre class=\"brush:java\">\npublic record BookRecommendation(String title, String author, int publicationYear, String reason) {\n\n}\n<\/pre>\n<p><strong>Structured Output Example<\/strong><\/p>\n<pre class=\"brush:java\">\npublic class StructuredDemo {\n\n    public static void main(String[] args) {\n\n        var client = OpenAIClientFactory.createGeminiClient();\n\n        var request = ChatRequest.builder()\n                .model(\"gemini-2.5-flash\")\n                .message(SystemMessage.of(\"You are a software engineering expert. Recommend one classic software engineering book\"))\n                .message(UserMessage.of(\"Recommend a classic software engineering book.\"))\n                .responseFormat(ResponseFormat.jsonSchema(JsonSchema.builder()\n                        .name(\"Book Recommendation\")\n                        .schemaClass(BookRecommendation.class)\n                        .build()))\n                .build();\n\n        var response = client.chatCompletions().createStream(request).join();\n\n        response.filter(chatResponse -&gt; !chatResponse.getChoices().isEmpty())\n                .map(Chat::firstContent)\n                .forEach(System.out::print);\n\n        System.out.println(\"\");\n    }\n}\n<\/pre>\n<p>This example demonstrates how to request structured output from the model using a JSON schema, ensuring that the response follows a predefined format instead of free-form text. The key part of the request is the <code>responseFormat<\/code> configuration. By using <code>ResponseFormat.jsonSchema(...)<\/code> and supplying a schema generated from the <code>BookRecommendation<\/code> class, the application instructs the model to return JSON that matches the fields of that class. This enables reliable, machine-readable responses that can be safely mapped to Java objects instead of relying on fragile text parsing.<\/p>\n<p><strong>Sample Output<\/strong><\/p>\n<p>When you run the <code>StructuredDemo<\/code> application, the console displays a JSON object that matches the structure of the <code>BookRecommendation<\/code> schema. The final output will look similar to the following:<\/p>\n<pre class=\"brush:javascript,json\">\n{\"author\": \"Frederick P. Brooks Jr.\", \n \"publicationYear\": 1975, \n \"reason\": \"This book articulates timeless principles about project management, team dynamics, and the inherent difficulties of software development. It introduces concepts like 'Brooks's Law' (adding manpower to a late software project makes it later) and the importance of conceptual integrity. Its insights remain highly relevant for anyone involved in large-scale software projects, making it a foundational text.\", \n \"title\": \"The Mythical Man-Month\"}\n<\/pre>\n<p>This output is not free-form text. Instead, it is a structured JSON document that follows the exact fields defined in the <code>BookRecommendation<\/code> class: <code>title<\/code>, <code>author<\/code>, <code>publicationYear<\/code>, and <code>reason<\/code>. Because the request included a JSON schema through <code>ResponseFormat.jsonSchema(...)<\/code>, the model was guided to format its response strictly according to that structure.<\/p>\n<h2 class=\"wp-block-heading\">7. Keeping Conversation State with Interactive Input<\/h2>\n<p>For interactive applications, conversation state becomes important because each new user input should build on everything that has already been said. Instead of sending isolated prompts, the application keeps a running history of messages and sends the full conversation to the model on every request. This allows the assistant to respond in a way that is consistent with earlier questions and answers, creating a natural multi-turn chat experience.<\/p>\n<p>Below is an example that adapts the earlier <code>ChatDemo<\/code> into an interactive program where users can type multiple questions, receive replies, and continue the conversation until they type <code>exit<\/code>.<\/p>\n<pre class=\"brush:java\">\npublic class InteractiveChatDemo {\n\n    public static void main(String[] args) {\n\n        var client = OpenAIClientFactory.createGeminiClient();\n\n        List&lt;ChatMessage&gt; conversation = new ArrayList&lt;&gt;();\n        conversation.add(ChatMessage.SystemMessage.of(\n                \"You are a helpful Java tutor. Answer clearly and briefly.\"\n        ));\n\n        try (Scanner scanner = new Scanner(System.in)) {\n\n            System.out.println(\"Start chatting with the assistant (type 'exit' to quit).\");\n\n            while (true) {\n                System.out.print(\"You: \");\n                String input = scanner.nextLine();\n\n                if (input == null || input.isBlank()) {\n                    continue;\n                }\n                if (\"exit\".equalsIgnoreCase(input.trim())) {\n                    break;\n                }\n\n                conversation.add(ChatMessage.UserMessage.of(input));\n\n                ChatRequest.ChatRequestBuilder builder\n                        = ChatRequest.builder().model(\"gemini-2.5-flash\");\n\n                for (ChatMessage message : conversation) {\n                    builder.message(message);\n                }\n\n                ChatRequest chatRequest = builder.build();\n\n                var future = client.chatCompletions().create(chatRequest);\n                var chat = future.join();\n\n                String reply = chat.firstContent().toString();\n\n                System.out.println(\"Assistant: \" + reply);\n\n                conversation.add(ChatMessage.AssistantMessage.of(reply));\n            }\n        }\n    }\n}\n<\/pre>\n<p>This example starts by creating a Gemini client using the same factory method used in earlier examples. A mutable list conversation is used to store the full conversation. The first message added is a system message that defines the assistant\u2019s role as a helpful Java tutor. This message is included in every request, ensuring the model continues to follow the same behaviour throughout the session.<\/p>\n<p>The program then enters a loop that reads user input from the console using a <code>Scanner<\/code>. Each time the user types a message, the input is validated to ensure it is not empty and checked for the <code>exit<\/code> command. If the user chooses to continue, the input is added to the conversation history as a user message.<\/p>\n<p>To build the request, a <code>ChatRequestBuilder<\/code> is created and every message in the <code>conversation<\/code> list is added to it in order. This is the key step that preserves conversation state, because the model receives not only the latest question but also all previous exchanges, allowing it to generate context-aware responses. The request is sent using <code>client.chatCompletions().create(chatRequest)<\/code>, which returns an asynchronous result.<\/p>\n<p>Finally, the assistant\u2019s reply is added back into the <code>conversation<\/code> list as an assistant message. This ensures that the next request includes both what the user said and what the assistant answered, enabling true multi-turn conversations. This same pattern can be extended to support streaming responses, logging, or persistent chat sessions stored in databases for longer-lived interactions.<\/p>\n<p><strong>Example Output<\/strong><\/p>\n<pre class=\"brush:plain\">\nStart chatting with the assistant (type 'exit' to quit).\nYou: What is a record in Java?\nAssistant: A Java record is a special type of **class** designed to act as a **transparent carrier for immutable data**.\n\nIt automatically provides:\n*   A compact syntax for declaring data-only classes.\n*   An implicit, canonical constructor.\n*   Accessor methods (getters) for its components.\n*   Implementations of `equals()`, `hashCode()`, and `toString()` based on its components.\n\nRecords significantly reduce boilerplate code for data objects that were traditionally written as plain classes with fields, constructors, and overridden methods. They were introduced in Java 16.\nYou: When should I use a record instead of a class?\nAssistant: You should use a record instead of a class primarily when:\n\n1.  **You need a simple immutable data carrier.** Records are perfect for Data Transfer Objects (DTOs), value objects, or tuples where the main purpose is to hold a fixed set of data.\n2.  **The data should not change after creation.** Records are inherently immutable. If you need mutable objects, use a regular class.\n3.  **You want to eliminate boilerplate code.** Records automatically provide the constructor, accessors, `equals()`, `hashCode()`, and `toString()` methods, drastically reducing the code you have to write for data-centric classes.\n4.  **You are representing a \"nominal tuple\" or \"product type.\"** Meaning, an object whose identity is defined solely by the values of its components.\n\n**In essence, use a record when your class is \"just data\" and you want that data to be immutable and easily comparable.** Use a regular class when you need mutable state, complex behavior, inheritance, or more control over the object's lifecycle and internal representation.\nYou: exit\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n<\/pre>\n<h2 class=\"wp-block-heading\">8. Conclusion<\/h2>\n<p>In this article, we explored how to use the simple openai library to integrate large language models into Java applications with minimal overhead. We walked through basic chat completions, real-time streaming responses, structured outputs using JSON schemas, and interactive conversations that preserve context across multiple user inputs. <\/p>\n<p>By keeping provider configuration separate from application logic and relying on consistent request and response models, simple openai makes it easier to build maintainable, vendor-independent AI features. These patterns provide a solid foundation for developing everything from simple command-line tools to more advanced, conversational and data-driven systems powered by modern LLMs.<\/p>\n<h2 class=\"wp-block-heading\">9. Download the Source Code<\/h2>\n<p>This article explored the use of the simple <a href=\"https:\/\/www.javacodegeeks.com\/spring-ai-openai-tts-example.html\" target=\"_blank\" rel=\"noreferrer noopener\">OpenAI<\/a> library in Java applications.<\/p>\n<div class=\"download\"><strong>Download<\/strong><br \/>\nYou can download the full source code of this example here: <a href=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2026\/01\/simple-openai-demo.zip\"><strong>Java simple openai<\/strong><\/a>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Modern Java applications increasingly utilise large language models for tasks such as text generation and structured data extraction; however, provider-specific SDKs can make switching vendors difficult. The simple-openai library solves this by offering a unified, type-safe Java client for OpenAI-compatible APIs across multiple providers. In this article, we build small Java apps using simple openai &hellip;<\/p>\n","protected":false},"author":128888,"featured_media":140511,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[5051,2399,5050,5052],"class_list":["post-140514","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-google-gemini","tag-large-language-models","tag-openai-api","tag-simple-openai"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>An Introduction to Using simple-openai in Java - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Build AI features in java using chat and structured outputs through the flexible simple-openai openai client library.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"An Introduction to Using simple-openai in Java - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Build AI features in java using chat and structured outputs through the flexible simple-openai openai client library.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:author\" content=\"https:\/\/web.facebook.com\/omos.aziegbe\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-30T16:59:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-01-30T17:00:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2026\/01\/simple-openai-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Omozegie Aziegbe\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/OAziegbe\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Omozegie Aziegbe\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html\"},\"author\":{\"name\":\"Omozegie Aziegbe\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/7d3eac6e45542536e961129ae0fb453e\"},\"headline\":\"An Introduction to Using simple-openai in Java\",\"datePublished\":\"2026-01-30T16:59:58+00:00\",\"dateModified\":\"2026-01-30T17:00:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html\"},\"wordCount\":1705,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/simple-openai-logo.jpg\",\"keywords\":[\"Google Gemini\",\"Large Language Models\",\"OpenAI API\",\"simple-openai\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html\",\"name\":\"An Introduction to Using simple-openai in Java - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/simple-openai-logo.jpg\",\"datePublished\":\"2026-01-30T16:59:58+00:00\",\"dateModified\":\"2026-01-30T17:00:01+00:00\",\"description\":\"Build AI features in java using chat and structured outputs through the flexible simple-openai openai client library.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/simple-openai-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/simple-openai-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/an-introduction-to-using-simple-openai-in-java.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"An Introduction to Using simple-openai in Java\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/7d3eac6e45542536e961129ae0fb453e\",\"name\":\"Omozegie Aziegbe\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2023\\\/12\\\/cropped-jcg_profile_pic-96x96.jpg\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2023\\\/12\\\/cropped-jcg_profile_pic-96x96.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2023\\\/12\\\/cropped-jcg_profile_pic-96x96.jpg\",\"caption\":\"Omozegie Aziegbe\"},\"description\":\"Omos Aziegbe is a technical writer and web\\\/application developer with a BSc in Computer Science and Software Engineering from the University of Bedfordshire. Specializing in Java enterprise applications with the Jakarta EE framework, Omos also works with HTML5, CSS, and JavaScript for web development. As a freelance web developer, Omos combines technical expertise with research and writing on topics such as software engineering, programming, web application development, computer science, and technology.\",\"sameAs\":[\"https:\\\/\\\/web.facebook.com\\\/omos.aziegbe\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/omosaziegbe\\\/\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/OAziegbe\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/omozegie-aziegbe\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"An Introduction to Using simple-openai in Java - Java Code Geeks","description":"Build AI features in java using chat and structured outputs through the flexible simple-openai openai client library.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html","og_locale":"en_US","og_type":"article","og_title":"An Introduction to Using simple-openai in Java - Java Code Geeks","og_description":"Build AI features in java using chat and structured outputs through the flexible simple-openai openai client library.","og_url":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_author":"https:\/\/web.facebook.com\/omos.aziegbe","article_published_time":"2026-01-30T16:59:58+00:00","article_modified_time":"2026-01-30T17:00:01+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2026\/01\/simple-openai-logo.jpg","type":"image\/jpeg"}],"author":"Omozegie Aziegbe","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/OAziegbe","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Omozegie Aziegbe","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html"},"author":{"name":"Omozegie Aziegbe","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/7d3eac6e45542536e961129ae0fb453e"},"headline":"An Introduction to Using simple-openai in Java","datePublished":"2026-01-30T16:59:58+00:00","dateModified":"2026-01-30T17:00:01+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html"},"wordCount":1705,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2026\/01\/simple-openai-logo.jpg","keywords":["Google Gemini","Large Language Models","OpenAI API","simple-openai"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html","url":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html","name":"An Introduction to Using simple-openai in Java - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2026\/01\/simple-openai-logo.jpg","datePublished":"2026-01-30T16:59:58+00:00","dateModified":"2026-01-30T17:00:01+00:00","description":"Build AI features in java using chat and structured outputs through the flexible simple-openai openai client library.","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2026\/01\/simple-openai-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2026\/01\/simple-openai-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/an-introduction-to-using-simple-openai-in-java.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"An Introduction to Using simple-openai in Java"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/7d3eac6e45542536e961129ae0fb453e","name":"Omozegie Aziegbe","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2023\/12\/cropped-jcg_profile_pic-96x96.jpg","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2023\/12\/cropped-jcg_profile_pic-96x96.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2023\/12\/cropped-jcg_profile_pic-96x96.jpg","caption":"Omozegie Aziegbe"},"description":"Omos Aziegbe is a technical writer and web\/application developer with a BSc in Computer Science and Software Engineering from the University of Bedfordshire. Specializing in Java enterprise applications with the Jakarta EE framework, Omos also works with HTML5, CSS, and JavaScript for web development. As a freelance web developer, Omos combines technical expertise with research and writing on topics such as software engineering, programming, web application development, computer science, and technology.","sameAs":["https:\/\/web.facebook.com\/omos.aziegbe","https:\/\/www.linkedin.com\/in\/omosaziegbe\/","https:\/\/x.com\/https:\/\/twitter.com\/OAziegbe"],"url":"https:\/\/www.javacodegeeks.com\/author\/omozegie-aziegbe"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/140514","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/128888"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=140514"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/140514\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/140511"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=140514"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=140514"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=140514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}