# openai-java
**Repository Path**: jasoncjs/openai-java
## Basic Information
- **Project Name**: openai-java
- **Description**: The OpenAI Java API Library is currently in beta.
There may be minor breaking changes.
Have thoughts or feedback? File an issue or comment on this thread.
Maven Central javadoc
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: docs/more-examples
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-02-12
- **Last Updated**: 2025-02-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# OpenAI Java API Library
> [!NOTE]
> The OpenAI Java API Library is currently in _beta_.
>
> There may be frequent breaking changes.
>
> Have thoughts or feedback? [File an issue](https://github.com/openai/openai-java/issues/new) or comment on [this thread](https://community.openai.com/t/your-feedback-requested-java-sdk/1061029).
[](https://central.sonatype.com/artifact/com.openai/openai-java/0.14.1)
[](https://javadoc.io/doc/com.openai/openai-java/0.14.1)
The OpenAI Java SDK provides convenient access to the OpenAI REST API from applications written in Java.
The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are also available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/0.0.1).
## Installation
### Gradle
```kotlin
implementation("com.openai:openai-java:0.14.1")
```
### Maven
```xml
com.openai
openai-java
0.14.1
```
## Requirements
This library requires Java 8 or later.
## Usage
See the [`openai-java-example`](openai-java-example/src/main/java/com/openai/example) directory for complete and runnable examples.
### Configure the client
Use `OpenAIOkHttpClient.builder()` to configure the client. At a minimum you need to set `.apiKey()`:
```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
OpenAIClient client = OpenAIOkHttpClient.builder()
.apiKey("My API Key")
.build();
```
Alternately, set the environment with `OPENAI_API_KEY`, `OPENAI_ORG_ID` or `OPENAI_PROJECT_ID`, and use `OpenAIOkHttpClient.fromEnv()` to read from the environment.
```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
OpenAIClient client = OpenAIOkHttpClient.fromEnv();
// Note: you can also call fromEnv() from the client builder, for example if you need to set additional properties
OpenAIClient client = OpenAIOkHttpClient.builder()
.fromEnv()
// ... set properties on the builder
.build();
```
| Property | Environment variable | Required | Default value |
| ------------ | -------------------- | -------- | ------------- |
| apiKey | `OPENAI_API_KEY` | true | — |
| organization | `OPENAI_ORG_ID` | false | — |
| project | `OPENAI_PROJECT_ID` | false | — |
Read the documentation for more configuration options.
---
### Example: creating a resource
To create a new chat completion, first use the `ChatCompletionCreateParams` builder to specify attributes, then pass that to the `create` method of the `completions` service.
```java
import com.openai.models.ChatCompletion;
import com.openai.models.ChatCompletionCreateParams;
import com.openai.models.ChatCompletionUserMessageParam;
import com.openai.models.ChatModel;
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.addMessage(ChatCompletionUserMessageParam.builder()
.content("Say this is a test")
.build())
.model(ChatModel.O1)
.build();
ChatCompletion chatCompletion = client.chat().completions().create(params);
```
### Example: listing resources
The OpenAI API provides a `list` method to get a paginated list of jobs. You can retrieve the first page by:
```java
import com.openai.models.FineTuningJob;
import com.openai.models.FineTuningJobListPage;
FineTuningJobListPage page = client.fineTuning().jobs().list();
for (FineTuningJob job : page.data()) {
System.out.println(job);
}
```
Use the `FineTuningJobListParams` builder to set parameters:
```java
import com.openai.models.FineTuningJobListPage;
import com.openai.models.FineTuningJobListParams;
FineTuningJobListParams params = FineTuningJobListParams.builder()
.after("after")
.limit(20L)
.build();
FineTuningJobListPage page1 = client.fineTuning().jobs().list(params);
// Using the `from` method of the builder you can reuse previous params values:
FineTuningJobListPage page2 = client.fineTuning().jobs().list(FineTuningJobListParams.builder()
.from(params)
.build());
// Or easily get params for the next page by using the helper `getNextPageParams`:
FineTuningJobListPage page3 = client.fineTuning().jobs().list(params.getNextPageParams(page2));
```
See [Pagination](#pagination) below for more information on transparently working with lists of objects without worrying about fetching each page.
---
## Requests
### Parameters and bodies
To make a request to the OpenAI API, you generally build an instance of the appropriate `Params` class.
In [Example: creating a resource](#example-creating-a-resource) above, we used the `ChatCompletionCreateParams.builder()` to pass to the `create` method of the `completions` service.
Sometimes, the API may support other properties that are not yet supported in the Java SDK types. In that case, you can attach them using the `putAdditionalProperty` method.
```java
import com.openai.core.JsonValue;
import com.openai.models.ChatCompletionCreateParams;
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
// ... normal properties
.putAdditionalProperty("secret_param", JsonValue.from("4242"))
.build();
```
## Responses
### Response validation
When receiving a response, the OpenAI Java SDK will deserialize it into instances of the typed model classes. In rare cases, the API may return a response property that doesn't match the expected Java type. If you directly access the mistaken property, the SDK will throw an unchecked `OpenAIInvalidDataException` at runtime. If you would prefer to check in advance that that response is completely well-typed, call `.validate()` on the returned model.
```java
import com.openai.models.ChatCompletion;
ChatCompletion chatCompletion = client.chat().completions().create().validate();
```
### Response properties as JSON
In rare cases, you may want to access the underlying JSON value for a response property rather than using the typed version provided by this SDK. Each model property has a corresponding JSON version, with an underscore before the method name, which returns a `JsonField` value.
```java
import com.openai.core.JsonField;
import java.util.Optional;
JsonField field = responseObj._field();
if (field.isMissing()) {
// Value was not specified in the JSON response
} else if (field.isNull()) {
// Value was provided as a literal null
} else {
// See if value was provided as a string
Optional jsonString = field.asString();
// If the value given by the API did not match the shape that the SDK expects
// you can deserialise into a custom type
MyClass myObj = responseObj._field().asUnknown().orElseThrow().convert(MyClass.class);
}
```
### Additional model properties
Sometimes, the server response may include additional properties that are not yet available in this library's types. You can access them using the model's `_additionalProperties` method:
```java
import com.openai.core.JsonValue;
JsonValue secret = errorObject._additionalProperties().get("secret_field");
```
---
## Pagination
For methods that return a paginated list of results, this library provides convenient ways access the results either one page at a time, or item-by-item across all pages.
### Auto-pagination
To iterate through all results across all pages, you can use `autoPager`, which automatically handles fetching more pages for you:
### Synchronous
```java
import com.openai.models.FineTuningJob;
import com.openai.models.FineTuningJobListPage;
// As an Iterable:
FineTuningJobListPage page = client.fineTuning().jobs().list(params);
for (FineTuningJob job : page.autoPager()) {
System.out.println(job);
};
// As a Stream:
client.fineTuning().jobs().list(params).autoPager().stream()
.limit(50)
.forEach(job -> System.out.println(job));
```
### Asynchronous
```java
// Using forEach, which returns CompletableFuture:
asyncClient.fineTuning().jobs().list(params).autoPager()
.forEach(job -> System.out.println(job), executor);
```
### Manual pagination
If none of the above helpers meet your needs, you can also manually request pages one-by-one. A page of results has a `data()` method to fetch the list of objects, as well as top-level `response` and other methods to fetch top-level data about the page. It also has methods `hasNextPage`, `getNextPage`, and `getNextPageParams` methods to help with pagination.
```java
import com.openai.models.FineTuningJob;
import com.openai.models.FineTuningJobListPage;
FineTuningJobListPage page = client.fineTuning().jobs().list(params);
while (page != null) {
for (FineTuningJob job : page.data()) {
System.out.println(job);
}
page = page.getNextPage().orElse(null);
}
```
---
## Error handling
This library throws exceptions in a single hierarchy for easy handling:
- **`OpenAIException`** - Base exception for all exceptions
- **`OpenAIServiceException`** - HTTP errors with a well-formed response body we were able to parse. The exception message and the `.debuggingRequestId()` will be set by the server.
| 400 | BadRequestException |
| ------ | ----------------------------- |
| 401 | AuthenticationException |
| 403 | PermissionDeniedException |
| 404 | NotFoundException |
| 422 | UnprocessableEntityException |
| 429 | RateLimitException |
| 5xx | InternalServerException |
| others | UnexpectedStatusCodeException |
- **`OpenAIIoException`** - I/O networking errors
- **`OpenAIInvalidDataException`** - any other exceptions on the client side, e.g.:
- We failed to serialize the request body
- We failed to parse the response body (has access to response code and body)
## Microsoft Azure OpenAI
To use this library with [Azure OpenAI](https://learn.microsoft.com/azure/ai-services/openai/overview), use the same
OpenAI client builder but with the Azure-specific configuration.
```java
OpenAIClient client = OpenAIOkHttpClient.builder()
// Gets the API key from the `AZURE_OPENAI_KEY` environment variable
.fromEnv()
// Set the Azure Entra ID
.credential(BearerTokenCredential.create(AuthenticationUtil.getBearerTokenSupplier(
new DefaultAzureCredentialBuilder().build(), "https://cognitiveservices.azure.com/.default")))
.build();
```
See the complete Azure OpenAI example in the [`openai-java-example`](openai-java-example/src/main/java/com/openai/example/AzureEntraIdExample.java) directory. The other examples in the directory also work with Azure as long as the client is configured to use it.
## Network options
### Retries
Requests that experience certain errors are automatically retried 2 times by default, with a short exponential backoff. Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict, 429 Rate Limit, and >=500 Internal errors will all be retried by default. You can provide a `maxRetries` on the client builder to configure this:
```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
OpenAIClient client = OpenAIOkHttpClient.builder()
.fromEnv()
.maxRetries(4)
.build();
```
### Timeouts
Requests time out after 10 minutes by default. You can configure this on the client builder:
```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import java.time.Duration;
OpenAIClient client = OpenAIOkHttpClient.builder()
.fromEnv()
.timeout(Duration.ofSeconds(30))
.build();
```
### Proxies
Requests can be routed through a proxy. You can configure this on the client builder:
```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import java.net.InetSocketAddress;
import java.net.Proxy;
OpenAIClient client = OpenAIOkHttpClient.builder()
.fromEnv()
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("example.com", 8080)))
.build();
```
## Making custom/undocumented requests
This library is typed for convenient access to the documented API. If you need to access undocumented params or response properties, the library can still be used.
### Undocumented request params
To make requests using undocumented parameters, you can provide or override parameters on the params object while building it.
```java
FooCreateParams address = FooCreateParams.builder()
.id("my_id")
.putAdditionalProperty("secret_prop", JsonValue.from("hello"))
.build();
```
### Undocumented response properties
To access undocumented response properties, you can use `res._additionalProperties()` on a response object to get a map of untyped fields of type `Map`. You can then access fields like `._additionalProperties().get("secret_prop").asString()` or use other helpers defined on the `JsonValue` class to extract it to a desired type.
## Logging
We use the standard [OkHttp logging interceptor](https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor).
You can enable logging by setting the environment variable `OPENAI_LOG` to `info`.
```sh
$ export OPENAI_LOG=info
```
Or to `debug` for more verbose logging.
```sh
$ export OPENAI_LOG=debug
```
## Semantic versioning
This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
1. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_
2. Changes that we do not expect to impact the vast majority of users in practice.
We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
We are keen for your feedback; please open an [issue](https://www.github.com/openai/openai-java/issues) with questions, bugs, or suggestions.