Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/phpaisdk/openai-compatible/llms.txt

Use this file to discover all available pages before exploring further.

The image generation workflow mirrors the chat completions pattern: build the request body with ImageRequestBuilder::build(), POST it to the provider’s /images/generations endpoint, then parse the response with ImageResponseParser::parse(). The adapter normalizes aspect ratio to size mapping, base64 output decoding, and provider metadata extraction so your image model class stays concise.

Building the request body

ImageRequestBuilder::build() accepts a model ID, provider name, an ImageRequest, and an optional $options array that lets you customize parameter names and behaviour for providers that deviate slightly from the standard OpenAI shape.
use AiSdk\OpenAICompatible\ImageRequestBuilder;
use AiSdk\Requests\ImageRequest;

$body = ImageRequestBuilder::build(
    modelId: 'dall-e-3',
    providerName: 'openai',
    request: new ImageRequest(
        prompt: 'A clean product photo on a white background',
        count: 1,
        size: '1024x1024',
    ),
);

// $body === [
//     'model'           => 'dall-e-3',
//     'prompt'          => 'A clean product photo on a white background',
//     'n'               => 1,
//     'size'            => '1024x1024',
//     'response_format' => 'b64_json',
// ]

The $options array

Every key in the $options array controls a specific part of the body-building logic. All keys are optional — sensible defaults are applied when a key is absent.
Option keyTypeDefaultDescription
aspectRatioParameterstring|nullnullWhen set, passes $request->aspectRatio under this parameter name (e.g. 'aspect_ratio' for xAI). Set to null to omit the aspect ratio entirely.
inferSizeFromAspectRatiobooltrueWhen true and $request->size is null, the adapter derives a size value from the aspect ratio using the built-in mapping table. Set to false when the provider uses a native aspect ratio parameter instead.
includeResponseFormatbooltrueWhen true, adds response_format: b64_json to the body so images are returned as base64 strings. Set to false for providers that always return base64 and reject this field.
sizeParameterstring|null'size'The parameter name to use for the image size. Set to null to omit the size from the request body entirely.
seedParameterstring|null'seed'The parameter name to use for the random seed. Set to null to omit the seed from the request body entirely.

Aspect ratio to size mapping

When inferSizeFromAspectRatio is true (the default) and no explicit size is provided on the request, the adapter maps the portable aspect ratio string to an OpenAI-compatible WxH size string:
Aspect ratioMapped size
1:11024x1024
3:21536x1024
16:91536x1024
2:31024x1536
9:161024x1536
$body = ImageRequestBuilder::build(
    'dall-e-3',
    'openai',
    new ImageRequest(
        prompt: 'A wide product scene',
        aspectRatio: '16:9',
    ),
);

// $body['size'] === '1536x1024'
Aspect ratios not in the mapping table (for example 21:9 or 4:3) throw an InvalidArgumentException. To use an unsupported ratio, either pass an explicit size on the request or pass the aspect ratio through the provider-specific raw escape hatch:
new ImageRequest(
    prompt: 'A cinematic panorama',
    providerOptions: ['myprovider' => ['raw' => ['size' => '1792x768']]],
);

Provider-specific variants

Providers that use a non-standard shape can be accommodated without writing a custom builder. The xAI image API, for example, accepts aspect_ratio directly and has no size parameter:
$body = ImageRequestBuilder::build(
    modelId: 'grok-imagine-image-quality',
    providerName: 'xai',
    request: new ImageRequest(
        prompt: 'A city skyline',
        count: 1,
        aspectRatio: '16:9',
        providerOptions: ['xai' => ['raw' => ['resolution' => '2k']]],
    ),
    options: [
        'aspectRatioParameter'    => 'aspect_ratio',   // pass aspect ratio natively
        'inferSizeFromAspectRatio' => false,            // don't convert to WxH
        'sizeParameter'           => null,             // omit 'size' field entirely
    ],
);

// $body === [
//     'model'           => 'grok-imagine-image-quality',
//     'prompt'          => 'A city skyline',
//     'n'               => 1,
//     'response_format' => 'b64_json',
//     'aspect_ratio'    => '16:9',
//     'resolution'      => '2k',
// ]
// Note: 'size' is not present in the body
The raw escape hatch on ImageRequest::providerOptions is merged last, overwriting any key the builder already set, which is how resolution appears in the body above.

Parsing the response

Pass the decoded JSON response to ImageResponseParser::parse(). It returns an ImageResponse containing one ImageData object per generated image, token usage, and provider metadata.
use AiSdk\OpenAICompatible\ImageResponseParser;

$payload = $this->runner()->postJson($url, $body, $headers, 'openai');
$response = ImageResponseParser::parse($payload, 'openai');

Accessing image data

// Access the first image
$image = $response->first();

echo $image->mimeType;  // e.g. 'image/png' or 'image/webp'
echo $image->width;     // e.g. 1024
echo $image->height;    // e.g. 1024

// Raw bytes decoded from b64_json
$bytes = $image->bytes(); // binary string

// Save to disk
file_put_contents('output.png', $bytes);

// Iterate all generated images
foreach ($response->images as $img) {
    echo $img->mimeType;
}

Usage and metadata

echo $response->usage->inputTokens;
echo $response->usage->outputTokens;
echo $response->usage->totalTokens;

$meta = $response->providerMetadata['openai'];
echo $meta['id'];      // e.g. 'img_123'
echo $meta['model'];   // e.g. 'dall-e-3'
echo $meta['size'];    // e.g. '1024x1024'
echo $meta['quality']; // e.g. 'standard'

Full example

use AiSdk\OpenAICompatible\ImageRequestBuilder;
use AiSdk\OpenAICompatible\ImageResponseParser;
use AiSdk\Requests\ImageRequest;

$request = new ImageRequest(
    prompt: 'A clean product photo',
    count: 2,
    size: '1024x1024',
    seed: 12345,
    providerOptions: ['openai' => ['raw' => ['background' => 'transparent']]],
);

$body = ImageRequestBuilder::build('dall-e-3', 'openai', $request);
// [
//     'model'           => 'dall-e-3',
//     'prompt'          => 'A clean product photo',
//     'n'               => 2,
//     'size'            => '1024x1024',
//     'seed'            => 12345,
//     'response_format' => 'b64_json',
//     'background'      => 'transparent',
// ]

$payload = $httpClient->postJson(
    'https://api.openai.com/v1/images/generations',
    $body,
    ['Authorization' => 'Bearer ' . $apiKey],
);

$response = ImageResponseParser::parse($payload, 'openai');

echo $response->first()->mimeType;  // 'image/png'
file_put_contents('image1.png', $response->first()->bytes());

echo $response->usage->totalTokens;
For building a complete provider that includes an image model, see Building a Provider.

Build docs developers (and LLMs) love