diff --git a/dotnet/samples/Concepts/Embeddings/VoyageAI_TextEmbedding.cs b/dotnet/samples/Concepts/Embeddings/VoyageAI_TextEmbedding.cs
new file mode 100644
index 000000000000..f3f6569721a4
--- /dev/null
+++ b/dotnet/samples/Concepts/Embeddings/VoyageAI_TextEmbedding.cs
@@ -0,0 +1,46 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Microsoft.SemanticKernel;
+using Microsoft.SemanticKernel.Connectors.VoyageAI;
+
+namespace Embeddings;
+
+///
+/// Example demonstrating VoyageAI text embeddings with Semantic Kernel.
+///
+public class VoyageAI_TextEmbedding(ITestOutputHelper output) : BaseTest(output)
+{
+ [Fact]
+ public async Task GenerateTextEmbeddingsAsync()
+ {
+ // Get API key from environment
+ var apiKey = Environment.GetEnvironmentVariable("VOYAGE_AI_API_KEY")
+ ?? throw new InvalidOperationException("Please set the VOYAGE_AI_API_KEY environment variable");
+
+ // Create embedding service
+ var embeddingService = new VoyageAITextEmbeddingGenerationService(
+ modelId: "voyage-3-large",
+ apiKey: apiKey
+ );
+
+ // Generate embeddings
+ var texts = new List
+ {
+ "Semantic Kernel is an SDK for integrating AI models",
+ "VoyageAI provides high-quality embeddings",
+ "C# is a modern, object-oriented programming language"
+ };
+
+ Console.WriteLine("Generating embeddings for:");
+ for (int i = 0; i < texts.Count; i++)
+ {
+ Console.WriteLine($"{i + 1}. {texts[i]}");
+ }
+
+ var embeddings = await embeddingService.GenerateEmbeddingsAsync(texts);
+
+ Console.WriteLine($"\nGenerated {embeddings.Count} embeddings");
+ Console.WriteLine($"Embedding dimension: {embeddings[0].Length}");
+ Console.WriteLine($"First embedding (first 5 values): [{string.Join(", ", embeddings[0].Span[..5].ToArray())}]");
+ }
+}
diff --git a/dotnet/samples/Concepts/Reranking/VoyageAI_Reranking.cs b/dotnet/samples/Concepts/Reranking/VoyageAI_Reranking.cs
new file mode 100644
index 000000000000..9071b9a40852
--- /dev/null
+++ b/dotnet/samples/Concepts/Reranking/VoyageAI_Reranking.cs
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Microsoft.SemanticKernel;
+using Microsoft.SemanticKernel.Connectors.VoyageAI;
+
+namespace Reranking;
+
+///
+/// Example demonstrating VoyageAI reranking with Semantic Kernel.
+///
+public class VoyageAI_Reranking(ITestOutputHelper output) : BaseTest(output)
+{
+ [Fact]
+ public async Task RerankDocumentsAsync()
+ {
+ // Get API key from environment
+ var apiKey = Environment.GetEnvironmentVariable("VOYAGE_AI_API_KEY")
+ ?? throw new InvalidOperationException("Please set the VOYAGE_AI_API_KEY environment variable");
+
+ // Create reranking service
+ var rerankingService = new VoyageAITextRerankingService(
+ modelId: "rerank-2.5",
+ apiKey: apiKey
+ );
+
+ // Define query and documents
+ var query = "What are the key features of Semantic Kernel?";
+
+ var documents = new List
+ {
+ "Semantic Kernel is an open-source SDK that lets you easily build agents that can call your existing code.",
+ "The capital of France is Paris, a beautiful city known for its art and culture.",
+ "Python is a high-level, interpreted programming language with dynamic typing.",
+ "Semantic Kernel provides enterprise-ready AI orchestration with model flexibility and plugin ecosystem.",
+ "Machine learning models require large amounts of data for training."
+ };
+
+ Console.WriteLine($"Query: {query}\n");
+ Console.WriteLine("Documents to rerank:");
+ for (int i = 0; i < documents.Count; i++)
+ {
+ Console.WriteLine($"{i + 1}. {documents[i]}");
+ }
+
+ // Rerank documents
+ var results = await rerankingService.RerankAsync(query, documents);
+
+ Console.WriteLine("\nReranked results (sorted by relevance):");
+ for (int i = 0; i < results.Count; i++)
+ {
+ var result = results[i];
+ Console.WriteLine($"\n{i + 1}. Score: {result.RelevanceScore:F4}");
+ Console.WriteLine($" Original Index: {result.Index}");
+ Console.WriteLine($" Text: {result.Text}");
+ }
+ }
+}
diff --git a/dotnet/src/Connectors/Connectors.VoyageAI.UnitTests/Connectors.VoyageAI.UnitTests.csproj b/dotnet/src/Connectors/Connectors.VoyageAI.UnitTests/Connectors.VoyageAI.UnitTests.csproj
new file mode 100644
index 000000000000..a99f7bef1a18
--- /dev/null
+++ b/dotnet/src/Connectors/Connectors.VoyageAI.UnitTests/Connectors.VoyageAI.UnitTests.csproj
@@ -0,0 +1,25 @@
+
+
+
+ net9.0
+ Microsoft.SemanticKernel.Connectors.VoyageAI.UnitTests
+ Microsoft.SemanticKernel.Connectors.VoyageAI.UnitTests
+ false
+ true
+ enable
+ $(NoWarn);SKEXP0001
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dotnet/src/Connectors/Connectors.VoyageAI.UnitTests/Services/VoyageAIContextualizedEmbeddingGenerationServiceTests.cs b/dotnet/src/Connectors/Connectors.VoyageAI.UnitTests/Services/VoyageAIContextualizedEmbeddingGenerationServiceTests.cs
new file mode 100644
index 000000000000..0cadc50bf042
--- /dev/null
+++ b/dotnet/src/Connectors/Connectors.VoyageAI.UnitTests/Services/VoyageAIContextualizedEmbeddingGenerationServiceTests.cs
@@ -0,0 +1,342 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Http;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.SemanticKernel.Connectors.VoyageAI;
+using Xunit;
+
+namespace Microsoft.SemanticKernel.Connectors.VoyageAI.UnitTests.Services;
+
+///
+/// Unit tests for .
+///
+public sealed class VoyageAIContextualizedEmbeddingGenerationServiceTests : IDisposable
+{
+ private readonly HttpMessageHandlerStub _messageHandlerStub;
+ private readonly HttpClient _httpClient;
+
+ public VoyageAIContextualizedEmbeddingGenerationServiceTests()
+ {
+ this._messageHandlerStub = new HttpMessageHandlerStub();
+ this._httpClient = new HttpClient(this._messageHandlerStub);
+ }
+
+ [Fact]
+ public void Constructor_WithValidParameters_CreatesInstance()
+ {
+ // Arrange & Act
+ var service = new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: "voyage-3",
+ apiKey: "test-api-key",
+ httpClient: this._httpClient
+ );
+
+ // Assert
+ service.Should().NotBeNull();
+ service.Attributes.Should().ContainKey("ModelId");
+ service.Attributes["ModelId"].Should().Be("voyage-3");
+ }
+
+ [Fact]
+ public void Constructor_WithNullModelId_ThrowsArgumentNullException()
+ {
+ // Act & Assert
+ Assert.Throws(() =>
+ new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: null!,
+ apiKey: "test-api-key"
+ )
+ );
+ }
+
+ [Fact]
+ public void Constructor_WithNullApiKey_ThrowsArgumentNullException()
+ {
+ // Act & Assert
+ Assert.Throws(() =>
+ new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: "voyage-3",
+ apiKey: null!
+ )
+ );
+ }
+
+ [Fact]
+ public async Task GenerateContextualizedEmbeddingsAsync_ReturnsEmbeddings()
+ {
+ // Arrange
+ var expectedEmbeddings = new List
+ {
+ new[] { 0.1f, 0.2f, 0.3f },
+ new[] { 0.4f, 0.5f, 0.6f }
+ };
+
+ var responseContent = JsonSerializer.Serialize(new
+ {
+ results = new[]
+ {
+ new
+ {
+ embeddings = new[]
+ {
+ new { embedding = expectedEmbeddings[0], index = 0 },
+ new { embedding = expectedEmbeddings[1], index = 1 }
+ }
+ }
+ },
+ total_tokens = 20
+ });
+
+ this._messageHandlerStub.ResponseToReturn = new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent(responseContent)
+ };
+
+ var service = new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: "voyage-3",
+ apiKey: "test-api-key",
+ httpClient: this._httpClient
+ );
+
+ var inputs = new List>
+ {
+ new List { "chunk1", "chunk2" }
+ };
+
+ // Act
+ var result = await service.GenerateContextualizedEmbeddingsAsync(inputs).ConfigureAwait(false);
+
+ // Assert
+ result.Should().NotBeNull();
+ result.Should().HaveCount(2);
+ result[0].Length.Should().Be(3);
+ result[1].Length.Should().Be(3);
+ }
+
+ [Fact]
+ public async Task GenerateContextualizedEmbeddingsAsync_SendsCorrectRequest()
+ {
+ // Arrange
+ var responseContent = JsonSerializer.Serialize(new
+ {
+ results = new[]
+ {
+ new
+ {
+ embeddings = new[]
+ {
+ new { embedding = new[] { 0.1f, 0.2f }, index = 0 }
+ }
+ }
+ },
+ total_tokens = 10
+ });
+
+ this._messageHandlerStub.ResponseToReturn = new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent(responseContent)
+ };
+
+ var service = new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: "voyage-3",
+ apiKey: "test-api-key",
+ httpClient: this._httpClient
+ );
+
+ var inputs = new List>
+ {
+ new List { "test chunk" }
+ };
+
+ // Act
+ await service.GenerateContextualizedEmbeddingsAsync(inputs).ConfigureAwait(false);
+
+ // Assert
+ this._messageHandlerStub.RequestContent.Should().NotBeNull();
+ this._messageHandlerStub.RequestContent.Should().Contain("voyage-3");
+ this._messageHandlerStub.RequestContent.Should().Contain("test chunk");
+ this._messageHandlerStub.RequestHeaders.Should().ContainKey("Authorization");
+ }
+
+ [Fact]
+ public async Task GenerateContextualizedEmbeddingsAsync_SendsCorrectModel()
+ {
+ // Arrange
+ var responseContent = JsonSerializer.Serialize(new
+ {
+ results = new[]
+ {
+ new
+ {
+ embeddings = new[]
+ {
+ new { embedding = new[] { 0.1f, 0.2f }, index = 0 }
+ }
+ }
+ },
+ total_tokens = 10
+ });
+
+ this._messageHandlerStub.ResponseToReturn = new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent(responseContent)
+ };
+
+ var service = new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: "voyage-3",
+ apiKey: "test-api-key",
+ httpClient: this._httpClient
+ );
+
+ var inputs = new List>
+ {
+ new List { "test chunk" }
+ };
+
+ // Act
+ var result = await service.GenerateContextualizedEmbeddingsAsync(inputs).ConfigureAwait(false);
+
+ // Assert
+ result.Should().NotBeNull();
+ this._messageHandlerStub.RequestContent.Should().NotBeNull();
+ this._messageHandlerStub.RequestContent.Should().Contain("voyage-3");
+ }
+
+ [Fact]
+ public async Task GenerateContextualizedEmbeddingsAsync_HandlesApiError()
+ {
+ // Arrange
+ this._messageHandlerStub.ResponseToReturn = new HttpResponseMessage(HttpStatusCode.BadRequest)
+ {
+ Content = new StringContent("API error")
+ };
+
+ var service = new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: "voyage-3",
+ apiKey: "test-api-key",
+ httpClient: this._httpClient
+ );
+
+ var inputs = new List>
+ {
+ new List { "test" }
+ };
+
+ // Act & Assert
+ await Assert.ThrowsAsync(
+ async () => await service.GenerateContextualizedEmbeddingsAsync(inputs).ConfigureAwait(false)
+ ).ConfigureAwait(false);
+ }
+
+ [Fact]
+ public async Task GenerateEmbeddingsAsync_WrapsToContextualizedCall()
+ {
+ // Arrange
+ var expectedEmbedding = new[] { 0.1f, 0.2f, 0.3f };
+
+ var responseContent = JsonSerializer.Serialize(new
+ {
+ results = new[]
+ {
+ new
+ {
+ embeddings = new[]
+ {
+ new { embedding = expectedEmbedding, index = 0 }
+ }
+ }
+ },
+ total_tokens = 10
+ });
+
+ this._messageHandlerStub.ResponseToReturn = new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent(responseContent)
+ };
+
+ var service = new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: "voyage-3",
+ apiKey: "test-api-key",
+ httpClient: this._httpClient
+ );
+
+ var data = new List { "text1" };
+
+ // Act
+ var result = await service.GenerateEmbeddingsAsync(data).ConfigureAwait(false);
+
+ // Assert
+ result.Should().NotBeNull();
+ result.Should().HaveCount(1);
+ result[0].Length.Should().Be(3);
+ }
+
+ [Fact]
+ public void Attributes_ContainsModelId()
+ {
+ // Arrange & Act
+ var service = new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: "voyage-3",
+ apiKey: "test-api-key",
+ httpClient: this._httpClient
+ );
+
+ // Assert
+ service.Attributes.Should().ContainKey("ModelId");
+ service.Attributes["ModelId"].Should().Be("voyage-3");
+ }
+
+ [Fact]
+ public void ServiceShouldUseCustomEndpoint()
+ {
+ // Arrange
+ var customEndpoint = "https://custom.api.com/v1";
+
+ // Act
+ var service = new VoyageAIContextualizedEmbeddingGenerationService(
+ modelId: "voyage-3",
+ apiKey: "test-api-key",
+ endpoint: customEndpoint,
+ httpClient: this._httpClient
+ );
+
+ // Assert
+ service.Should().NotBeNull();
+ }
+
+ public void Dispose()
+ {
+ this._httpClient.Dispose();
+ this._messageHandlerStub.Dispose();
+ }
+
+ private sealed class HttpMessageHandlerStub : HttpMessageHandler
+ {
+ public HttpResponseMessage? ResponseToReturn { get; set; }
+ public string? RequestContent { get; private set; }
+ public Dictionary RequestHeaders { get; } = new();
+
+ protected override async Task SendAsync(
+ HttpRequestMessage request,
+ CancellationToken cancellationToken)
+ {
+ if (request.Content is not null)
+ {
+ this.RequestContent = await request.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
+ }
+
+ foreach (var header in request.Headers)
+ {
+ this.RequestHeaders[header.Key] = string.Join(",", header.Value);
+ }
+
+ return this.ResponseToReturn ?? new HttpResponseMessage(HttpStatusCode.OK);
+ }
+ }
+}
diff --git a/dotnet/src/Connectors/Connectors.VoyageAI.UnitTests/Services/VoyageAIMultimodalEmbeddingGenerationServiceTests.cs b/dotnet/src/Connectors/Connectors.VoyageAI.UnitTests/Services/VoyageAIMultimodalEmbeddingGenerationServiceTests.cs
new file mode 100644
index 000000000000..e8057b511f30
--- /dev/null
+++ b/dotnet/src/Connectors/Connectors.VoyageAI.UnitTests/Services/VoyageAIMultimodalEmbeddingGenerationServiceTests.cs
@@ -0,0 +1,358 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Http;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.SemanticKernel.Connectors.VoyageAI;
+using Xunit;
+
+namespace Microsoft.SemanticKernel.Connectors.VoyageAI.UnitTests.Services;
+
+///
+/// Unit tests for .
+///
+public sealed class VoyageAIMultimodalEmbeddingGenerationServiceTests : IDisposable
+{
+ private readonly HttpMessageHandlerStub _messageHandlerStub;
+ private readonly HttpClient _httpClient;
+
+ public VoyageAIMultimodalEmbeddingGenerationServiceTests()
+ {
+ this._messageHandlerStub = new HttpMessageHandlerStub();
+ this._httpClient = new HttpClient(this._messageHandlerStub);
+ }
+
+ [Fact]
+ public void Constructor_WithValidParameters_CreatesInstance()
+ {
+ // Arrange & Act
+ var service = new VoyageAIMultimodalEmbeddingGenerationService(
+ modelId: "voyage-multimodal-3",
+ apiKey: "test-api-key",
+ httpClient: this._httpClient
+ );
+
+ // Assert
+ service.Should().NotBeNull();
+ service.Attributes.Should().ContainKey("ModelId");
+ service.Attributes["ModelId"].Should().Be("voyage-multimodal-3");
+ }
+
+ [Fact]
+ public void Constructor_WithNullModelId_ThrowsArgumentNullException()
+ {
+ // Act & Assert
+ Assert.Throws(() =>
+ new VoyageAIMultimodalEmbeddingGenerationService(
+ modelId: null!,
+ apiKey: "test-api-key"
+ )
+ );
+ }
+
+ [Fact]
+ public void Constructor_WithNullApiKey_ThrowsArgumentNullException()
+ {
+ // Act & Assert
+ Assert.Throws(() =>
+ new VoyageAIMultimodalEmbeddingGenerationService(
+ modelId: "voyage-multimodal-3",
+ apiKey: null!
+ )
+ );
+ }
+
+ [Fact]
+ public async Task GenerateMultimodalEmbeddingsAsync_WithTextInputs_ReturnsEmbeddings()
+ {
+ // Arrange
+ var expectedEmbeddings = new List
+ {
+ new[] { 0.1f, 0.2f, 0.3f },
+ new[] { 0.4f, 0.5f, 0.6f }
+ };
+
+ var responseContent = JsonSerializer.Serialize(new
+ {
+ data = new[]
+ {
+ new { embedding = expectedEmbeddings[0], index = 0, @object = "embedding" },
+ new { embedding = expectedEmbeddings[1], index = 1, @object = "embedding" }
+ },
+ usage = new { total_tokens = 20 }
+ });
+
+ this._messageHandlerStub.ResponseToReturn = new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent(responseContent)
+ };
+
+ var service = new VoyageAIMultimodalEmbeddingGenerationService(
+ modelId: "voyage-multimodal-3",
+ apiKey: "test-api-key",
+ httpClient: this._httpClient
+ );
+
+ var inputs = new List