Official PHP SDK for Apiframe - The ultimate platform for AI image and video generation APIs.
- 🎨 Midjourney API (Original) - Generate, upscale, vary, blend, inpaint, face swap
- 🚀 Midjourney Pro API - Fast & Turbo modes, better stability
- ⚡ Flux AI - Fast and high-quality image generation
- 🎠Ideogram - Creative image generation with text rendering
- 🎬 Luma AI - Text and image to video generation
- 🎵 Suno AI - AI music generation
- 🎶 Udio AI - Advanced music creation
- 🎥 Runway ML - Gen-3 video generation
- 🎪 Kling AI - Video generation and manipulation
- 📸 AI Photos - Headshots, face swap, and photo enhancement
- 📤 Media Upload - Upload and manage media files
- PHP 7.4 or higher
- Composer
- An Apiframe API key (get one at apiframe.ai)
Install via Composer:
composer require apiframe/php-sdk
<?php
require 'vendor/autoload.php';
use Apiframe\Apiframe;
$client = new Apiframe([
'apiKey' => 'your_api_key_here'
]);
// Create an image generation task
$task = $client->midjourney->imagine([
'prompt' => 'a serene mountain landscape at sunset, photorealistic',
'aspect_ratio' => '16:9'
]);
echo "Task created: {$task['id']}\n";
// Wait for completion with progress updates
$result = $client->tasks->waitFor($task['id'], [
'onProgress' => function($progress) {
echo "Progress: {$progress}%\n";
}
]);
echo "Images ready: " . json_encode($result['image_urls']) . "\n";
$client = new Apiframe([
'apiKey' => 'your_api_key', // Required: Your Apiframe API key
'baseURL' => 'https://api.apiframe.ai', // Optional: Custom API endpoint
'timeout' => 300 // Optional: Request timeout in seconds (default: 300)
]);
The original Midjourney API with comprehensive features.
Endpoint: /imagine
, /imagine-video
, /reroll
, /variations
, /faceswap
, etc.
Docs: https://docs.apiframe.ai/api-endpoints
Create a new image generation task.
$task = $client->midjourney->imagine([
'prompt' => 'a serene mountain landscape',
'aspect_ratio' => '16:9', // Optional: '1:1', '16:9', '9:16', etc.
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Generate videos using a text prompt and an image URL.
$task = $client->midjourney->imagineVideo([
'prompt' => 'cinematic mountain landscape',
'image_url' => 'https://example.com/start-frame.jpg',
'motion' => 'high', // Optional: 'low' or 'high'
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Reroll to create new images from a previous Imagine task.
$task = $client->midjourney->reroll([
'parent_task_id' => 'original_task_id',
'prompt' => 'optional new prompt', // Optional: uses original prompt if not provided
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Create 4 new variations of one of the 4 generated images.
$task = $client->midjourney->variations([
'parent_task_id' => 'original_task_id',
'index' => '1', // '1', '2', '3', '4', or 'strong', 'subtle'
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Swap the face on a target image with the face on a provided image.
$task = $client->midjourney->faceSwap([
'target_image_url' => 'https://example.com/target.jpg',
'swap_image_url' => 'https://example.com/face.jpg',
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Upscale one of the 4 generated images to get a single image.
$task = $client->midjourney->upscale1x([
'parent_task_id' => 'original_task_id',
'index' => '1', // '1', '2', '3', or '4'
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Upscale with Subtle or Creative mode.
$task = $client->midjourney->upscaleAlt([
'parent_task_id' => 'upscale1x_task_id',
'type' => 'subtle', // 'subtle' or 'creative'
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Upscale any image to higher resolution (2x or 4x).
$task = $client->midjourney->upscaleHighres([
'parent_task_id' => 'task_id', // Or use image_url instead
'image_url' => 'https://example.com/image.jpg', // Or use parent_task_id instead
'type' => '2x', // '2x' or '4x'
'index' => '1', // Optional: '1', '2', '3', or '4'
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Redraw a selected area of an image (Vary Region).
$task = $client->midjourney->inpaint([
'parent_task_id' => 'upscale1x_task_id',
'mask' => 'base64_encoded_mask_image',
'prompt' => 'a red sports car',
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Enlarges an image's canvas beyond its original size.
$task = $client->midjourney->outpaint([
'parent_task_id' => 'upscale1x_task_id',
'zoom_ratio' => 1.5, // Can be 1.5, 2, or 1 for custom zoom
'aspect_ratio' => '1:1', // Optional
'prompt' => 'mountain landscape', // Optional
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Broadens the image canvas in a specific direction.
$task = $client->midjourney->pan([
'parent_task_id' => 'upscale1x_task_id',
'direction' => 'up', // 'up', 'down', 'left', or 'right'
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Writes four example prompts based on an image.
$task = $client->midjourney->describe([
'image_url' => 'https://example.com/image.jpg',
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Blend multiple images into one image (2-5 images).
$task = $client->midjourney->blend([
'image_urls' => [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg'
],
'dimension' => 'square', // Optional: 'square', 'portrait', or 'landscape'
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Analyzes your prompt and suggests optimizations.
$task = $client->midjourney->shorten([
'prompt' => 'a very beautiful and amazing sunset over the mountains with clouds',
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
Get the seed of a generated image.
$task = $client->midjourney->seed([
'task_id' => 'original_task_id',
'webhook_url' => 'https://your-domain.com/webhook', // Optional
'webhook_secret' => 'your-secret' // Optional
]);
The Pro Midjourney API with Fast & Turbo modes.
Endpoint: /pro/midjourney/*
Docs: https://docs.apiframe.ai/pro-midjourney-api/api-endpoints
Create a new image with Pro API.
$task = $client->midjourneyAlt->imagine([
'prompt' => 'a serene mountain landscape',
'mode' => 'turbo' // 'fast' or 'turbo'
]);
Upscale a specific image from a Pro API generation.
$task = $client->midjourneyAlt->upscale([
'parent_task_id' => 'parent_task_id',
'index' => '1', // '1', '2', '3', or '4'
'type' => 'subtle' // 'subtle' or 'creative'
]);
Create variations with strong/subtle control.
$task = $client->midjourneyAlt->vary([
'parent_task_id' => 'parent_task_id',
'index' => '1', // '1', '2', '3', or '4'
'type' => 'subtle' // 'subtle' or 'strong'
]);
// Generate with Flux (specify model)
$task = $client->flux->generate([
'model' => 'flux-pro', // 'flux-schnell', 'flux-pro', 'flux-dev', etc.
'prompt' => 'a futuristic cityscape',
'width' => 1024,
'height' => 1024,
'steps' => 50, // only for flux-pro and flux-dev
'guidance' => 7.5, // only for flux-pro and flux-dev
'seed' => 42,
'safety_tolerance' => 2
]);
// Convenience methods (automatically set model)
$task = $client->flux->generatePro([
'prompt' => 'a futuristic cityscape',
'width' => 1024,
'height' => 1024
]);
$task = $client->flux->generateDev([
'prompt' => 'a landscape',
'aspect_ratio' => '16:9'
]);
$task = $client->flux->generateSchnell([
'prompt' => 'quick sketch',
'width' => 512,
'height' => 512
]);
// Generate image
$task = $client->ideogram->generate([
'prompt' => 'a logo design',
'aspect_ratio' => 'ASPECT_1_1',
'style_type' => 'DESIGN',
'magic_prompt_option' => 'AUTO',
'seed' => 12345,
'resolution' => 'RESOLUTION_1024_1024'
]);
// Upscale image
$task = $client->ideogram->upscale([
'image_url' => 'https://...',
'prompt' => 'enhance this image',
'resemblance' => 80, // 1-100
'detail' => 50, // 1-100
'seed' => 12345
]);
// Describe image
$task = $client->ideogram->describe([
'image_url' => 'https://...'
]);
// Remix (image-to-image)
$task = $client->ideogram->remix([
'image_url' => 'https://...',
'prompt' => 'transform this image...',
'image_weight' => 70, // 1-100
'style_type' => 'REALISTIC'
]);
// Generate video from text prompt
$task = $client->luma->generate([
'prompt' => 'a serene beach with waves',
'aspect_ratio' => '16:9',
'loop' => false,
'enhance_prompt' => true
]);
// Generate video with start and end images
$task = $client->luma->generate([
'prompt' => 'a smooth transition',
'image_url' => 'https://start-image.jpg',
'end_image_url' => 'https://end-image.jpg',
'aspect_ratio' => '1:1'
]);
// Extend a previously generated video
$task = $client->luma->extend([
'parent_task_id' => 'previous_task_id',
'prompt' => 'continue the scene with more action'
]);
// Generate song with lyrics (creates TWO songs)
$task = $client->suno->generate([
'prompt' => 'an upbeat electronic track',
'lyrics' => 'Verse 1: Dancing through the night...',
'model' => 'chirp-v3-5',
'tags' => 'electronic, dance, upbeat',
'title' => 'Digital Dreams',
'make_instrumental' => false
]);
// Result will contain TWO songs with same lyrics
$result = $client->tasks->waitFor($task['id']);
// $result['songs'] will contain array of 2 songs
// Upload audio and turn it into extendable song
$uploadTask = $client->suno->upload([
'audio_url' => 'https://your-audio-url.mp3'
]);
$uploadResult = $client->tasks->waitFor($uploadTask['id']);
// Extend a song
$extendTask = $client->suno->extend([
'song_id' => $uploadResult['song_id'],
'continue_at' => 30,
'from_upload' => true,
'prompt' => 'continue with more energy'
]);
// Generate lyrics only
$lyricsTask = $client->suno->generateLyrics([
'prompt' => 'a song about summer adventures'
]);
$lyricsResult = $client->tasks->waitFor($lyricsTask['id']);
// Generate music (creates TWO songs with lyrics)
$task = $client->udio->generate([
'prompt' => 'a calm ambient soundtrack',
'lyrics' => 'Verse 1: Under the stars...',
'model' => 'udio32-v1.5',
'tags' => 'ambient, calm, instrumental',
'prompt_strength' => 0.8,
'clarity_strength' => 0.7,
'lyrics_strength' => 0.6,
'generation_quality' => 0.9,
'lyrics_placement_start' => 4,
'lyrics_placement_end' => 20,
'bypass_prompt_optimization' => false
]);
$result = $client->tasks->waitFor($task['id']);
// $result['songs'] will contain array of 2 songs
// Generate video
$task = $client->runway->generate([
'prompt' => 'a drone shot flying over mountains',
'generation_type' => 'text2video',
'model' => 'gen3',
'aspect_ratio' => '16:9',
'duration' => 10,
'flip' => false
]);
// Convenience method: Text to video
$task = $client->runway->textToVideo(
'a drone shot flying over mountains',
['model' => 'gen3a_turbo', 'duration' => 5]
);
// Convenience method: Image to video
$task = $client->runway->imageToVideo(
'https://image-url.jpg',
'add cinematic motion to this scene',
['duration' => 10]
);
// Convenience method: Video to video
$task = $client->runway->videoToVideo(
'https://video-url.mp4',
'transform this video with a sunset atmosphere',
['model' => 'gen3', 'duration' => 5]
);
// Generate video
$task = $client->kling->generate([
'prompt' => 'a time-lapse of a flower blooming',
'generation_type' => 'text2video',
'model' => 'kling-v1-5',
'mode' => 'pro',
'aspect_ratio' => '16:9',
'duration' => 10,
'cfg_scale' => 0.5
]);
// Convenience method: Text to video
$task = $client->kling->textToVideo(
'a time-lapse of a flower blooming',
['duration' => 10, 'aspect_ratio' => '16:9']
);
// Convenience method: Image to video
$task = $client->kling->imageToVideo(
'https://image-url.jpg',
'animate this image with smooth motion',
['mode' => 'pro', 'duration' => 5]
);
// Virtual Try On
$task = $client->kling->tryon([
'human_image_url' => 'https://person-image.jpg',
'cloth_image_url' => 'https://clothing-image.jpg',
'model' => 'kolors-virtual-try-on-v1-5'
]);
// Step 1: Upload and prepare 10-30 images for training
$uploadTask = $client->aiPhotos->upload([
'images' => ['base64_image_1', 'base64_image_2', '...'], // 10-30 images
'ethnicity' => 'white',
'gender' => 'male',
'age' => 30
]);
$uploadResult = $client->tasks->waitFor($uploadTask['id']);
echo "Images ready for training\n";
// Step 2: Train AI on the subject
$trainTask = $client->aiPhotos->train([
'training_images_id' => $uploadTask['id'],
'trigger_word' => 'TOKMSN' // Default trigger word
]);
$trainResult = $client->tasks->waitFor($trainTask['id']);
echo "Training finished, trigger_word: {$trainResult['trigger_word']}\n";
// Step 3: Generate photos using the trained model
$generateTask = $client->aiPhotos->generate([
'training_id' => $trainTask['id'],
'prompt' => 'a realistic portrait of TOKMSN black man wearing a suit',
'aspect_ratio' => '1:1',
'number_of_images' => '4',
'seed' => 12345
]);
$result = $client->tasks->waitFor($generateTask['id']);
echo "Generated photos: " . json_encode($result['image_urls']) . "\n";
// Upload image from file (max 2MB)
$upload = $client->media->upload([
'filename' => './path/to/image.jpg'
]);
echo "Uploaded: {$upload['imageURL']}\n";
// Upload audio from file (max 2MB, 60 seconds)
$audioUpload = $client->media->uploadAudio([
'filename' => './path/to/audio.mp3'
]);
echo "Uploaded audio: {$audioUpload['audioURL']}\n";
// Use uploaded media
$task = $client->midjourney->blend([
'image_urls' => [$upload['imageURL'], $another_url]
]);
General task management endpoints.
Get the result/status of a submitted task.
$task = $client->tasks->get($taskId);
echo "Status: {$task['status']}\n"; // 'pending', 'processing', 'completed', 'failed'
Get the results/statuses of multiple tasks (min 2, max 20).
$result = $client->tasks->getMany(['task_id_1', 'task_id_2', 'task_id_3']);
echo "Tasks: " . count($result['tasks']) . "\n";
Wait for a task to complete with progress tracking.
$result = $client->tasks->waitFor($taskId, [
'onProgress' => function($progress) {
echo "Progress: {$progress}%\n";
},
'interval' => 3000, // Polling interval in ms (default: 3000)
'timeout' => 300000 // Max wait time in ms (default: 300000 / 5 min)
]);
Get account details including credits, usage, plan, etc.
$account = $client->tasks->getAccountInfo();
echo "Email: {$account['email']}\n";
echo "Credits: {$account['credits']}\n";
echo "Total Images: {$account['total_images']}\n";
echo "Plan: {$account['plan']}\n";
use Apiframe\Exceptions\ApiframeException;
use Apiframe\Exceptions\AuthenticationException;
use Apiframe\Exceptions\RateLimitException;
use Apiframe\Exceptions\TimeoutException;
try {
$task = $client->midjourney->imagine(['prompt' => '...']);
$result = $client->tasks->waitFor($task['id']);
} catch (AuthenticationException $e) {
echo "Invalid API key\n";
} catch (RateLimitException $e) {
echo "Rate limit exceeded\n";
} catch (TimeoutException $e) {
echo "Request timed out\n";
} catch (ApiframeException $e) {
echo "API error: {$e->getMessage()}\n";
echo "Status: {$e->getStatus()}\n";
}
You can set your API key using an environment variable:
export APIFRAME_API_KEY=your_api_key_here
Then in your code:
$client = new Apiframe([
'apiKey' => getenv('APIFRAME_API_KEY')
]);
Check the /examples
directory for complete examples:
midjourney-example.php
- Midjourney Original API usagemidjourney-alt-example.php
- Midjourney Pro API usageflux-example.php
- Flux AI image generationluma-video-example.php
- Luma video generationsuno-music-example.php
- Suno music generationmedia-upload-example.php
- Media upload and usagecomprehensive-example.php
- All features demo
For detailed API documentation, visit docs.apiframe.ai
- Documentation: docs.apiframe.ai
- GitHub Issues: github.com/apiframe/apiframe-php-sdk/issues
MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.