OpenAI OpenAPI Specification - Kotlin
From https://github.com/openai/openai-openapi/blob/master/openapi.yaml
NOTES:
- There is https://github.com/openai/openai-java, which OpenAI describes as
"The official Java library for the OpenAI API", but:
- That "official" library lags behind https://github.com/openai/openai-openapi/blob/master/openapi.yaml
For example, as of 2025/02/12 is is STILL lacking OpenAI's Realtime API (https://platform.openai.com/docs/api-reference/realtime), which is my main use case. openai-javais actually a nearly fully modernized Kotlin library, so the nameopenai-javais legacy;
it really should be namedopenai-kotlin.
 - That "official" library lags behind https://github.com/openai/openai-openapi/blob/master/openapi.yaml
 - I was initially tempted to inflate this repo to contain multiple openapi-generator generated languages, but for now I am limiting it to Kotlin.
 - openapi-generator has >4k open Issues:
https://github.com/OpenAPITools/openapi-generator/issues
So, no promises about the quality of its output.
Maybe one day I will open a PR to auto-generate some of the changes I made manually. 
Requirements:
- OpenAPI Generator: https://openapi-generator.tech/docs/installation
 
Optional:
curl -o openapi-YYYYMMDD.yaml https://raw.githubusercontent.com/openai/openai-openapi/refs/heads/master/openapi.yaml
You don't have to do this.
openapi-generator supports fetching the specification directly from a url.
I prefer to save a snapshot of the specification that was used for the generation.
time openapi-generator generate -i openapi-YYYYMMDD.yaml -g kotlin -o ./lib --skip-validate-spec --additional-properties=artifactId=openai-kotlin-client,artifactVersion=0.0.1,groupId=com.openai,packageName=com.openai
(< 5 seconds on MacBook Pro M4 Pro)cp lib/build.gradle .mv lib/gradle* lib/settings.gradle .echo -e "\ninclude(\":lib\")" >> settings.gradle- Edit 
build.gradleto be a project file andlib/build.gradleto be a module file. chmod +x ./gradlew./gradlew build
(< 20 seconds on MacBook Pro M4 Pro to [eventually; see "Changes"] successfully compile from clean)
All of this is also shown in the openai-kotlin-client.sh file.
At this point, the build will actually fail.
I had to make some manual changes in order to get it to compile successfully:
- AudioApi.kt:
- change 
AudioResponseFormat? = jsontoAudioResponseFormat? = AudioResponseFormat.json - change 
timestampGranularities?.valuetotimestampGranularities 
 - change 
 - remove 
data(data class ...->class ...) in:- CreateAssistantRequestToolResourcesFileSearch.kt
 - CreateThreadRequestToolResourcesFileSearch.kt
 
 
This just got it to COMPILE successfully!
I had to make further changes in order to get it to RUN successfully.
All of my changes can be seen at:
https://github.com/swooby/openai-openapi-kotlin/pull/1/files
When a new spec comes out:
- Make sure to start from a fresh/stashed checkout.
 rm -r ./lib/srccurl -o openapi-YYYYMMDD.yaml https://raw.githubusercontent.com/openai/openai-openapi/refs/heads/master/openapi.yamlopenapi-generator generate -i openapi-YYYYMMDD.yaml -g kotlin -o ./lib --skip-validate-spec --additional-properties=artifactId=openai-kotlin-client,artifactVersion=0.0.1,groupId=com.openai,packageName=com.openai- Fix generated gradle files:
mv lib/build.gradle lib/build.gradle.ktsrm -f ./gradle && mv lib/gradle* .mv lib/settings.gradle ./settings.gradle.kts- Compare/Review with the settings.gradle and build.gradle files.
gradle*: probably discard all changessettings.gradle.kts: probably discard all changeslib/build.gradle.kts: probably discard all changes
 - While you are here, update any dependencies in 
gradle/libs.versions.toml 
 - Consistently format all generated code with 
./gradlew spotlessApply - Fix generated code compiler errors:
TODO: Open an OpenAPI or OpenAI bug on these...apis/AudioApi- add/keep 
AudioResponseFormat.json - add/keep 
timestampGranularities?.value 
- add/keep 
 models/CreateAssistantRequestToolResourcesFileSearch: keep non-data class
(compiler error to have data class with no constructor parameters)models/CreateThreadRequestToolResourcesFileSearch: keep non-data class
(compiler error to have data class with no constructor parameters)
 - Review each changed file, especially ones that show as modified in:
https://github.com/swooby/openai-openapi-kotlin/pull/1/filesapis&docs: probably keep all changesinfrastructure:ApiClient.kt: probably discard all changesBigDecimalAdapter.kt: probably discard all changesBigIntegerAdapter.kt: probably discard all changesSerializer.kt: probably discard all changes
models: probably keep all changes except...Realtime*files:
(This can get a little complicated...)RealtimeClientEvent*: Keep alltype: RealtimeClientEvent*.Type = RealtimeClientEvent*.Type....one-line assignments
These help a lot to simplify sending client events.RealtimeConversationItem- add/keep 
in_progressin nestedStatus; undocumented value comes from the server 
- add/keep 
 RealtimeConversationItemContentInner- add/keep 
audioin nestedType; undocumented value comes from the server 
- add/keep 
 RealtimeResponse- change/keep 
maxOutputTokensto typeRealtimeSessionMaxResponseOutputTokens - add/keep 
in_progressin nestedStatus; undocumented value comes from the server 
- change/keep 
 RealtimeResponseCreateParams- change/keep 
maxResponseOutputTokensto typeRealtimeSessionMaxResponseOutputTokens 
- change/keep 
 RealtimeResponseCreateParamsConversation- add/keep 
enum class ... auto, none ... 
- add/keep 
 - move 
RealtimeResponseCreateParamsMaxResponseOutputTokensto commonRealtimeSessionMaxResponseOutputTokens
This empty class would cause a runtime deserialization exception. - move 
RealtimeResponseMaxOutputTokensto commonRealtimeSessionMaxResponseOutputTokensThis empty class would cause a runtime deserialization exception. RealtimeServerEventConversationItemCreated- add/keep nullable 
previousItemId; null value comes from the server 
- add/keep nullable 
 RealtimeServerEventInputAudioBufferCommitted:- add/keep nullable 
previousItemId; null value comes from the server 
- add/keep nullable 
 RealtimeSessionmodel- add/keep javadoc
 - change/keep type to 
kotlin.String? 
- change/keep 
maxResponseOutputTokensto typeRealtimeSessionMaxResponseOutputTokens 
RealtimeSessionCreateRequest- add/keep 
@SerializeNull - change/keep 
maxResponseOutputTokensto typeRealtimeSessionMaxResponseOutputTokens - nested 
enum class Model- change/keep javadoc
 - change/keep 
gpt-4o-realtime-preview ...simplification;
The generated names leave outgpt-4o-. 
 
- add/keep 
 RealtimeSessionCreateRequestInputAudioTranscription- add/keep nested 
enum class Model whisper-1 ... - change/keep 
modelto nestedModel 
- add/keep nested 
 RealtimeSessionCreateRequestTurnDetection- add/keep nested 
enum class Type server_vad ... - change/keep 
typeto nestedType 
- add/keep nested 
 RealtimeSessionCreateResponse- change/keep 
maxResponseOutputTokensto typeRealtimeSessionMaxResponseOutputTokens 
- change/keep 
 - restore/reset/keep 
RealtimeSessionMaxResponseOutputTokens - delete 
RealtimeSessionModel
This empty class would cause a runtime deserialization exception. 
test: probably keep all changes except...- revert 
RealtimeResponseCreateParamsMaxResponseOutputTokensTest
detected as a rename fromRealtimeSessionMaxResponseOutputTokensTest - delete 
RealtimeResponseMaxOutputTokensTest - delete 
RealtimeSessionModelTest 
- revert