0xmrmasry / voyage-ai
PHP client for the Voyage AI API — text embeddings, multimodal embeddings, and reranking.
dev-main
2026-05-11 17:12 UTC
Requires
- php: >=8.1
- guzzlehttp/guzzle: ^7.0
- psr/http-client: ^1.0
Requires (Dev)
- mockery/mockery: ^1.6
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^10.0 || ^11.0
This package is auto-updated.
Last update: 2026-05-11 17:16:06 UTC
README
PHP client for the Voyage AI API — text embeddings, multimodal embeddings (text, images, video), and reranking.
Installation
composer require 0xmrmasry/voyage-ai
Configuration
Set your API key via environment variable:
VOYAGE_API_KEY=your-api-key
Or pass it directly:
$voyage = \VoyageAI\Voyage::client('your-api-key');
Usage
Text Embeddings
use VoyageAI\Voyage; use VoyageAI\Enums\{InputType, OutputDtype}; $voyage = Voyage::client(getenv('VOYAGE_API_KEY')); $response = $voyage->embeddings()->create( input: ['I like cats', 'I also like dogs'], model: 'voyage-4-large', ); foreach ($response->data as $result) { echo "Index: {$result->index}, Dims: " . count($result->embedding) . "\n"; } echo "Tokens used: {$response->usage->totalTokens}\n";
With Options
$response = $voyage->embeddings()->create( input: 'Represent this sentence for searching relevant passages', model: 'voyage-4-large', options: [ 'input_type' => InputType::Query, 'truncation' => true, 'output_dimension' => 256, 'output_dtype' => OutputDtype::Float, ], );
Quantized Embeddings (int8, uint8, binary, ubinary)
$response = $voyage->embeddings()->create( input: 'Test for quantization', model: 'voyage-4-large', options: [ 'output_dtype' => OutputDtype::Int8, ], ); // $response->data[0]->embedding is now array of ints (-128..127)
Reranking
$response = $voyage->reranking()->create( query: 'talk about rain', documents: [ 'sunny day at the beach', 'rainy day in the city', 'snowy mountain peak', ], model: 'rerank-2.5', ); // Results sorted by descending relevance foreach ($response->data as $result) { echo "Document {$result->index}: score {$result->relevanceScore}\n"; }
With Options
$response = $voyage->reranking()->create( query: 'best fruit', documents: ['apple', 'banana', 'car'], model: 'rerank-2.5-lite', options: [ 'top_k' => 2, 'return_documents' => true, 'truncation' => true, ], ); foreach ($response->data as $result) { echo "{$result->document}: {$result->relevanceScore}\n"; }
Multimodal Embeddings
use VoyageAI\Resources\{MultimodalInput, TextContent, ImageUrlContent, VideoUrlContent}; $response = $voyage->multimodal()->create( inputs: [ new MultimodalInput([ new TextContent('This is a banana.'), new ImageUrlContent('https://example.com/banana.jpg'), ]), ], model: 'voyage-multimodal-3.5', );
With Video
use VoyageAI\Resources\{MultimodalInput, TextContent, ImageUrlContent, VideoUrlContent}; $response = $voyage->multimodal()->create( inputs: [ new MultimodalInput([ new TextContent('A bunny running in a field.'), new ImageUrlContent('https://example.com/bunny.jpg'), new VideoUrlContent('https://example.com/bunny.mp4'), ]), ], model: 'voyage-multimodal-3.5', );
Base64 Images and Video
use VoyageAI\Resources\{MultimodalInput, TextContent, ImageBase64Content, VideoBase64Content}; $response = $voyage->multimodal()->create( inputs: [ new MultimodalInput([ new TextContent('A photo of a cat.'), new ImageBase64Content('data:image/jpeg;base64,/9j/4AAQSkZJRg...'), new VideoBase64Content('data:video/mp4;base64,AAAAIGZ0eXBpc29t...'), ]), ], model: 'voyage-multimodal-3.5', options: [ 'input_type' => InputType::Document, 'truncation' => true, ], );
Custom Base URL
$voyage = Voyage::client( apiKey: 'your-key', baseUrl: 'https://your-proxy.example.com/v1', );
Available Models
Text Embedding Models
| Model | Context Length | Embedding Dimension |
|---|---|---|
| voyage-4-large | 32,000 | 1024 (default), 256, 512, 2048 |
| voyage-4 | 32,000 | 1024 (default), 256, 512, 2048 |
| voyage-4-lite | 32,000 | 1024 (default), 256, 512, 2048 |
| voyage-3.5 | 32,000 | 1024 (default), 256, 512, 2048 |
| voyage-3.5-lite | 32,000 | 1024 (default), 256, 512, 2048 |
| voyage-3-large | 32,000 | 1024 (default), 256, 512, 2048 |
| voyage-3 | 32,000 | 1024 |
| voyage-3-lite | 32,000 | 512 |
| voyage-code-3.5 | 32,000 | 1024 (default), 256, 512, 2048 |
| voyage-code-3 | 32,000 | 1024 (default), 256, 512, 2048 |
| voyage-finance-2 | 32,000 | 1024 |
| voyage-multilingual-2 | 32,000 | 1024 |
| voyage-law-2 | 16,000 | 1024 |
| voyage-code-2 | 16,000 | 1536 |
Multimodal Embedding Models
| Model | Context Length | Embedding Dimension |
|---|---|---|
| voyage-multimodal-3.5 | 32,000 | 1024 |
| voyage-multimodal-3 | 32,000 | 1024 |
Reranking Models
| Model | Query Token Limit | Query + Document Token Limit |
|---|---|---|
| rerank-2.5 | 8,000 | 32,000 |
| rerank-2.5-lite | 8,000 | 32,000 |
| rerank-2 | 4,000 | 16,000 |
| rerank-2-lite | 2,000 | 8,000 |
| rerank-1 | 2,000 | 8,000 |
| rerank-lite-1 | 1,000 | 4,000 |
Error Handling
All API errors throw VoyageAI\Exceptions\VoyageException with an $httpStatusCode property:
try { $response = $voyage->embeddings()->create('Hello', 'invalid-model'); } catch (\VoyageAI\Exceptions\VoyageException $e) { echo "Error ({$e->httpStatusCode}): {$e->getMessage()}\n"; }
Requirements
- PHP 8.1+
- Guzzle 7 (installed automatically via Composer)
License
MIT