FAL Provider
FAL provides ultra-fast inference for image and video generation models. Known for speed optimization and support for latest models including FLUX, Stable Diffusion, and video generation.
Setup
Installation
import (
"github.com/digitallysavvy/go-ai/pkg/ai"
"github.com/digitallysavvy/go-ai/pkg/providers/fal"
)
Configuration
provider := fal.New(fal.Config{
APIKey: os.Getenv("FAL_API_KEY"),
Headers: map[string]string{"X-Custom": "value"},
})
model, err := provider.ImageModel("fal-ai/flux-pro")
fal.Config.APIKey falls back to the FAL_API_KEY environment variable,
then to FAL_KEY, if left empty. fal.Config.Headers are sent on every
request across image, video, speech, and transcription models.
Breaking change: the default base URL is now
https://fal.run(washttps://fal.run/fal-ai, which doubled the path for fully-qualified model IDs and broke default-config requests). Always pass fully-qualified model IDs likefal-ai/fast-sdxl, notfast-sdxl. The image and video default models arefal-ai/fast-sdxlandfal-ai/luma-ray.
Get API Key
export FAL_API_KEY=...
Available Models
Image Generation
| Model ID | Quality | Speed | Price | Best For |
|---|---|---|---|---|
| fal-ai/flux-pro | Excellent | Fast | $0.05/image | High quality |
| fal-ai/flux-schnell | Good | Very Fast | $0.003/image | Speed |
| fal-ai/stable-diffusion-xl | High | Fast | $0.03/image | General |
Video Generation
| Model ID | Quality | Speed | Price | Best For |
|---|---|---|---|---|
| fal-ai/stable-video-diffusion | Medium | Medium | $0.10/video | Video from image |
| fal-ai/runway-gen3 | High | Slow | $0.50/video | High quality video |
Provider-Specific Features
Ultra-Fast Inference
FAL optimizes for speed:
start := time.Now()
result, err := ai.GenerateImage(ctx, ai.GenerateImageOptions{
Model: model,
Prompt: "A sunset over mountains",
})
elapsed := time.Since(start)
fmt.Printf("Generated in %v\n", elapsed) // ~1-2 seconds
Video Generation
Create videos from text or images:
videoModel, err := provider.VideoModel("fal-ai/stable-video-diffusion")
// Generate from image
initImage, _ := os.ReadFile("frame.png")
fps := 10
result, err := ai.GenerateVideo(ctx, ai.GenerateVideoOptions{
Model: videoModel,
Prompt: ai.VideoPrompt{
Image: &ai.VideoPromptImage{Data: initImage},
},
FPS: &fps,
ProviderOptions: map[string]interface{}{
"fal": map[string]interface{}{
"frames": 25,
},
},
})
os.WriteFile("output.mp4", result.Video.Data, 0644)
Async Video And Webhooks
fal.VideoModel implements provider.VideoModelStarter /
VideoModelStatusChecker, so it also works with ai.ExperimentalStartVideo
/ ai.ExperimentalGetVideoStatus, and can complete via a webhook instead of
polling:
started, err := ai.ExperimentalStartVideo(ctx, ai.StartVideoOptions{
Model: videoModel,
Prompt: ai.VideoPrompt{Text: "A cat playing piano"},
WebhookURL: "https://example.com/fal-webhook",
})
Speech and Transcription
speechModel, err := provider.SpeechModel("fal-ai/minimax/speech-02-hd")
if err != nil {
log.Fatal(err)
}
result, err := ai.GenerateSpeech(ctx, ai.GenerateSpeechOptions{
Model: speechModel,
Text: "Hello from Fal.",
})
transcriptionModel, err := provider.TranscriptionModel("fal-ai/wizper")
if err != nil {
log.Fatal(err)
}
transcript, err := ai.Transcribe(ctx, ai.TranscribeOptions{
Model: transcriptionModel,
Audio: audioBytes,
})
Fal does not support reranking — provider.RerankingModel returns an error.
Examples
Basic Image Generation
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/digitallysavvy/go-ai/pkg/ai"
"github.com/digitallysavvy/go-ai/pkg/providers/fal"
)
func main() {
provider := fal.New(fal.Config{
APIKey: os.Getenv("FAL_KEY"),
})
model, err := provider.ImageModel("fal-ai/flux-schnell")
if err != nil {
log.Fatal(err)
}
start := time.Now()
result, err := ai.GenerateImage(context.Background(), ai.GenerateImageOptions{
Model: model,
Prompt: "A peaceful zen garden",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Generated in %v\n", time.Since(start))
os.WriteFile("garden.png", result.Images[0].Data, 0644)
}
Fast Batch Generation
prompts := []string{
"A red apple",
"A green apple",
"A yellow apple",
}
// Parallel generation
var wg sync.WaitGroup
for i, prompt := range prompts {
wg.Add(1)
go func(idx int, p string) {
defer wg.Done()
result, err := ai.GenerateImage(context.Background(), ai.GenerateImageOptions{
Model: model,
Prompt: p,
})
if err != nil {
return
}
filename := fmt.Sprintf("apple_%d.png", idx)
os.WriteFile(filename, result.Images[0].Data, 0644)
}(i, prompt)
}
wg.Wait()
Best Practices
-
Speed Optimization
- Use flux-schnell for rapid iteration
- Parallel requests for batches
- Leverage fast inference for real-time apps
-
Quality vs Speed
- Use schnell for previews
- Use pro for finals
- Balance based on use case
-
Cost Management
- Schnell is very cost-effective
- Cache results
- Use for high-volume applications
Rate Limits & Pricing
Check dashboard for current limits and pricing.
Workflow Serialization
Fal image, speech, and transcription models can cross a workflow boundary
with provider.SerializeImageModel / DeserializeImageModel,
provider.SerializeSpeechModel / DeserializeSpeechModel, and
provider.SerializeTranscriptionModel / DeserializeTranscriptionModel. See
Provider Serialization
for the mechanism; video models are not yet serializable.