Repository: openai/openai-dotnet (2026-04-15T22:30:56Z)

Issue:
Add ResponsesClientOptions in OpenAI.Responses
### Describe the feature or improvement you are requesting

Please add a dedicated `ResponsesClientOptions` type in `OpenAI.Responses` and update the Responses API surface to use it instead of `OpenAIClientOptions`.

Today, `ResponsesClient` constructors and `ResponsesClientSettings.Options` use `OpenAIClientOptions`, even though the client itself lives in the `OpenAI.Responses` namespace. A dedicated `ResponsesClientOptions` would make the API more consistent and better scoped to the Responses feature area.

### Additional context

Current usage of `OpenAIClientOptions` appears in:

- `/home/runner/work/openai-dotnet/openai-dotnet/src/Custom/Responses/ResponsesClient.cs`
- `/home/runner/work/openai-dotnet/openai-dotnet/src/Custom/Responses/ResponsesClientSettings.cs`

There is already a precedent for a feature-specific options type with `RealtimeClientOptions` in:

- `/home/runner/work/openai-dotnet/openai-dotnet/src/Custom/Realtime/RealtimeClientOptions.cs`

Suggested scope:
- Add `ResponsesClientOptions`
- Update `ResponsesClient` constructors to accept it
- Update `ResponsesClientSettings.Options` to use it
- Provide a conversion/helper path from `OpenAIClientOptions` if needed for compatibility
- Update `OpenAIClient.GetResponsesClient()` to pass Responses-specific options appropriately


Discussion:

Patch:
diff --git a/README.md b/README.md
index 35b586201..6822cadbd 100644
--- a/README.md
+++ b/README.md
@@ -978,7 +978,7 @@ var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
 
 var client = new ResponsesClient(
     new BearerTokenPolicy(new DefaultAzureCredential(), "https://ai.azure.com/.default"),
-    new OpenAIClientOptions { Endpoint = new Uri($"{endpoint}/openai/v1/") }
+    new ResponsesClientOptions { Endpoint = new Uri($"{endpoint}/openai/v1/") }
 );
 
 var response = await client.CreateResponseAsync("gpt-5-mini", "Hello world!");
diff --git a/api/OpenAI.net10.0.cs b/api/OpenAI.net10.0.cs
index 45bd66dc7..28c0bc1b4 100644
--- a/api/OpenAI.net10.0.cs
+++ b/api/OpenAI.net10.0.cs
@@ -6261,11 +6261,11 @@ public class ResponsesClient {
         protected ResponsesClient();
         [Experimental("SCME0002")]
         public ResponsesClient(ResponsesClientSettings settings);
-        public ResponsesClient(ApiKeyCredential credential, OpenAIClientOptions options);
+        public ResponsesClient(ApiKeyCredential credential, ResponsesClientOptions options);
         public ResponsesClient(ApiKeyCredential credential);
-        public ResponsesClient(AuthenticationPolicy authenticationPolicy, OpenAIClientOptions options);
+        public ResponsesClient(AuthenticationPolicy authenticationPolicy, ResponsesClientOptions options);
         public ResponsesClient(AuthenticationPolicy authenticationPolicy);
-        protected internal ResponsesClient(ClientPipeline pipeline, OpenAIClientOptions options);
+        protected internal ResponsesClient(ClientPipeline pipeline, ResponsesClientOptions options);
         public ResponsesClient(string apiKey);
         [Experimental("OPENAI001")]
         public virtual Uri Endpoint { get; }
@@ -6315,9 +6315,15 @@ public class ResponsesClient {
         public virtual AsyncCollectionResult<StreamingResponseUpdate> GetResponseStreamingAsync(GetResponseOptions options, CancellationToken cancellationToken = default);
         public virtual AsyncCollectionResult<StreamingResponseUpdate> GetResponseStreamingAsync(string responseId, CancellationToken cancellationToken = default);
     }
+    public class ResponsesClientOptions : ClientPipelineOptions {
+        public Uri Endpoint { get; set; }
+        public string OrganizationId { get; set; }
+        public string ProjectId { get; set; }
+        public string UserAgentApplicationId { get; set; }
+    }
     [Experimental("SCME0002")]
     public sealed class ResponsesClientSettings : ClientSettings {
-        public OpenAIClientOptions Options { get; set; }
+        public ResponsesClientOptions Options { get; set; }
         protected override void BindCore(Microsoft.Extensions.Configuration.IConfigurationSection section);
     }
     [Experimental("OPENAI001")]
diff --git a/api/OpenAI.net8.0.cs b/api/OpenAI.net8.0.cs
index 45bd66dc7..28c0bc1b4 100644
--- a/api/OpenAI.net8.0.cs
+++ b/api/OpenAI.net8.0.cs
@@ -6261,11 +6261,11 @@ public class ResponsesClient {
         protected ResponsesClient();
         [Experimental("SCME0002")]
         public ResponsesClient(ResponsesClientSettings settings);
-        public ResponsesClient(ApiKeyCredential credential, OpenAIClientOptions options);
+        public ResponsesClient(ApiKeyCredential credential, ResponsesClientOptions options);
         public ResponsesClient(ApiKeyCredential credential);
-        public ResponsesClient(AuthenticationPolicy authenticationPolicy, OpenAIClientOptions options);
+        public ResponsesClient(AuthenticationPolicy authenticationPolicy, ResponsesClientOptions options);
         public ResponsesClient(AuthenticationPolicy authenticationPolicy);
-        protected internal ResponsesClient(ClientPipeline pipeline, OpenAIClientOptions options);
+        protected internal ResponsesClient(ClientPipeline pipeline, ResponsesClientOptions options);
         public ResponsesClient(string apiKey);
         [Experimental("OPENAI001")]
         public virtual Uri Endpoint { get; }
@@ -6315,9 +6315,15 @@ public class ResponsesClient {
         public virtual AsyncCollectionResult<StreamingResponseUpdate> GetResponseStreamingAsync(GetResponseOptions options, CancellationToken cancellationToken = default);
         public virtual AsyncCollectionResult<StreamingResponseUpdate> GetResponseStreamingAsync(string responseId, CancellationToken cancellationToken = default);
     }
+    public class ResponsesClientOptions : ClientPipelineOptions {
+        public Uri Endpoint { get; set; }
+        public string OrganizationId { get; set; }
+        public string ProjectId { get; set; }
+        public string UserAgentApplicationId { get; set; }
+    }
     [Experimental("SCME0002")]
     public sealed class ResponsesClientSettings : ClientSettings {
-        public OpenAIClientOptions Options { get; set; }
+        public ResponsesClientOptions Options { get; set; }
         protected override void BindCore(Microsoft.Extensions.Configuration.IConfigurationSection section);
     }
     [Experimental("OPENAI001")]
diff --git a/api/OpenAI.netstandard2.0.cs b/api/OpenAI.netstandard2.0.cs
index 0af05b9f7..317dab50c 100644
--- a/api/OpenAI.netstandard2.0.cs
+++ b/api/OpenAI.netstandard2.0.cs
@@ -5466,11 +5466,11 @@ public class ResponseResult : IJsonModel<ResponseResult>, IPersistableModel<Resp
     public class ResponsesClient {
         protected ResponsesClient();
         public ResponsesClient(ResponsesClientSettings settings);
-        public ResponsesClient(ApiKeyCredential credential, OpenAIClientOptions options);
+        public ResponsesClient(ApiKeyCredential credential, ResponsesClientOptions options);
         public ResponsesClient(ApiKeyCredential credential);
-        public ResponsesClient(AuthenticationPolicy authenticationPolicy, OpenAIClientOptions options);
+        public ResponsesClient(AuthenticationPolicy authenticationPolicy, ResponsesClientOptions options);
         public ResponsesClient(AuthenticationPolicy authenticationPolicy);
-        protected internal ResponsesClient(ClientPipeline pipeline, OpenAIClientOptions options);
+        protected internal ResponsesClient(ClientPipeline pipeline, ResponsesClientOptions options);
         public ResponsesClient(string apiKey);
         public virtual Uri Endpoint { get; }
         public ClientPipeline Pipeline { get; }
@@ -5519,8 +5519,14 @@ public class ResponsesClient {
         public virtual AsyncCollectionResult<StreamingResponseUpdate> GetResponseStreamingAsync(GetResponseOptions options, CancellationToken cancellationToken = default);
         public virtual AsyncCollectionResult<StreamingResponseUpdate> GetResponseStreamingAsync(string responseId, CancellationToken cancellationToken = default);
     }
+    public class ResponsesClientOptions : ClientPipelineOptions {
+        public Uri Endpoint { get; set; }
+        public string OrganizationId { get; set; }
+        public string ProjectId { get; set; }
+        public string UserAgentApplicationId { get; set; }
+    }
     public sealed class ResponsesClientSettings : ClientSettings {
-        public OpenAIClientOptions Options { get; set; }
+        public ResponsesClientOptions Options { get; set; }
         protected override void BindCore(Microsoft.Extensions.Configuration.IConfigurationSection section);
     }
     public readonly partial struct ResponseServiceTier : IEquatable<ResponseServiceTier> {
diff --git a/src/Custom/OpenAIClient.cs b/src/Custom/OpenAIClient.cs
index 81de550b4..b718215eb 100644
--- a/src/Custom/OpenAIClient.cs
+++ b/src/Custom/OpenAIClient.cs
@@ -86,15 +86,6 @@ namespace OpenAI;
 [CodeGenSuppress("GetInternalUploadsClient")]
 public partial class OpenAIClient
 {
-    private const string OpenAIV1Endpoint = "https://api.openai.com/v1";
-
-    private static class KnownHeaderNames
-    {
-        public const string OpenAIOrganization = "OpenAI-Organization";
-        public const string OpenAIProject = "OpenAI-Project";
-        public const string UserAgent = "User-Agent";
-    }
-
     private readonly OpenAIClientOptions _options;
 
     // CUSTOM: Added as a convenience.
@@ -122,7 +113,7 @@ private static class KnownHeaderNames
     /// <param name="credential"> The <see cref="ApiKeyCredential"/> to authenticate with the service. </param>
     /// <param name="options"> The options to configure the client. </param>
     /// <exception cref="ArgumentNullException"> <paramref name="credential"/> is null. </exception>
-    public OpenAIClient(ApiKeyCredential credential, OpenAIClientOptions options) : this(OpenAIClient.CreateApiKeyAuthenticationPolicy(credential), options)
+    public OpenAIClient(ApiKeyCredential credential, OpenAIClientOptions options) : this(OpenAIClientUtilities.CreateApiKeyAuthenticationPolicy(credential), options)
     {
         _keyCredential = credential;
     }
@@ -147,8 +138,8 @@ public OpenAIClient(AuthenticationPolicy authenticationPolicy, OpenAIClientOptio
         Argument.AssertNotNull(authenticationPolicy, nameof(authenticationPolicy));
         options ??= new OpenAIClientOptions();
 
-        Pipeline = OpenAIClient.CreatePipeline(authenticationPolicy, options);
-        _endpoint = OpenAIClient.GetEndpoint(options);
+        Pipeline = OpenAIClientUtilities.CreatePipeline(authenticationPolicy, options, options.UserAgentApplicationId, options.OrganizationId, options.ProjectId);
+        _endpoint = OpenAIClientUtilities.GetEndpoint(options.Endpoint);
         _options = options;
     }
 
@@ -163,7 +154,7 @@ protected internal OpenAIClient(ClientPipeline pipeline, OpenAIClientOptions opt
         options ??= new OpenAIClientOptions();
 
         Pipeline = pipeline;
-        _endpoint = OpenAIClient.GetEndpoint(options);
+        _endpoint = OpenAIClientUtilities.GetEndpoint(options.Endpoint);
         _options = options;
     }
 
@@ -345,7 +336,13 @@ protected internal OpenAIClient(ClientPipeline pipeline, OpenAIClientOptions opt
     /// </remarks>
     /// <returns> A new <see cref="ResponsesClient"/>. </returns>
     [Experimental("OPENAI001")]
-    public virtual ResponsesClient GetResponsesClient() => new(Pipeline, _options);
+    public virtual ResponsesClient GetResponsesClient() => new(Pipeline, new ResponsesClientOptions
+    {
+        Endpoint = _options.Endpoint,
+        OrganizationId = _options.OrganizationId,
+        ProjectId = _options.ProjectId,
+        UserAgentApplicationId = _options.UserAgentApplicationId,
+    });
 
     /// <summary>
     /// Gets a new instance of <see cref="VectorStoreClient"/> that reuses the client configuration details provided to
@@ -376,44 +373,11 @@ protected internal OpenAIClient(ClientPipeline pipeline, OpenAIClientOptions opt
     public virtual VideoClient GetVideoClient() => new(Pipeline, _options);
 
     internal static AuthenticationPolicy CreateApiKeyAuthenticationPolicy(ApiKeyCredential credential)
-    {
-        Argument.AssertNotNull(credential, nameof(credential));
-        return ApiKeyAuthenticationPolicy.CreateHeaderApiKeyPolicy(credential, AuthorizationHeader, AuthorizationApiKeyPrefix);
-    }
+        => OpenAIClientUtilities.CreateApiKeyAuthenticationPolicy(credential);
 
     internal static ClientPipeline CreatePipeline(AuthenticationPolicy authenticationPolicy, OpenAIClientOptions options)
-    {
-        return ClientPipeline.Create(
-            options: options,
-            perCallPolicies: [CreateAddCustomHeadersPolicy(options)],
-            perTryPolicies: [authenticationPolicy],
-            beforeTransportPolicies: []);
-    }
+        => OpenAIClientUtilities.CreatePipeline(authenticationPolicy, options, options?.UserAgentApplicationId, options?.OrganizationId, options?.ProjectId);
 
     internal static Uri GetEndpoint(OpenAIClientOptions options = null)
-    {
-        return options?.Endpoint ?? new(OpenAIV1Endpoint);
-    }
-
-    private static PipelinePolicy CreateAddCustomHeadersPolicy(OpenAIClientOptions options = null)
-    {
-        TelemetryDetails telemetryDetails = new(typeof(OpenAIClientOptions).Assembly, options?.UserAgentApplicationId);
-        return new GenericActionPipelinePolicy((message) =>
-        {
-            if (message?.Request?.Headers?.TryGetValue(KnownHeaderNames.UserAgent, out string _) == false)
-            {
-                message.Request.Headers.Set(KnownHeaderNames.UserAgent, telemetryDetails.ToString());
-            }
-
-            if (!string.IsNullOrEmpty(options?.OrganizationId))
-            {
-                message.Request.Headers.Set(KnownHeaderNames.OpenAIOrganization, options.OrganizationId);
-            }
-
-            if (!string.IsNullOrEmpty(options?.ProjectId))
-            {
-                message.Request.Headers.Set(KnownHeaderNames.OpenAIProject, options.ProjectId);
-            }
-        });
-    }
+        => OpenAIClientUtilities.GetEndpoint(options?.Endpoint);
 }
diff --git a/src/Custom/Realtime/RealtimeClient.cs b/src/Custom/Realtime/RealtimeClient.cs
index 8de09fa06..b92ee7ad8 100644
--- a/src/Custom/Realtime/RealtimeClient.cs
+++ b/src/Custom/Realtime/RealtimeClient.cs
@@ -9,15 +9,6 @@ namespace OpenAI.Realtime;
 [CodeGenType("Realtime")]
 public partial class RealtimeClient
 {
-    private const string DefaultEndpoint = "https://api.openai.com/v1";
-
-    private static class KnownHeaderNames
-    {
-        public const string OpenAIOrganization = "OpenAI-Organization";
-        public const string OpenAIProject = "OpenAI-Project";
-        public const string UserAgent = "User-Agent";
-    }
-
     public event EventHandler<BinaryData> OnSendingCommand;
     public event EventHandler<BinaryData> OnReceivingCommand;
 
@@ -49,7 +40,7 @@ private static class KnownHeaderNames
     /// <param name="credential"> The <see cref="ApiKeyCredential"/> to authenticate with the service. </param>
     /// <param name="options"> The options to configure the client. </param>
     /// <exception cref="ArgumentNullException"> <paramref name="credential"/> is null. </exception>
-    public RealtimeClient(ApiKeyCredential credential, RealtimeClientOptions options) : this(OpenAIClient.CreateApiKeyAuthenticationPolicy(credential), options)
+    public RealtimeClient(ApiKeyCredential credential, RealtimeClientOptions options) : this(OpenAIClientUtilities.CreateApiKeyAuthenticationPolicy(credential), options)
     {
         _keyCredential = credential;
     }
@@ -74,8 +65,8 @@ public RealtimeClient(AuthenticationPolicy authenticationPolicy, RealtimeClientO
         Argument.AssertNotNull(authenticationPolicy, nameof(authenticationPolicy));
         options ??= new RealtimeClientOptions();
 
-        Pipeline = CreatePipeline(authenticationPolicy, options);
-        _endpoint = GetEndpoint(options);
+        Pipeline = OpenAIClientUtilities.CreatePipeline(authenticationPolicy, options, options.UserAgentApplicationId, options.OrganizationId, options.ProjectId);
+        _endpoint = OpenAIClientUtilities.GetEndpoint(options.Endpoint);
         _webSocketEndpoint = GetWebSocketEndpoint(options);
     }
 
@@ -93,7 +84,7 @@ protected internal RealtimeClient(ClientPipeline pipeline, RealtimeClientOptions
         options ??= new RealtimeClientOptions();
 
         Pipeline = pipeline;
-        _endpoint = GetEndpoint(options);
+        _endpoint = OpenAIClientUtilities.GetEndpoint(options.Endpoint);
         _webSocketEndpoint = GetWebSocketEndpoint(options);
     }
 
@@ -109,14 +100,9 @@ public RealtimeClient(RealtimeClientSettings settings)
     [Experimental("OPENAI001")]
     public Uri Endpoint => _endpoint;
 
-    private static Uri GetEndpoint(RealtimeClientOptions options = null)
-    {
-        return options?.Endpoint ?? new(DefaultEndpoint);
-    }
-
     private static Uri GetWebSocketEndpoint(RealtimeClientOptions options = null)
     {
-        UriBuilder uriBuilder = new(options?.Endpoint ?? new(DefaultEndpoint));
+        UriBuilder uriBuilder = new(OpenAIClientUtilities.GetEndpoint(options?.Endpoint));
         uriBuilder.Scheme = uriBuilder.Scheme.ToLowerInvariant() switch
         {
             "http" => "ws",
@@ -132,37 +118,6 @@ private static Uri GetWebSocketEndpoint(RealtimeClientOptions options = null)
         return uriBuilder.Uri;
     }
 
-    private static ClientPipeline CreatePipeline(AuthenticationPolicy authenticationPolicy, RealtimeClientOptions options)
-    {
-        return ClientPipeline.Create(
-            options: options,
-            perCallPolicies: [CreateAddCustomHeadersPolicy(options)],
-            perTryPolicies: [authenticationPolicy],
-            beforeTransportPolicies: []);
-    }
-
-    private static PipelinePolicy CreateAddCustomHeadersPolicy(RealtimeClientOptions options = null)
-    {
-        TelemetryDetails telemetryDetails = new(typeof(RealtimeClientOptions).Assembly, options?.UserAgentApplicationId);
-        return new GenericActionPipelinePolicy((message) =>
-        {
-            if (message?.Request?.Headers?.TryGetValue(KnownHeaderNames.UserAgent, out string _) == false)
-            {
-                message.Request.Headers.Set(KnownHeaderNames.UserAgent, telemetryDetails.ToString());
-            }
-
-            if (!string.IsNullOrEmpty(options?.OrganizationId))
-            {
-                message.Request.Headers.Set(KnownHeaderNames.OpenAIOrganization, options.OrganizationId);
-            }
-
-            if (!string.IsNullOrEmpty(options?.ProjectId))
-            {
-                message.Request.Headers.Set(KnownHeaderNames.OpenAIProject, options.ProjectId);
-            }
-        });
-    }
-
     internal void RaiseOnSendingCommand<T>(T session, BinaryData data)
         => OnSendingCommand?.Invoke(session, data);
 
diff --git a/src/Custom/Responses/ResponsesClient.cs b/src/Custom/Responses/ResponsesClient.cs
index 0c24b3abc..1d4219a84 100644
--- a/src/Custom/Responses/ResponsesClient.cs
+++ b/src/Custom/Responses/ResponsesClient.cs
@@ -28,7 +28,7 @@ public partial class ResponsesClient
     /// <summary> Initializes a new instance of <see cref="ResponsesClient"/>. </summary>
     /// <param name="apiKey"> The API key to authenticate with the service. </param>
     /// <exception cref="ArgumentNullException"> <paramref name="apiKey"/> is null. </exception>
-    public ResponsesClient(string apiKey) : this(new ApiKeyCredential(apiKey), new OpenAIClientOptions())
+    public ResponsesClient(string apiKey) : this(new ApiKeyCredential(apiKey), new ResponsesClientOptions())
     {
     }
 
@@ -38,7 +38,7 @@ public partial class ResponsesClient
     /// <summary> Initializes a new instance of <see cref="ResponsesClient"/>. </summary>
     /// <param name="credential"> The <see cref="ApiKeyCredential"/> to authenticate with the service. </param>
     /// <exception cref="ArgumentNullException"> <paramref name="credential"/> is null. </exception>
-    public ResponsesClient(ApiKeyCredential credential) : this(credential, new OpenAIClientOptions())
+    public ResponsesClient(ApiKeyCredential credential) : this(credential, new ResponsesClientOptions())
     {
     }
 
@@ -49,7 +49,7 @@ public partial class ResponsesClient
     /// <param name="credential"> The <see cref="ApiKeyCredential"/> to authenticate with the service. </param>
     /// <param name="options"> The options to configure the client. </param>
     /// <exception cref="ArgumentNullException"> <paramref name="credential"/> is null. </exception>
-    public ResponsesClient(ApiKeyCredential credential, OpenAIClientOptions options) : this(OpenAIClient.CreateApiKeyAuthenticationPolicy(credential), options)
+    public ResponsesClient(ApiKeyCredential credential, ResponsesClientOptions options) : this(OpenAIClientUtilities.CreateApiKeyAuthenticationPolicy(credential), options)
     {
     }
 
@@ -57,7 +57,7 @@ public ResponsesClient(ApiKeyCredential credential, OpenAIClientOptions options)
     /// <summary> Initializes a new instance of <see cref="ResponsesClient"/>. </summary>
     /// <param name="authenticationPolicy"> The authentication policy used to authenticate with the service. </param>
     /// <exception cref="ArgumentNullException"> <paramref name="authenticationPolicy"/> is null. </exception>
-    public ResponsesClient(AuthenticationPolicy authenticationPolicy) : this(authenticationPolicy, new OpenAIClientOptions())
+    public ResponsesClient(AuthenticationPolicy authenticationPolicy) : this(authenticationPolicy, new ResponsesClientOptions())
     {
     }
 
@@ -66,13 +66,13 @@ public ResponsesClient(ApiKeyCredential credential, OpenAIClientOptions options)
     /// <param name="authenticationPolicy"> The authentication policy used to authenticate with the service. </param>
     /// <param name="options"> The options to configure the client. </param>
     /// <exception cref="ArgumentNullException"> <paramref name="authenticationPolicy"/> is null. </exception>
-    public ResponsesClient(AuthenticationPolicy authenticationPolicy, OpenAIClientOptions options)
+    public ResponsesClient(AuthenticationPolicy authenticationPolicy, ResponsesClientOptions options)
     {
         Argument.AssertNotNull(authenticationPolicy, nameof(authenticationPolicy));
-        options ??= new OpenAIClientOptions();
+        options ??= new ResponsesClientOptions();
 
-        Pipeline = OpenAIClient.CreatePipeline(authenticationPolicy, options);
-        _endpoint = OpenAIClient.GetEndpoint(options);
+        Pipeline = OpenAIClientUtilities.CreatePipeline(authenticationPolicy, options, options.UserAgentApplicationId, options.OrganizationId, options.ProjectId);
+        _endpoint = OpenAIClientUtilities.GetEndpoint(options.Endpoint);
     }
 
     // CUSTOM:
@@ -83,13 +83,13 @@ public ResponsesClient(AuthenticationPolicy authenticationPolicy, OpenAIClientOp
     /// <param name="pipeline"> The HTTP pipeline to send and receive REST requests and responses. </param>
     /// <param name="options"> The options to configure the client. </param>
     /// <exception cref="ArgumentNullException"> <paramref name="pipeline"/> is null. </exception>
-    protected internal ResponsesClient(ClientPipeline pipeline, OpenAIClientOptions options)
+    protected internal ResponsesClient(ClientPipeline pipeline, ResponsesClientOptions options)
     {
         Argument.AssertNotNull(pipeline, nameof(pipeline));
-        options ??= new OpenAIClientOptions();
+        options ??= new ResponsesClientOptions();
 
         Pipeline = pipeline;
-        _endpoint = OpenAIClient.GetEndpoint(options);
+        _endpoint = OpenAIClientUtilities.GetEndpoint(options.Endpoint);
     }
 
     [Experimental("SCME0002")]
diff --git a/src/Custom/Responses/ResponsesClientOptions.cs b/src/Custom/Responses/ResponsesClientOptions.cs
new file mode 100644
index 000000000..f74e5da2c
--- /dev/null
+++ b/src/Custom/Responses/ResponsesClientOptions.cs
@@ -0,0 +1,104 @@
+using Microsoft.Extensions.Configuration;
+using System;
+using System.ClientModel.Primitives;
+
+namespace OpenAI.Responses;
+
+/// <summary> The options to configure the <see cref="ResponsesClient"/>. </summary>
+public class ResponsesClientOptions : ClientPipelineOptions
+{
+    private Uri _endpoint;
+    private string _organizationId;
+    private string _projectId;
+    private string _userAgentApplicationId;
+
+    /// <summary>
+    /// The service endpoint that the client will send requests to. If not set, the default endpoint will be used.
+    /// </summary>
+    public Uri Endpoint
+    {
+        get => _endpoint;
+        set
+        {
+            AssertNotFrozen();
+            _endpoint = value;
+        }
+    }
+
+    /// <summary>
+    /// The value to use for the <c>OpenAI-Organization</c> request header. Users who belong to multiple organizations
+    /// can set this value to specify which organization is used for an API request. Usage from these API requests will
+    /// count against the specified organization's quota. If not set, the header will be omitted, and the default
+    /// organization will be billed. You can change your default organization in your user settings.
+    /// <see href="https://platform.openai.com/docs/guides/production-best-practices/setting-up-your-organization">Learn more</see>.
+    /// </summary>
+    public string OrganizationId
+    {
+        get => _organizationId;
+        set
+        {
+            AssertNotFrozen();
+            _organizationId = value;
+        }
+    }
+
+    /// <summary>
+    /// The value to use for the <c>OpenAI-Project</c> request header. Users who are accessing their projects through
+    /// their legacy user API key can set this value to specify which project is used for an API request. Usage from
+    /// these API requests will count as usage for the specified project. If not set, the header will be omitted, and
+    /// the default project will be accessed.
+    /// </summary>
+    public string ProjectId
+    {
+        get => _projectId;
+        set
+        {
+            AssertNotFrozen();
+            _projectId = value;
+        }
+    }
+
+    /// <summary>
+    /// An optional application ID to use as part of the request User-Agent header.
+    /// </summary>
+    public string UserAgentApplicationId
+    {
+        get => _userAgentApplicationId;
+        set
+        {
+            AssertNotFrozen();
+            _userAgentApplicationId = value;
+        }
+    }
+
+    public ResponsesClientOptions()
+    {
+    }
+
+    /// <summary>
+    /// Internal constructor for binding from a configuration section.
+    /// Used by ClientSettings classes to bind nested "Options" section.
+    /// </summary>
+    internal ResponsesClientOptions(IConfigurationSection section)
+    {
+        if (Uri.TryCreate(section[nameof(Endpoint)], UriKind.Absolute, out Uri endpoint))
+        {
+            Endpoint = endpoint;
+        }
+
+        if (section[nameof(OrganizationId)] is string organizationId)
+        {
+            OrganizationId = organizationId;
+        }
+
+        if (section[nameof(ProjectId)] is string projectId)
+        {
+            ProjectId = projectId;
+        }
+
+        if (section[nameof(UserAgentApplicationId)] is string userAgentApplicationId)
+        {
+            UserAgentApplicationId = userAgentApplicationId;
+        }
+    }
+}
diff --git a/src/Custom/Responses/ResponsesClientSettings.cs b/src/Custom/Responses/ResponsesClientSettings.cs
index 5f97de89a..df6ab1736 100644
--- a/src/Custom/Responses/ResponsesClientSettings.cs
+++ b/src/Custom/Responses/ResponsesClientSettings.cs
@@ -7,14 +7,14 @@ namespace OpenAI.Responses;
 [Experimental("SCME0002")]
 public sealed class ResponsesClientSettings : ClientSettings
 {
-    public OpenAIClientOptions Options { get; set; }
+    public ResponsesClientOptions Options { get; set; }
 
     protected override void BindCore(IConfigurationSection section)
     {
         var optionsSection = section.GetSection("Options");
         if (optionsSection.Exists())
         {
-            Options ??= new OpenAIClientOptions(optionsSection);
+            Options ??= new ResponsesClientOptions(optionsSection);
         }
     }
 }
diff --git a/src/Utility/OpenAIClientUtilities.cs b/src/Utility/OpenAIClientUtilities.cs
new file mode 100644
index 000000000..07fa2a7d7
--- /dev/null
+++ b/src/Utility/OpenAIClientUtilities.cs
@@ -0,0 +1,64 @@
+using System;
+using System.ClientModel;
+using System.ClientModel.Primitives;
+
+namespace OpenAI;
+
+internal static class OpenAIClientUtilities
+{
+    public const string OpenAIV1Endpoint = "https://api.openai.com/v1";
+
+    private const string AuthorizationHeader = "Authorization";
+    private const string AuthorizationApiKeyPrefix = "Bearer";
+
+    private const string OpenAIOrganizationHeaderName = "OpenAI-Organization";
+    private const string OpenAIProjectHeaderName = "OpenAI-Project";
+    private const string UserAgentHeaderName = "User-Agent";
+
+    public static AuthenticationPolicy CreateApiKeyAuthenticationPolicy(ApiKeyCredential credential)
+    {
+        Argument.AssertNotNull(credential, nameof(credential));
+        return ApiKeyAuthenticationPolicy.CreateHeaderApiKeyPolicy(credential, AuthorizationHeader, AuthorizationApiKeyPrefix);
+    }
+
+    public static ClientPipeline CreatePipeline(
+        AuthenticationPolicy authenticationPolicy,
+        ClientPipelineOptions options,
+        string userAgentApplicationId,
+        string organizationId,
+        string projectId)
+    {
+        return ClientPipeline.Create(
+            options: options,
+            perCallPolicies: [CreateAddCustomHeadersPolicy(userAgentApplicationId, organizationId, projectId)],
+            perTryPolicies: [authenticationPolicy],
+            beforeTransportPolicies: []);
+    }
+
+    public static Uri GetEndpoint(Uri endpoint)
+    {
+        return endpoint ?? new Uri(OpenAIV1Endpoint);
+    }
+
+    private static PipelinePolicy CreateAddCustomHeadersPolicy(string userAgentApplicationId, string organizationId, string projectId)
+    {
+        TelemetryDetails telemetryDetails = new(typeof(OpenAIClientUtilities).Assembly, userAgentApplicationId);
+        return new GenericActionPipelinePolicy((message) =>
+        {
+            if (message?.Request?.Headers?.TryGetValue(UserAgentHeaderName, out string _) == false)
+            {
+                message.Request.Headers.Set(UserAgentHeaderName, telemetryDetails.ToString());
+            }
+
+            if (!string.IsNullOrEmpty(organizationId))
+            {
+                message.Request.Headers.Set(OpenAIOrganizationHeaderName, organizationId);
+            }
+
+            if (!string.IsNullOrEmpty(projectId))
+            {
+                message.Request.Headers.Set(OpenAIProjectHeaderName, projectId);
+            }
+        });
+    }
+}


Test patch:
diff --git a/tests/Snippets/ReadMeSnippets.cs b/tests/Snippets/ReadMeSnippets.cs
index 9fda333ff..096f51f58 100644
--- a/tests/Snippets/ReadMeSnippets.cs
+++ b/tests/Snippets/ReadMeSnippets.cs
@@ -1180,7 +1180,7 @@ public async Task AzureOpenAI()
 
         var client = new ResponsesClient(
             new BearerTokenPolicy(new DefaultAzureCredential(), "https://ai.azure.com/.default"),
-            new OpenAIClientOptions { Endpoint = new Uri($"{endpoint}/openai/v1/") }
+            new ResponsesClientOptions { Endpoint = new Uri($"{endpoint}/openai/v1/") }
         );
 
 #if SNIPPET
diff --git a/tests/Utility/OpenAITestEnvironment.cs b/tests/Utility/OpenAITestEnvironment.cs
index 467b5b2de..b59a35764 100644
--- a/tests/Utility/OpenAITestEnvironment.cs
+++ b/tests/Utility/OpenAITestEnvironment.cs
@@ -155,7 +155,7 @@ public T GetTestClient<T>(string modelName = default, OpenAIClientOptions option
             nameof(VectorStoreClient) => new VectorStoreClient(credential, options),
             nameof(OpenAIClient) => new OpenAIClient(credential, options),
             nameof(RealtimeClient) => new RealtimeClient(credential, CreateRealtimeClientOptions(options)),
-            nameof(ResponsesClient) => new ResponsesClient(credential, options),
+            nameof(ResponsesClient) => new ResponsesClient(credential, CreateResponsesClientOptions(options)),
             nameof(SkillClient) => new SkillClient(credential, options),
             _ => throw new NotImplementedException($"Unsupported client type: {typeof(T).Name}"),
         };
@@ -175,6 +175,14 @@ public T GetTestClient<T>(string modelName = default, OpenAIClientOptions option
         UserAgentApplicationId = options?.UserAgentApplicationId,
     };
 
+    private static ResponsesClientOptions CreateResponsesClientOptions(OpenAIClientOptions options) => new()
+    {
+        Endpoint = options?.Endpoint,
+        OrganizationId = options?.OrganizationId,
+        ProjectId = options?.ProjectId,
+        UserAgentApplicationId = options?.UserAgentApplicationId,
+    };
+
     private static bool TryReadEnvFile(string filePath,
                                        Dictionary<string, string> environment)
     {