cjmellor / fal-ai-laravel
A Laravel SDK for Fal.ai
Requires
- php: ^8.4
- hosmelq/sse-saloon: ^0.1.0
- illuminate/support: ^12.0
- saloonphp/saloon: ^3.0
Requires (Dev)
- driftingly/rector-laravel: ^2.0
- larastan/larastan: ^3.0
- laravel/pail: ^1.2
- laravel/pint: ^1.0
- nunomaduro/collision: ^8.0
- orchestra/testbench: ^10.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/phpstan: ^2.0
- rector/rector: ^2.0
This package is auto-updated.
Last update: 2025-09-03 10:59:13 UTC
README
Fal.ai Laravel Package
A Laravel package for integrating with the Fal.ai API, providing a fluent interface for AI model interactions with built-in webhook support.
โจ Features
- ๐ Fluent API - Chainable methods for easy request building
- ๐ Webhook Support - Secure webhook handling with ED25519 signature verification
- โก Queue & Sync Modes - Support for both immediate and queued requests
- ๐ก Real-time Streaming - Server-Sent Events (SSE) support for progressive AI model responses
- ๐ก๏ธ Security - Built-in webhook verification middleware
- ๐งช Well Tested - Comprehensive test suite
- ๐ Laravel Integration - Native Laravel middleware and service provider
- ๐ฃ๏ธ Built-in Routes - Pre-configured webhook endpoints ready to use
๐ฆ Installation
Install the package via Composer:
composer require fal-ai/laravel
Publish the configuration file:
php artisan vendor:publish --provider="FalAi\FalAiServiceProvider"
Add your Fal.ai API key to your .env
file:
FAL_API_KEY=your_fal_api_key_here
๐ Basic Usage
๐ฏ Simple Request
use FalAi\FalAi; $falAi = new FalAi(); $response = $falAi->model('fal-ai/flux/schnell') ->prompt('A beautiful sunset over mountains') ->imageSize('landscape_4_3') ->run();
โก Queue vs Sync Modes
Tip
Queue mode is the default and recommended for most use cases. It's perfect for complex generations that take time to process.
๐ Queue Mode (Default)
$response = $falAi->model('fal-ai/flux/dev') ->prompt('A futuristic cityscape') ->queue() // Explicit queue mode (optional, it's the default) ->run(); // Returns: ['request_id' => 'req_123...', 'status' => 'IN_QUEUE']
Use queue mode when:
- Generating high-quality images with many inference steps
- Processing multiple images in batch
- You don't need immediate results
- Working with complex prompts or large image sizes
โก Sync Mode
$response = $falAi->model('fal-ai/flux/schnell') ->prompt('A beautiful landscape') ->sync() // Switch to sync mode ->run(); // Returns the complete result immediately
Use sync mode when:
- You need immediate results
- Generating simple images with few inference steps
- Building interactive applications
- Testing and development
Warning
Sync mode may timeout for complex requests. Use queue mode for production applications.
๐ Webhook Support
๐ค Making Requests with Webhooks
When you add a webhook URL to your request, it automatically switches to queue mode:
$response = $falAi->model('fal-ai/flux/schnell') ->withWebhook('https://myapp.com/webhooks/fal') ->prompt('A beautiful sunset over mountains') ->imageSize('landscape_4_3') ->run(); // Returns: ['request_id' => 'req_123...', 'status' => 'IN_QUEUE']
๐ Webhook URL Requirements
- Must be a valid HTTPS URL
- Must be publicly accessible
- Should respond with 2xx status codes
๐ ๏ธ Setting Up Webhook Endpoints
You have two options for handling webhooks: use the built-in route or create your own custom endpoint.
๐ฏ Option 1: Built-in Webhook Route (Easiest)
The package includes a pre-configured webhook route at /webhooks/fal
that handles basic webhook processing:
// This route is automatically registered by the package // POST /webhooks/fal // Use it in your requests: $response = $falAi->model('fal-ai/flux/schnell') ->withWebhook(url('/webhooks/fal')) // Uses the built-in route ->prompt('Your prompt here') ->run();
Tip
The built-in route automatically verifies webhooks and returns appropriate responses. Perfect for getting started quickly!
๐ญ Option 2: Custom Webhook Endpoint (Recommended for Production)
use FalAi\Middleware\VerifyFalWebhook; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/webhooks/fal', function (Request $request) { $payload = $request->json()->all(); if ($payload['status'] === 'OK') { $images = $payload['data']['images']; // Process successful results foreach ($images as $image) { // Save image URL: $image['url'] } } elseif ($payload['status'] === 'ERROR') { $error = $payload['error']; // Handle error } return response()->json(['status' => 'processed']); })->middleware(VerifyFalWebhook::class);
For production applications, create a custom webhook endpoint with your own processing logic:
use FalAi\Middleware\VerifyFalWebhook; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/webhooks/fal-custom', function (Request $request) { $payload = $request->json()->all(); if ($payload['status'] === 'OK') { $images = $payload['data']['images']; // Process successful results foreach ($images as $image) { // Save image URL: $image['url'] // Custom processing logic here } } elseif ($payload['status'] === 'ERROR') { $error = $payload['error']; // Handle error with custom logic } return response()->json(['status' => 'processed']); })->middleware(VerifyFalWebhook::class);
๐ง Option 3: Manual Verification (Advanced)
For complete control over the verification process:
use FalAi\Services\WebhookVerifier; use FalAi\Exceptions\WebhookVerificationException; Route::post('/webhooks/fal-manual', function (Request $request) { $verifier = new WebhookVerifier(); try { $verifier->verify($request); // Webhook is valid, process payload $payload = $request->json()->all(); return response()->json(['status' => 'verified']); } catch (WebhookVerificationException $e) { return response()->json([ 'error' => 'Unauthorized', 'message' => 'Webhook verification failed' ], 401); } });
๐ Webhook Payload Examples
โ Successful Completion
{ "request_id": "req_123456789", "status": "OK", "data": { "images": [ { "url": "https://fal.media/files/generated-image.jpg", "width": 1024, "height": 768, "content_type": "image/jpeg" } ], "seed": 12345, "has_nsfw_concepts": [false], "prompt": "A beautiful sunset over mountains" } }
โ Error
{ "request_id": "req_123456789", "status": "ERROR", "error": { "type": "ValidationError", "message": "Invalid prompt provided" } }
๐ก Streaming
The Fal.ai Laravel package supports real-time streaming responses using Server-Sent Events (SSE). This is particularly useful for AI models that generate content progressively, such as text generation or image creation with intermediate steps.
๐ฏ Basic Streaming Usage
To use streaming, call the stream()
method instead of run()
or queue()
:
use Cjmellor\FalAi\Facades\FalAi; $streamResponse = FalAi::model('fal-ai/flux/schnell') ->prompt('A beautiful sunset over mountains') ->imageSize('landscape_4_3') ->stream(); $streamResponse->getResponse(); }
๐ Streaming vs Regular Requests
Feature | Regular Request | Streaming Request |
---|---|---|
Response Time | Wait for completion | Real-time updates |
User Experience | Loading spinner | Progress indicators |
Resource Usage | Lower | Slightly higher |
Complexity | Simple | Moderate |
Best For | Simple workflows | Interactive applications |
๐ Important Notes
- Streaming requests always use the
https://fal.run
endpoint regardless of configuration - Not all Fal.ai models support streaming - check the model documentation
- Streaming responses cannot be cached like regular responses
- Consider implementing proper error handling for network interruptions
- Use streaming for models that benefit from progressive updates (text generation, multi-step image creation)
โ๏ธ Configuration
Note
You can customise the package behaviour by publishing and modifying the configuration file.
The configuration file config/fal-ai.php
contains the following options:
return [ 'api_key' => env('FAL_API_KEY'), 'base_url' => 'https://queue.fal.run', 'default_model' => '', 'webhook' => [ // JWKS cache TTL in seconds (max 24 hours) 'jwks_cache_ttl' => env('FAL_WEBHOOK_JWKS_CACHE_TTL', 86400), // Timestamp tolerance in seconds (prevents replay attacks) 'timestamp_tolerance' => env('FAL_WEBHOOK_TIMESTAMP_TOLERANCE', 300), // HTTP timeout for JWKS fetching 'verification_timeout' => env('FAL_WEBHOOK_VERIFICATION_TIMEOUT', 10), ], ];
Environment Variables
# Required FAL_API_KEY=your_fal_api_key_here # Optional webhook configuration FAL_WEBHOOK_JWKS_CACHE_TTL=86400 FAL_WEBHOOK_TIMESTAMP_TOLERANCE=300 FAL_WEBHOOK_VERIFICATION_TIMEOUT=10
๐ Fluent API Methods
๐ ๏ธ Common Methods
$request = $falAi->model('fal-ai/flux/schnell') ->prompt('Your prompt here') // Set the text prompt ->imageSize('landscape_4_3') // Set image dimensions ->numImages(2) // Number of images to generate ->seed(12345) // Set random seed ->withWebhook('https://...') // Add webhook URL ->queue() // Use queue mode ->sync(); // Use sync mode
โ ๏ธ Error Handling
Important
Always implement proper error handling in production applications to gracefully handle API failures and webhook verification issues.
use FalAi\Exceptions\WebhookVerificationException; use InvalidArgumentException; try { $response = $falAi->model('fal-ai/flux/schnell') ->withWebhook('https://myapp.com/webhook') ->prompt('Test prompt') ->run(); if (!$response->successful()) { throw new Exception('API request failed: ' . $response->body()); } } catch (InvalidArgumentException $e) { // Invalid webhook URL or other validation errors echo "Validation error: " . $e->getMessage(); } catch (WebhookVerificationException $e) { // Webhook verification failed (in webhook endpoints) echo "Webhook error: " . $e->getMessage(); } catch (Exception $e) { // Other errors (network, API, etc.) echo "Error: " . $e->getMessage(); }
๐งช Testing
Run the test suite:
composer test
๐ Security
Caution
Webhook security is critical for protecting your application from malicious requests. Always use the provided verification mechanisms.
๐ Webhook Security
This package implements Fal.ai's webhook verification using:
- ED25519 signature verification using Fal.ai's public keys
- Timestamp validation to prevent replay attacks
- JWKS caching for performance
- Automatic header extraction and validation
๐ก Best Practices
Tip
Follow these security practices to ensure your webhook endpoints are secure:
- Always use HTTPS for webhook URLs
- Use the provided middleware for automatic verification
- Validate webhook payloads in your application logic
- Implement proper error handling and logging
- Monitor webhook endpoints for suspicious activity
- Use rate limiting on webhook routes
- Keep your API keys secure and rotate them regularly
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
๐ License
This package is open-sourced software licensed under the MIT license.
๐ฌ Support
For support, please open an issue on GitHub or contact the maintainers.