diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+1.1.0:
+
+- BREAKING CHANGE: Fix details representations for various types [[#44](https://github.com/MercuryTechnologies/openai/pull/44)] [[#45](https://github.com/MercuryTechnologies/openai/pull/45)] [[#50](https://github.com/MercuryTechnologies/openai/pull/50)] [[#51](https://github.com/MercuryTechnologies/openai/pull/51)]
+
+  A few details-related fields were fixed to match the behavior of the OpenAI
+  API.
+
+- Add `FromJSON`/`ToJSON` instances for all types [[#42](https://github.com/MercuryTechnologies/openai/pull/42)] [[#47](https://github.com/MercuryTechnologies/openai/pull/47)]
+
+- [Add support for `reasoning_effort` parameter in chat completions](https://github.com/MercuryTechnologies/openai/pull/48)
+
 1.0.1:
 
 - Include `README`
diff --git a/openai.cabal b/openai.cabal
--- a/openai.cabal
+++ b/openai.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               openai
-version:            1.0.1
+version:            1.1.0
 synopsis:           Servant bindings to OpenAI
 description:        This package provides comprehensive and type-safe bindings
                     to OpenAI, providing both a Servant interface and
diff --git a/src/OpenAI/V1/Assistants.hs b/src/OpenAI/V1/Assistants.hs
--- a/src/OpenAI/V1/Assistants.hs
+++ b/src/OpenAI/V1/Assistants.hs
@@ -49,6 +49,9 @@
     , response_format :: Maybe (AutoOr ResponseFormat)
     } deriving stock (Generic, Show)
 
+instance FromJSON CreateAssistant where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON CreateAssistant where
     toJSON = genericToJSON aesonOptions
 
@@ -80,6 +83,9 @@
     , response_format :: Maybe (AutoOr ResponseFormat)
     } deriving stock (Generic, Show)
 
+instance FromJSON ModifyAssistant where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON ModifyAssistant where
     toJSON = genericToJSON aesonOptions
 
@@ -113,7 +119,7 @@
     , top_p :: Maybe Double
     , response_format :: AutoOr ResponseFormat
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Audio/Speech.hs b/src/OpenAI/V1/Audio/Speech.hs
--- a/src/OpenAI/V1/Audio/Speech.hs
+++ b/src/OpenAI/V1/Audio/Speech.hs
@@ -21,6 +21,9 @@
 data Voice = Alloy | Echo | Fable | Onyx | Nova | Shimmer
     deriving stock (Bounded, Enum, Generic, Show)
 
+instance FromJSON Voice where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON Voice where
     toJSON = genericToJSON aesonOptions
 
@@ -28,6 +31,9 @@
 data Format = MP3 | Opus | AAC | FLAC | WAV | PCM
     deriving stock (Bounded, Enum, Generic, Show)
 
+instance FromJSON Format where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON Format where
     toJSON = genericToJSON aesonOptions
 
@@ -39,7 +45,7 @@
     , response_format :: Maybe Format
     , speed :: Maybe Double
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateSpeech`
 _CreateSpeech :: CreateSpeech
diff --git a/src/OpenAI/V1/Audio/Transcriptions.hs b/src/OpenAI/V1/Audio/Transcriptions.hs
--- a/src/OpenAI/V1/Audio/Transcriptions.hs
+++ b/src/OpenAI/V1/Audio/Transcriptions.hs
@@ -26,6 +26,7 @@
     , prompt :: Maybe Text
     , temperature :: Maybe Double
     } deriving stock (Generic, Show)
+      deriving anyclass (FromJSON, ToJSON)
 
 instance ToMultipart Tmp CreateTranscription where
     toMultipart CreateTranscription{ model = Model model, ..} =
@@ -67,7 +68,7 @@
     , compression_ratio :: Double
     , no_speech_prob :: Double
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Represents a verbose json transcription response returned by model, based
 -- on the provided input.
@@ -77,7 +78,7 @@
     , text :: Text
     , segments :: Vector Segment
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Audio/Translations.hs b/src/OpenAI/V1/Audio/Translations.hs
--- a/src/OpenAI/V1/Audio/Translations.hs
+++ b/src/OpenAI/V1/Audio/Translations.hs
@@ -22,6 +22,7 @@
     , prompt :: Maybe Text
     , temperature :: Maybe Double
     } deriving stock (Generic, Show)
+      deriving anyclass (FromJSON, ToJSON)
 
 instance ToMultipart Tmp CreateTranslation where
     toMultipart CreateTranslation{ model = Model model, ..} = MultipartData{..}
@@ -51,7 +52,7 @@
 data TranslationObject = TranslationObject
     { text :: Text
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Batches.hs b/src/OpenAI/V1/Batches.hs
--- a/src/OpenAI/V1/Batches.hs
+++ b/src/OpenAI/V1/Batches.hs
@@ -28,7 +28,7 @@
     , completion_window :: Text
     , metadata :: Maybe (Map Text Text)
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateBatch`
 _CreateBatch :: CreateBatch
@@ -51,13 +51,16 @@
 instance FromJSON Status where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Status where
+    toJSON = genericToJSON aesonOptions
+
 -- | The request counts for different statuses within the batch.
 data Counts = Counts
     { total :: Natural
     , completed :: Natural
     , failed :: Natural
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | The batch object
 data BatchObject = BatchObject
@@ -85,6 +88,9 @@
 
 instance FromJSON BatchObject where
     parseJSON = genericParseJSON aesonOptions
+
+instance ToJSON BatchObject where
+    toJSON = genericToJSON aesonOptions
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Chat/Completions.hs b/src/OpenAI/V1/Chat/Completions.hs
--- a/src/OpenAI/V1/Chat/Completions.hs
+++ b/src/OpenAI/V1/Chat/Completions.hs
@@ -21,6 +21,7 @@
     , AudioParameters(..)
     , ResponseFormat(..)
     , ServiceTier(..)
+    , ReasoningEffort(..)
     , FinishReason(..)
     , Token(..)
     , LogProbs(..)
@@ -41,13 +42,16 @@
 data InputAudio = InputAudio{ data_ :: Text, format :: AudioFormat }
     deriving stock (Generic, Show)
 
+instance FromJSON InputAudio where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON InputAudio where
     toJSON = genericToJSON aesonOptions
 
 -- | Image content part
 data ImageURL = ImageURL{ url :: Text, detail :: Maybe (AutoOr Text) }
     deriving stock (Generic, Show)
-    deriving anyclass (ToJSON)
+    deriving anyclass (FromJSON, ToJSON)
 
 -- | A content part
 data Content
@@ -59,14 +63,21 @@
 instance IsString Content where
     fromString string = Text{ text = fromString string }
 
-instance ToJSON Content where
-    toJSON = genericToJSON aesonOptions
+contentOptions :: Options
+contentOptions =
+    aesonOptions
         { sumEncoding =
             TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
 
         , tagSingleConstructors = True
         }
 
+instance FromJSON Content where
+    parseJSON = genericParseJSON contentOptions
+
+instance ToJSON Content where
+    toJSON = genericToJSON contentOptions
+
 -- | Data about a previous audio response from the model.
 -- [Learn more](https://platform.openai.com/docs/guides/audio)
 data AudioData = AudioData{ id :: Text }
@@ -131,10 +142,17 @@
 data Modality = Modality_Text | Modality_Audio
     deriving stock (Generic, Show)
 
-instance ToJSON Modality where
-    toJSON = genericToJSON aesonOptions
+modalityOptions :: Options
+modalityOptions =
+    aesonOptions
         { constructorTagModifier = stripPrefix "Modality_" }
 
+instance FromJSON Modality where
+    parseJSON = genericParseJSON modalityOptions
+
+instance ToJSON Modality where
+    toJSON = genericToJSON modalityOptions
+
 -- | Configuration for a
 -- [Predicted Output](https://platform.openai.com/docs/guides/predicted-outputs),
 -- which can greatly improve response times when large parts of the model
@@ -143,18 +161,28 @@
 data Prediction = Content{ content :: Text }
     deriving stock (Generic, Show)
 
-instance ToJSON Prediction where
-    toJSON = genericToJSON aesonOptions
+predictionOptions :: Options
+predictionOptions =
+    aesonOptions
         { sumEncoding =
             TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
 
         , tagSingleConstructors = True
         }
 
+instance FromJSON Prediction where
+    parseJSON = genericParseJSON predictionOptions
+
+instance ToJSON Prediction where
+    toJSON = genericToJSON predictionOptions
+
 -- | The voice the model uses to respond
 data Voice = Ash | Ballad | Coral | Sage | Verse
     deriving stock (Generic, Show)
 
+instance FromJSON Voice where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON Voice where
     toJSON = genericToJSON aesonOptions
 
@@ -162,6 +190,9 @@
 data AudioFormat = WAV | MP3 | FLAC | Opus | PCM16
     deriving stock (Generic, Show)
 
+instance FromJSON AudioFormat where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON AudioFormat where
     toJSON = genericToJSON aesonOptions
 
@@ -170,16 +201,28 @@
     { voice :: Voice
     , format :: AudioFormat
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Specifies the latency tier to use for processing the request
 data ServiceTier = Default
     deriving stock (Generic, Show)
 
+serviceOptions :: Options
+serviceOptions = aesonOptions{ tagSingleConstructors = True }
+
 instance FromJSON ServiceTier where
-    parseJSON = genericParseJSON aesonOptions{ tagSingleConstructors = True }
+    parseJSON = genericParseJSON serviceOptions
 
 instance ToJSON ServiceTier where
+    toJSON = genericToJSON serviceOptions
+
+data ReasoningEffort = Low | Medium | High
+    deriving stock (Generic, Show)
+
+instance FromJSON ReasoningEffort where
+    parseJSON = genericParseJSON aesonOptions
+
+instance ToJSON ReasoningEffort where
     toJSON = genericToJSON aesonOptions
 
 -- | Request body for @\/v1\/chat\/completions@
@@ -198,6 +241,7 @@
     , prediction :: Maybe Prediction
     , audio :: Maybe AudioParameters
     , presence_penalty :: Maybe Double
+    , reasoning_effort :: Maybe ReasoningEffort
     , response_format :: Maybe ResponseFormat
     , seed :: Maybe Integer
     , service_tier :: Maybe (AutoOr ServiceTier)
@@ -210,6 +254,9 @@
     , user :: Maybe Text
     } deriving stock (Generic, Show)
 
+instance FromJSON CreateChatCompletion where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON CreateChatCompletion where
     toJSON = genericToJSON aesonOptions
 
@@ -228,6 +275,7 @@
     , prediction = Nothing
     , audio = Nothing
     , presence_penalty = Nothing
+    , reasoning_effort = Nothing
     , response_format = Nothing
     , seed = Nothing
     , service_tier = Nothing
@@ -249,8 +297,11 @@
     deriving stock (Generic, Show)
 
 instance FromJSON FinishReason where
-    parseJSON = genericParseJSON messageOptions
+    parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON FinishReason where
+    toJSON = genericToJSON aesonOptions
+
 -- | Message tokens with log probability information
 data Token = Token
     { token :: Text
@@ -258,14 +309,14 @@
     , bytes :: Maybe (Vector Word8)
     , top_logprobs :: Maybe (Vector Token)
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Log probability information for the choice
 data LogProbs = LogProbs
     { content :: Maybe (Vector Token)
     , refusal :: Maybe (Vector Token)
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | A chat completion choice
 data Choice = Choice
@@ -274,7 +325,7 @@
     , message :: Message Text
     , logprobs :: Maybe LogProbs
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | ChatCompletion body
 data ChatCompletionObject = ChatCompletionObject
@@ -282,12 +333,13 @@
     , choices :: Vector Choice
     , created :: POSIXTime
     , model :: Model
+    , reasoning_effort :: Maybe ReasoningEffort
     , service_tier :: Maybe ServiceTier
-    , system_fingerprint :: Text
+    , system_fingerprint :: Maybe Text
     , object :: Text
     , usage :: Usage CompletionTokensDetails PromptTokensDetails
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/ChunkingStrategy.hs b/src/OpenAI/V1/ChunkingStrategy.hs
--- a/src/OpenAI/V1/ChunkingStrategy.hs
+++ b/src/OpenAI/V1/ChunkingStrategy.hs
@@ -30,10 +30,8 @@
     , constructorTagModifier = stripPrefix "ChunkingStrategy_"
     }
 
-instance ToJSON ChunkingStrategy where
-    toJSON = genericToJSON chunkingStrategyOptions
-
 instance FromJSON ChunkingStrategy where
     parseJSON = genericParseJSON chunkingStrategyOptions
 
-
+instance ToJSON ChunkingStrategy where
+    toJSON = genericToJSON chunkingStrategyOptions
diff --git a/src/OpenAI/V1/DeletionStatus.hs b/src/OpenAI/V1/DeletionStatus.hs
--- a/src/OpenAI/V1/DeletionStatus.hs
+++ b/src/OpenAI/V1/DeletionStatus.hs
@@ -12,4 +12,4 @@
     , object :: Text
     , deleted :: Bool
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
diff --git a/src/OpenAI/V1/Embeddings.hs b/src/OpenAI/V1/Embeddings.hs
--- a/src/OpenAI/V1/Embeddings.hs
+++ b/src/OpenAI/V1/Embeddings.hs
@@ -18,6 +18,9 @@
 data EncodingFormat = Float | Base64
     deriving stock (Generic, Show)
 
+instance FromJSON EncodingFormat where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON EncodingFormat where
     toJSON = genericToJSON aesonOptions
 
@@ -29,7 +32,7 @@
     , dimensions :: Maybe Natural
     , user :: Maybe Text
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateEmbeddings`
 _CreateEmbeddings :: CreateEmbeddings
@@ -45,7 +48,7 @@
     , embedding :: Vector Double
     , object :: Text
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Error.hs b/src/OpenAI/V1/Error.hs
--- a/src/OpenAI/V1/Error.hs
+++ b/src/OpenAI/V1/Error.hs
@@ -17,4 +17,4 @@
     , param :: Maybe Text
     , line :: Maybe Natural
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
diff --git a/src/OpenAI/V1/Files.hs b/src/OpenAI/V1/Files.hs
--- a/src/OpenAI/V1/Files.hs
+++ b/src/OpenAI/V1/Files.hs
@@ -55,7 +55,7 @@
     , object :: Text
     , purpose :: Purpose
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | The intended purpose of the uploaded file.
 data Purpose
diff --git a/src/OpenAI/V1/FineTuning/Jobs.hs b/src/OpenAI/V1/FineTuning/Jobs.hs
--- a/src/OpenAI/V1/FineTuning/Jobs.hs
+++ b/src/OpenAI/V1/FineTuning/Jobs.hs
@@ -67,7 +67,7 @@
     parseJSON = genericParseJSON integrationOptions
 
 instance ToJSON Integration where
-    toJSON = genericToJSON integrationOptions-- | CreateFineTuningJob body
+    toJSON = genericToJSON integrationOptions
 
 -- | Request body for @\/v1\/fine_tuning\/jobs@
 data CreateFineTuningJob = CreateFineTuningJob
@@ -79,7 +79,7 @@
     , integrations :: Maybe (Vector Integration)
     , seed :: Maybe Integer
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateFineTuningJob`
 _CreateFineTuningJob :: CreateFineTuningJob
@@ -104,6 +104,9 @@
 instance FromJSON Status where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Status where
+    toJSON = genericToJSON aesonOptions
+
 -- | The fine_tuning.job object represents a fine-tuning job that has been
 -- created through the API.
 data JobObject = JobObject
@@ -125,7 +128,7 @@
     , seed :: Integer
     , estimated_finish :: Maybe POSIXTime
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Log level
 data Level = Info | Warn | Error
@@ -134,6 +137,9 @@
 instance FromJSON Level where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Level where
+    toJSON = genericToJSON aesonOptions
+
 -- | Fine-tuning job event object
 data EventObject = EventObject
     { id :: Text
@@ -142,7 +148,7 @@
     , message :: Text
     , object :: Text
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Metrics at the step number during the fine-tuning job.
 data Metrics = Metrics
@@ -154,7 +160,7 @@
     , full_valid_loss :: Double
     , full_valid_mean_token_accuracy :: Double
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | The @fine_tuning.job.checkpoint@ object represents a model checkpoint for
 -- a fine-tuning job that is ready to use
@@ -167,7 +173,7 @@
     , fine_tuning_job_id :: FineTuningJobID
     , object :: Text
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Images/Edits.hs b/src/OpenAI/V1/Images/Edits.hs
--- a/src/OpenAI/V1/Images/Edits.hs
+++ b/src/OpenAI/V1/Images/Edits.hs
@@ -28,6 +28,7 @@
     , response_format :: Maybe ResponseFormat
     , user :: Maybe Text
     } deriving stock (Generic, Show)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateImageEdit`
 _CreateImageEdit :: CreateImageEdit
diff --git a/src/OpenAI/V1/Images/Generations.hs b/src/OpenAI/V1/Images/Generations.hs
--- a/src/OpenAI/V1/Images/Generations.hs
+++ b/src/OpenAI/V1/Images/Generations.hs
@@ -20,6 +20,9 @@
 data Quality = Standard | HD
     deriving stock (Generic, Show)
 
+instance FromJSON Quality where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON Quality where
     toJSON = genericToJSON aesonOptions
 
@@ -27,6 +30,9 @@
 data Style = Vivid | Natural
     deriving stock (Generic, Show)
 
+instance FromJSON Style where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON Style where
     toJSON = genericToJSON aesonOptions
 
@@ -53,6 +59,9 @@
     , style = Nothing
     , user = Nothing
     }
+
+instance FromJSON CreateImage where
+    parseJSON = genericParseJSON aesonOptions
 
 instance ToJSON CreateImage where
     toJSON = genericToJSON aesonOptions
diff --git a/src/OpenAI/V1/Images/Image.hs b/src/OpenAI/V1/Images/Image.hs
--- a/src/OpenAI/V1/Images/Image.hs
+++ b/src/OpenAI/V1/Images/Image.hs
@@ -12,4 +12,4 @@
     , url :: Maybe Text
     , revised_prompt :: Maybe Text
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
diff --git a/src/OpenAI/V1/Images/ResponseFormat.hs b/src/OpenAI/V1/Images/ResponseFormat.hs
--- a/src/OpenAI/V1/Images/ResponseFormat.hs
+++ b/src/OpenAI/V1/Images/ResponseFormat.hs
@@ -10,6 +10,9 @@
 data ResponseFormat = URL | B64_JSON
     deriving stock (Generic, Show)
 
+instance FromJSON ResponseFormat where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON ResponseFormat where
     toJSON = genericToJSON aesonOptions
 
diff --git a/src/OpenAI/V1/Images/Variations.hs b/src/OpenAI/V1/Images/Variations.hs
--- a/src/OpenAI/V1/Images/Variations.hs
+++ b/src/OpenAI/V1/Images/Variations.hs
@@ -24,6 +24,7 @@
     , size :: Maybe Text
     , user :: Maybe Text
     } deriving stock (Generic, Show)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateImageVariation`
 _CreateImageVariation :: CreateImageVariation
diff --git a/src/OpenAI/V1/ListOf.hs b/src/OpenAI/V1/ListOf.hs
--- a/src/OpenAI/V1/ListOf.hs
+++ b/src/OpenAI/V1/ListOf.hs
@@ -14,3 +14,6 @@
 
 instance FromJSON a => FromJSON (ListOf a) where
     parseJSON = genericParseJSON aesonOptions
+
+instance ToJSON a => ToJSON (ListOf a) where
+    toJSON = genericToJSON aesonOptions
diff --git a/src/OpenAI/V1/Message.hs b/src/OpenAI/V1/Message.hs
--- a/src/OpenAI/V1/Message.hs
+++ b/src/OpenAI/V1/Message.hs
@@ -70,9 +70,16 @@
         }
     deriving stock (Generic, Show)
 
-instance ToJSON Message where
-    toJSON = genericToJSON aesonOptions
+messageOptions :: Options
+messageOptions =
+    aesonOptions
         { sumEncoding =
             TaggedObject{ tagFieldName = "role", contentsFieldName = "" }
         , tagSingleConstructors = True
         }
+
+instance FromJSON Message where
+    parseJSON = genericParseJSON  messageOptions
+
+instance ToJSON Message where
+    toJSON = genericToJSON  messageOptions
diff --git a/src/OpenAI/V1/Moderations.hs b/src/OpenAI/V1/Moderations.hs
--- a/src/OpenAI/V1/Moderations.hs
+++ b/src/OpenAI/V1/Moderations.hs
@@ -21,7 +21,7 @@
     { input :: Text
     , model :: Maybe Model
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateModeration`
 _CreateModeration :: CreateModeration
@@ -36,6 +36,9 @@
 instance FromJSON InputType where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON InputType where
+    toJSON = genericToJSON aesonOptions
+
 -- | A moderation result
 data Result = Result
     { flagged :: Bool
@@ -45,7 +48,7 @@
     -- According to the OpenAPI spec the `category_applied_input_types`
     -- field is required but their actual implementation omits this field.
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Represents if a given text input is potentially harmful.
 data Moderation = Moderation
@@ -53,7 +56,7 @@
     , model :: Model
     , results :: Vector Result
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Order.hs b/src/OpenAI/V1/Order.hs
--- a/src/OpenAI/V1/Order.hs
+++ b/src/OpenAI/V1/Order.hs
@@ -8,6 +8,13 @@
 
 -- | Sort order by the @created_at@ timestamp of the objects
 data Order = Desc | Asc
+    deriving stock (Generic, Show)
+
+instance FromJSON Order where
+    parseJSON = genericParseJSON aesonOptions
+
+instance ToJSON Order where
+    toJSON = genericToJSON aesonOptions
 
 instance ToHttpApiData Order where
     toUrlPiece Desc = "desc"
diff --git a/src/OpenAI/V1/Threads.hs b/src/OpenAI/V1/Threads.hs
--- a/src/OpenAI/V1/Threads.hs
+++ b/src/OpenAI/V1/Threads.hs
@@ -34,7 +34,7 @@
     , tool_resources :: Maybe ToolResources
     , metadata :: Maybe (Map Text Text)
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `Thread`
 _Thread :: Thread
@@ -50,6 +50,9 @@
     , metadata :: Maybe (Map Text Text)
     } deriving stock (Generic, Show)
 
+instance FromJSON ModifyThread where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON ModifyThread where
     toJSON = genericToJSON aesonOptions
 
@@ -68,7 +71,7 @@
     , tool_resources :: Maybe ToolResources
     , metadata :: Maybe (Map Text Text)
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Threads/Messages.hs b/src/OpenAI/V1/Threads/Messages.hs
--- a/src/OpenAI/V1/Threads/Messages.hs
+++ b/src/OpenAI/V1/Threads/Messages.hs
@@ -36,6 +36,9 @@
     { metadata :: Maybe (Map Text Text)
     } deriving stock (Generic, Show)
 
+instance FromJSON ModifyMessage where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON ModifyMessage where
     toJSON = genericToJSON aesonOptions
 
@@ -52,17 +55,20 @@
 instance FromJSON Status where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Status where
+    toJSON = genericToJSON aesonOptions
+
 -- | On an incomplete message, details about why the message is incomplete.
 data IncompleteDetails = IncompleteDetails
     { reason :: Text
     } deriving (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | File
 data File = File
     { file_id :: FileID
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | An annotation
 data Annotation
@@ -80,20 +86,27 @@
         }
     deriving stock (Generic, Show)
 
-instance FromJSON Annotation where
-    parseJSON = genericParseJSON aesonOptions
+annotationOptions :: Options
+annotationOptions =
+    aesonOptions
         { sumEncoding =
             TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
 
         , tagSingleConstructors = True
         }
 
+instance FromJSON Annotation where
+    parseJSON = genericParseJSON annotationOptions
+
+instance ToJSON Annotation where
+    toJSON = genericToJSON annotationOptions
+
 -- | The text content that is part of a message.
 data TextObject = TextObject
     { value :: Text
     , annotations :: Vector Annotation
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 instance IsString TextObject where
     fromString string =
@@ -116,7 +129,7 @@
     , attachments :: Maybe (Vector Attachment)
     , metadata :: Map Text Text
     } deriving (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Threads/Runs.hs b/src/OpenAI/V1/Threads/Runs.hs
--- a/src/OpenAI/V1/Threads/Runs.hs
+++ b/src/OpenAI/V1/Threads/Runs.hs
@@ -83,6 +83,9 @@
     , response_format :: Maybe (AutoOr ResponseFormat)
     } deriving stock (Generic, Show)
 
+instance FromJSON CreateRun where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON CreateRun where
     toJSON = genericToJSON aesonOptions
 
@@ -124,6 +127,9 @@
     , response_format :: Maybe (AutoOr ResponseFormat)
     } deriving stock (Generic, Show)
 
+instance FromJSON CreateThreadAndRun where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON CreateThreadAndRun where
     toJSON = genericToJSON aesonOptions
 
@@ -150,7 +156,7 @@
 data SubmitToolOutputs = SubmitToolOutputs
     { tool_calls :: Vector ToolCall
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | The status of the run
 data Status
@@ -168,13 +174,17 @@
 instance FromJSON Status where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Status where
+    toJSON = genericToJSON aesonOptions
+
 -- | Details on the action required to continue the run
 data RequiredAction = RequiredAction_Submit_Tool_Outputs
     { submit_tool_outputs :: SubmitToolOutputs
     } deriving stock (Generic, Show)
 
-instance FromJSON RequiredAction where
-    parseJSON = genericParseJSON aesonOptions
+requiredActionOptions :: Options
+requiredActionOptions =
+    aesonOptions
         { sumEncoding =
               TaggedObject{ tagFieldName = "type" }
 
@@ -183,11 +193,17 @@
         , constructorTagModifier = stripPrefix "RequiredAction_"
         }
 
+instance FromJSON RequiredAction where
+    parseJSON = genericParseJSON requiredActionOptions
+
+instance ToJSON RequiredAction where
+    toJSON = genericToJSON requiredActionOptions
+
 -- | Details on why the run is incomplete
 data IncompleteDetails = IncompleteDetails
     { reason :: Text
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Represents an execution run on a thread.
 data RunObject = RunObject
@@ -209,7 +225,7 @@
     , instructions :: Maybe Text
     , tools :: Vector Tool
     , metadata :: Map Text Text
-    , usage :: Maybe (Usage (Maybe Void) (Maybe Void))
+    , usage :: Maybe (Usage (Maybe CompletionTokensDetails) (Maybe PromptTokensDetails))
     , temperature :: Maybe Double
     , top_p :: Maybe Double
     , max_prompt_tokens :: Maybe Natural
@@ -219,13 +235,16 @@
     , parallel_tool_calls :: Bool
     , response_format :: AutoOr ResponseFormat
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Request body for @\/v1\/threads\/:thread_id\/runs\/:run_id@
 data ModifyRun = ModifyRun
     { metadata :: Maybe (Map Text Text)
     } deriving stock (Generic, Show)
 
+instance FromJSON ModifyRun where
+    parseJSON = genericParseJSON aesonOptions
+
 instance ToJSON ModifyRun where
     toJSON = genericToJSON aesonOptions
 
@@ -238,12 +257,15 @@
     { tool_call_id :: Maybe Text
     , output :: Text
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Request body for @\/v1\/threads\/:thread_id\/runs\/:run_id\/submit_tool_outputs@
 data SubmitToolOutputsToRun = SubmitToolOutputsToRun
     { tool_outputs :: Vector ToolOutput
     } deriving stock (Generic, Show)
+
+instance FromJSON SubmitToolOutputsToRun where
+    parseJSON = genericParseJSON aesonOptions
 
 instance ToJSON SubmitToolOutputsToRun where
     toJSON = genericToJSON aesonOptions
diff --git a/src/OpenAI/V1/Threads/Runs/Steps.hs b/src/OpenAI/V1/Threads/Runs/Steps.hs
--- a/src/OpenAI/V1/Threads/Runs/Steps.hs
+++ b/src/OpenAI/V1/Threads/Runs/Steps.hs
@@ -43,17 +43,21 @@
 instance FromJSON Status where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Status where
+    toJSON = genericToJSON aesonOptions
+
 -- | Code Interpreter image output
 data Image = Image{ file_id :: FileID }
     deriving stock (Generic, Show)
-    deriving anyclass (FromJSON)
+    deriving anyclass (FromJSON, ToJSON)
 
 -- | An output from the Code Interpreter tool call
 data Output = Output_Logs{ logs :: Text } | Output_Image{ image :: Image }
     deriving stock (Generic, Show)
 
-instance FromJSON Output where
-    parseJSON = genericParseJSON aesonOptions
+outputOptions :: Options
+outputOptions =
+    aesonOptions
         { sumEncoding =
             TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
 
@@ -62,19 +66,25 @@
         , constructorTagModifier = stripPrefix "Output_"
         }
 
+instance FromJSON Output where
+    parseJSON = genericParseJSON outputOptions
+
+instance ToJSON Output where
+    toJSON = genericToJSON outputOptions
+
 -- | A Code Interpreter tool call
 data CodeInterpreter = CodeInterpreter
     { input :: Text
     , outputs :: Vector Output
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | The ranking options for the file search.
 data RankingOptions = RankingOptions
     { ranker :: Text
     , score_threshold :: Double
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | The content of the result that was found
 data Content = Content
@@ -85,6 +95,9 @@
 instance FromJSON Content where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Content where
+    toJSON = genericToJSON aesonOptions
+
 -- | Result of the file search
 data Result = Result
     { file_id :: FileID
@@ -92,14 +105,14 @@
     , score :: Double
     , content :: Vector Content
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | A File Search tool call
 data FileSearch = FileSearch
     { ranking_options :: RankingOptions
     , results :: Vector Result
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | The definition of the function that was called
 data Function = Function
@@ -107,7 +120,7 @@
     , arguments :: Text
     , output :: Maybe Text
     } deriving (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | A tool call the run step was involved in
 data ToolCall
@@ -116,8 +129,9 @@
     | ToolCall_Function { id :: Text, function :: Function }
     deriving stock (Generic, Show)
 
-instance FromJSON ToolCall where
-    parseJSON = genericParseJSON aesonOptions
+toolCallOptions :: Options
+toolCallOptions =
+    aesonOptions
         { sumEncoding =
             TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
 
@@ -126,20 +140,33 @@
         , constructorTagModifier = stripPrefix "ToolCall_"
         }
 
+instance FromJSON ToolCall where
+    parseJSON = genericParseJSON toolCallOptions
+
+instance ToJSON ToolCall where
+    toJSON = genericToJSON toolCallOptions
+
 -- | The details of the run step
 data StepDetails
     = Message_Creation{ message_id :: MessageID }
     | Tool_Calls{ tool_calls :: Vector ToolCall }
     deriving stock (Generic, Show)
 
-instance FromJSON StepDetails where
-    parseJSON = genericParseJSON aesonOptions
+stepDetailsOptions :: Options
+stepDetailsOptions =
+    aesonOptions
         { sumEncoding =
             TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
 
         , tagSingleConstructors = True
         }
 
+instance FromJSON StepDetails where
+    parseJSON = genericParseJSON stepDetailsOptions
+
+instance ToJSON StepDetails where
+    toJSON = genericToJSON stepDetailsOptions
+
 -- | Represents a step in execution of a run.
 data RunStepObject = RunStepObject
     { id :: StepID
@@ -158,7 +185,7 @@
     , metadata :: Map Text Text
     , usage :: Maybe (Usage CompletionTokensDetails PromptTokensDetails)
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/Uploads.hs b/src/OpenAI/V1/Uploads.hs
--- a/src/OpenAI/V1/Uploads.hs
+++ b/src/OpenAI/V1/Uploads.hs
@@ -33,7 +33,7 @@
     , bytes :: Natural
     , mime_type :: Text
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateUpload`
 _CreateUpload :: CreateUpload
@@ -41,7 +41,14 @@
 
 -- | Request body for @\/v1\/uploads\/:upload_id\/parts@
 data AddUploadPart = AddUploadPart{ data_ :: FilePath }
+    deriving stock (Generic, Show)
 
+instance FromJSON AddUploadPart where
+    parseJSON = genericParseJSON aesonOptions
+
+instance ToJSON AddUploadPart where
+    toJSON = genericToJSON aesonOptions
+
 -- | Default `AddUploadPart`
 _AddUploadPart :: AddUploadPart
 _AddUploadPart = AddUploadPart{ }
@@ -80,6 +87,13 @@
             CompleteUpload{ md5 = Just "", .. }
         fix x = x
 
+instance FromJSON CompleteUpload where
+    parseJSON = fmap (fmap fix) (genericParseJSON aesonOptions)
+      where
+        fix CompleteUpload{ md5 = Just "", .. } =
+            CompleteUpload{ md5 = Nothing, .. }
+        fix x = x
+
 -- | The status of the Upload
 data Status
     = Pending
@@ -91,6 +105,9 @@
 instance FromJSON Status where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Status where
+    toJSON = genericToJSON aesonOptions
+
 -- | The Upload object can accept byte chunks in the form of Parts.
 data UploadObject file = UploadObject
     { id :: UploadID
@@ -106,6 +123,8 @@
 
 instance FromJSON (UploadObject (Maybe Void))
 instance FromJSON (UploadObject FileObject)
+instance ToJSON (UploadObject (Maybe Void))
+instance ToJSON (UploadObject FileObject)
 
 -- | The upload part represents a chunk of bytes we can add to an upload
 -- object
@@ -115,7 +134,7 @@
     , upload_id :: UploadID
     , object :: Text
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API
diff --git a/src/OpenAI/V1/Usage.hs b/src/OpenAI/V1/Usage.hs
--- a/src/OpenAI/V1/Usage.hs
+++ b/src/OpenAI/V1/Usage.hs
@@ -12,28 +12,30 @@
 
 -- | Breakdown of tokens used in a completion
 data CompletionTokensDetails = CompletionTokensDetails
-    { accepted_prediction_tokens :: Natural
-    , audio_tokens :: Natural
-    , reasoning_tokens :: Natural
-    , rejected_prediction_tokens :: Natural
+    { accepted_prediction_tokens :: Maybe Natural
+    , audio_tokens :: Maybe Natural
+    , reasoning_tokens :: Maybe Natural
+    , rejected_prediction_tokens :: Maybe Natural
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Breakdown of tokens used in the prompt
 data PromptTokensDetails = PromptTokensDetails
-    { audio_tokens :: Natural
-    , cached_tokens :: Natural
+    { audio_tokens :: Maybe Natural
+    , cached_tokens :: Maybe Natural
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Usage statistics for the completion request
 data Usage completionTokensDetails promptTokensDetails = Usage
     { completion_tokens :: Natural
     , prompt_tokens :: Natural
     , total_tokens :: Natural
-    , completion_tokens_details :: completionTokensDetails
-    , prompt_tokens_details :: promptTokensDetails
+    , completion_tokens_details :: Maybe completionTokensDetails
+    , prompt_tokens_details :: Maybe promptTokensDetails
     } deriving stock (Generic, Show)
 
 instance FromJSON (Usage CompletionTokensDetails PromptTokensDetails)
-instance FromJSON (Usage (Maybe Void) (Maybe Void))
+instance FromJSON (Usage (Maybe CompletionTokensDetails) (Maybe PromptTokensDetails))
+instance ToJSON (Usage CompletionTokensDetails PromptTokensDetails)
+instance ToJSON (Usage (Maybe CompletionTokensDetails) (Maybe PromptTokensDetails))
diff --git a/src/OpenAI/V1/VectorStores.hs b/src/OpenAI/V1/VectorStores.hs
--- a/src/OpenAI/V1/VectorStores.hs
+++ b/src/OpenAI/V1/VectorStores.hs
@@ -44,7 +44,7 @@
     , chunking_strategy :: Maybe (AutoOr ChunkingStrategy)
     , metadata :: Maybe (Map Text Text)
     } deriving stock (Generic, Show)
-      deriving (ToJSON)
+      deriving (FromJSON, ToJSON)
 
 -- | Default `CreateVectorStore`
 _CreateVectorStore :: CreateVectorStore
@@ -61,7 +61,7 @@
     , expires_after :: Maybe ExpiresAfter
     , metadata :: Maybe (Map Text Text)
     } deriving stock (Generic, Show)
-      deriving (ToJSON)
+      deriving (FromJSON, ToJSON)
 
 -- | Default `ModifyVectorStore`
 _ModifyVectorStore :: ModifyVectorStore
@@ -78,6 +78,9 @@
 instance FromJSON Status where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Status where
+    toJSON = genericToJSON aesonOptions
+
 -- | A vector store is a collection of processed files can be used by the
 -- @file_search@ tool.
 data VectorStoreObject = VectorStoreObject
@@ -93,7 +96,7 @@
     , last_active_at :: Maybe POSIXTime
     , metadata :: Map Text Text
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/VectorStores/FileBatches.hs b/src/OpenAI/V1/VectorStores/FileBatches.hs
--- a/src/OpenAI/V1/VectorStores/FileBatches.hs
+++ b/src/OpenAI/V1/VectorStores/FileBatches.hs
@@ -28,7 +28,7 @@
     { file_ids :: Vector FileID
     , chunking_strategy :: Maybe ChunkingStrategy
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateVectorStoreFileBatch`
 _CreateVectorStoreFileBatch :: CreateVectorStoreFileBatch
@@ -45,7 +45,7 @@
     , status :: Status
     , file_counts :: Maybe FileCounts
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/VectorStores/FileCounts.hs b/src/OpenAI/V1/VectorStores/FileCounts.hs
--- a/src/OpenAI/V1/VectorStores/FileCounts.hs
+++ b/src/OpenAI/V1/VectorStores/FileCounts.hs
@@ -14,4 +14,4 @@
     , cancelled :: Natural
     , total :: Natural
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
diff --git a/src/OpenAI/V1/VectorStores/Files.hs b/src/OpenAI/V1/VectorStores/Files.hs
--- a/src/OpenAI/V1/VectorStores/Files.hs
+++ b/src/OpenAI/V1/VectorStores/Files.hs
@@ -29,7 +29,7 @@
     { file_id :: FileID
     , chunking_strategy :: Maybe ChunkingStrategy
     } deriving stock (Generic, Show)
-      deriving anyclass (ToJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Default `CreateVectorStoreFile`
 _CreateVectorStoreFile :: CreateVectorStoreFile
@@ -48,7 +48,7 @@
     , last_error :: Maybe Error
     , chunking_strategy :: ChunkingStrategy
     } deriving stock (Generic, Show)
-      deriving anyclass (FromJSON)
+      deriving anyclass (FromJSON, ToJSON)
 
 -- | Servant API
 type API =
diff --git a/src/OpenAI/V1/VectorStores/Status.hs b/src/OpenAI/V1/VectorStores/Status.hs
--- a/src/OpenAI/V1/VectorStores/Status.hs
+++ b/src/OpenAI/V1/VectorStores/Status.hs
@@ -13,6 +13,9 @@
 instance FromJSON Status where
     parseJSON = genericParseJSON aesonOptions
 
+instance ToJSON Status where
+    toJSON = genericToJSON aesonOptions
+
 instance ToHttpApiData Status where
     toUrlPiece In_Progress = "in_progress"
     toUrlPiece Completed = "completed"
diff --git a/tasty/Main.hs b/tasty/Main.hs
--- a/tasty/Main.hs
+++ b/tasty/Main.hs
@@ -89,7 +89,7 @@
 
     let user = "openai Haskell package"
     let chatModel = "gpt-4o-mini"
-
+    let reasoningModel = "o3-mini"
     let Methods{..} = V1.makeMethods clientEnv (Text.pack key)
 
     -- Test each format to make sure we're handling each possible content type
@@ -153,6 +153,7 @@
                     , prediction = Nothing
                     , audio = Nothing
                     , presence_penalty = Nothing
+                    , reasoning_effort = Nothing
                     , response_format = Nothing
                     , seed = Nothing
                     , service_tier = Nothing
@@ -167,6 +168,41 @@
 
                 return ()
 
+    let completionsMinimalReasoningTest =
+            HUnit.testCase "Create chat completion reasoning model - minimal" do
+                _ <- createChatCompletion CreateChatCompletion
+                    { messages =
+                        [ Completions.User
+                            { content = [ "Hello, world!" ], name = Nothing }
+                        ]
+                    , model = reasoningModel
+                    , store = Nothing
+                    , metadata = Nothing
+                    , frequency_penalty = Nothing
+                    , logit_bias = Nothing
+                    , logprobs = Nothing
+                    , top_logprobs = Nothing
+                    , max_completion_tokens = Nothing
+                    , n = Nothing
+                    , modalities = Nothing
+                    , prediction = Nothing
+                    , audio = Nothing
+                    , presence_penalty = Nothing
+                    , reasoning_effort = Just Completions.Low
+                    , response_format = Nothing
+                    , seed = Nothing
+                    , service_tier = Nothing
+                    , stop = Nothing
+                    , temperature = Nothing
+                    , top_p = Nothing
+                    , tools = Nothing
+                    , tool_choice = Nothing
+                    , parallel_tool_calls = Nothing
+                    , user = Nothing
+                    }
+
+                return ()
+
     let completionsMaximalTest =
             HUnit.testCase "Create chat completion - maximal" do
                 _ <- createChatCompletion CreateChatCompletion
@@ -208,6 +244,7 @@
                     , prediction = Nothing
                     , audio = Nothing
                     , presence_penalty = Just 0
+                    , reasoning_effort = Nothing
                     , response_format = Just Completions.ResponseFormat_Text
                     , seed = Just 0
                     , service_tier = Just Auto
@@ -632,6 +669,7 @@
             <>  [ transcriptionTest
                 , translationTest
                 , completionsMinimalTest
+                , completionsMinimalReasoningTest
                 , completionsMaximalTest
                 , embeddingsTest
                 , fineTuningTest
