@@ -195,6 +195,32 @@ impl OpenAIClient {
195195 self . handle_response ( response) . await
196196 }
197197
198+ /// `POST`s but expects an empty response rather than anything to deserialize.
199+ async fn post_empty (
200+ & mut self ,
201+ path : & str ,
202+ body : & impl serde:: ser:: Serialize ,
203+ ) -> Result < ( ) , APIError > {
204+ let request = self . build_request ( Method :: POST , path) . await ;
205+ let request = request. json ( body) ;
206+ let response = request. send ( ) . await ?;
207+
208+ if response. status ( ) . is_success ( ) {
209+ let headers = response. headers ( ) . clone ( ) ;
210+ self . response_headers = Some ( headers) ;
211+ Ok ( ( ) )
212+ } else {
213+ let status = response. status ( ) ;
214+ let error_message = response
215+ . text ( )
216+ . await
217+ . unwrap_or_else ( |_| format ! ( "Unknown error - no body text was provided" ) ) ;
218+ Err ( APIError :: CustomError {
219+ message : format ! ( "{status}: {error_message}" ) ,
220+ } )
221+ }
222+ }
223+
198224 async fn get < T : serde:: de:: DeserializeOwned > ( & mut self , path : & str ) -> Result < T , APIError > {
199225 let request = self . build_request ( Method :: GET , path) . await ;
200226 let response = request. send ( ) . await ?;
@@ -802,17 +828,15 @@ impl OpenAIClient {
802828 call_id : & str ,
803829 accept : AcceptCallRequest ,
804830 ) -> Result < ( ) , APIError > {
805- // /realtime/calls endpoints return empty strings on success
806- self . post :: < String > ( & format ! ( "realtime/calls/{call_id}/accept" ) , & accept)
807- . await ?;
808- Ok ( ( ) )
831+ // /realtime/calls endpoints return empty responses on success
832+ self . post_empty ( & format ! ( "realtime/calls/{call_id}/accept" ) , & accept)
833+ . await
809834 }
810835
811836 pub async fn hangup_call ( & mut self , call_id : & str ) -> Result < ( ) , APIError > {
812- // /realtime/calls endpoints return empty strings on success
813- self . post :: < String > ( & format ! ( "realtime/calls/{call_id}/hangup" ) , & ( ) )
814- . await ?;
815- Ok ( ( ) )
837+ // /realtime/calls endpoints return empty responses on success
838+ self . post_empty ( & format ! ( "realtime/calls/{call_id}/hangup" ) , & ( ) )
839+ . await
816840 }
817841
818842 /// Note that `reject_call` is very poorly documented and seems to be non-functional even in the GA release as of 2025-09-11:
@@ -825,9 +849,8 @@ impl OpenAIClient {
825849 /// a sensible workaround is to `accept` the call and immediately `hangup`. See `hangup_call`.
826850 pub async fn reject_call ( & mut self , call_id : & str ) -> Result < ( ) , APIError > {
827851 // ditto WRT successful body
828- self . post :: < String > ( & format ! ( "realtime/calls/{call_id}/reject" ) , & ( ) )
829- . await ?;
830- Ok ( ( ) )
852+ self . post_empty ( & format ! ( "realtime/calls/{call_id}/reject" ) , & ( ) )
853+ . await
831854 }
832855
833856 pub async fn refer_call (
@@ -836,9 +859,8 @@ impl OpenAIClient {
836859 refer : ReferCallRequest ,
837860 ) -> Result < ( ) , APIError > {
838861 // ditto WRT successful body
839- self . post :: < String > ( & format ! ( "realtime/calls/{call_id}/refer" ) , & refer)
840- . await ?;
841- Ok ( ( ) )
862+ self . post_empty ( & format ! ( "realtime/calls/{call_id}/refer" ) , & refer)
863+ . await
842864 }
843865
844866 fn build_url_with_preserved_query ( & self , path : & str ) -> Result < String , url:: ParseError > {
0 commit comments