Currently, Spring AI only provides a straightforward way to set custom HTTP headers in certain provider-specific integrations (e.g., spring.ai.azure.openai.custom-headers for Azure OpenAI). For other providers accessed via the ChatClient API — especially those using OpenAI-compatible endpoints like Google Gemini — there is no native mechanism to set provider-specific HTTP headers during client creation.

Expected Behavior Enable adding custom HTTP headers directly when building a ChatClient. For example:

ChatClient client = ChatClient.builder() .baseUrl("https://generativelanguage.googleapis.com/v1beta/openai/") .apiKey("...") .customHeader("X-Server-Throughput-Key", "my-throughput-token") .customHeader("Another-Header", "value") .build();

Benefits:

Simplifies integrating with providers that require extra headers (e.g., Gemini throughput provisioning keys, experimental API )

Context

I work for enterprise system. We have reserved provisioning throughput on vertex ai Gemini. But can't use it natively with Spring AI

Comment From: alanta335

have you tried using options

For example:

chatClient
                    .prompt()
                    .options(OpenAiChatOptions.builder()
                            .httpHeaders(Map.of("X-Server-Throughput-Key", "my-throughput-token"))
                            .build())

Comment From: naveenkumarsemails

have you tried using options

For example:

chatClient .prompt() .options(OpenAiChatOptions.builder() .httpHeaders(Map.of("X-Server-Throughput-Key", "my-throughput-token")) .build())

I tried using this with Azure Open AI Chat Client, and there isn't an option to set httpHeaders in the ChatOptions. I've tried everything from what I could find so far in the documentation, and there is no way to supply custom http headers to outgoing requests to the model. For example, I need to pass a custom Authorization token as the Azure Open AI instance within my organization requires a Bearer token to be present in the requests made. Is there any way to do this with Spring AI?

Comment From: YunKuiLu

You can take a look at this Azure Openai Auto Configuration doc.

You should be able to set your Http Header using AzureOpenAIClientBuilderCustomizer.

@Configuration
public class YourAzureOpenAiConfig {
    @Bean
    public AzureOpenAIClientBuilderCustomizer responseTimeoutCustomizer() {
        return openAiClientBuilder -> {
            HttpClientOptions clientOptions = new HttpClientOptions()
                    .setResponseTimeout(Duration.ofMinutes(5));
            openAiClientBuilder.httpClient(HttpClient.createDefault(clientOptions));
        };
    }
}

Comment From: naveenkumarsemails

You can take a look at this Azure Openai Auto Configuration doc.

You should be able to set your Http Header using AzureOpenAIClientBuilderCustomizer.

@Configuration public class YourAzureOpenAiConfig { @Bean public AzureOpenAIClientBuilderCustomizer responseTimeoutCustomizer() { return openAiClientBuilder -> { HttpClientOptions clientOptions = new HttpClientOptions() .setResponseTimeout(Duration.ofMinutes(5)); openAiClientBuilder.httpClient(HttpClient.createDefault(clientOptions)); }; } }

Hi, I've tried this already and does not work. Added a debug in code where the request is being made to the model, and the headers don't have any that I configured through the AzureOpenAIClientBuilderCustomizer.

Comment From: YunKuiLu

You can try to debug this code:

https://github.com/spring-projects/spring-ai/blob/90f636e4f0b580e700557ec542923a3bbfeac776/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiClientBuilderConfiguration.java#L52-L76

Comment From: naveenkumarsemails

You can try to debug this code:

spring-ai/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiClientBuilderConfiguration.java

Lines 52 to 76 in 90f636e

@Bean @ConditionalOnMissingBean // ({ OpenAIClient.class, TokenCredential.class }) public OpenAIClientBuilder openAIClientBuilder(AzureOpenAiConnectionProperties connectionProperties, ObjectProvider customizers) {

final OpenAIClientBuilder clientBuilder;

// Connect to OpenAI (e.g. not the Azure OpenAI). The deploymentName property is // used as OpenAI model name. if (StringUtils.hasText(connectionProperties.getOpenAiApiKey())) { clientBuilder = new OpenAIClientBuilder().endpoint("https://api.openai.com/v1") .credential(new KeyCredential(connectionProperties.getOpenAiApiKey())) .clientOptions(new ClientOptions().setApplicationId(APPLICATION_ID)); applyOpenAIClientBuilderCustomizers(clientBuilder, customizers); return clientBuilder; }

Map customHeaders = connectionProperties.getCustomHeaders(); List

headers = customHeaders.entrySet() .stream() .map(entry -> new Header(entry.getKey(), entry.getValue())) .collect(Collectors.toList()); ClientOptions clientOptions = new ClientOptions().setApplicationId(APPLICATION_ID).setHeaders(headers);

Assert.hasText(connectionProperties.getEndpoint(), "Endpoint must not be empty");

Thank you, I tried debugging this and noticed that the clientBuilder has all my custom headers up to line 86. The custom headers are then removed in line 90 after invoking the applyOpenAIClientBuilderCustomizers method. Would you know why?

Update: Apologies, seems like the custom headers I mentioned above were pulled from my application.properties file. I do not see any from the AzureOpenAIClientBuilderCustomizer being added. So that class isn't being picked up in the applyOpenAIClientBuilderCustomizers in line 90 as mentioned above. I verified to make sure @Configuration and @Bean annotations are present.

Update #2: Thank you @YunKuiLu - I figured out what the issue was. This was very helpful. I am now able to pass my custom headers with the request.

Comment From: ghostg00

I hope to receive support so that all model vendors have this custom HTTP header support, not just OpenAI.

Comment From: okulkarni-eis

Any update on support for providing dynamic custom headers?