Fal
Installation
Install the gem and add to the application“s Gemfile by executing:
$ bundle add fal
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install fal
Usage
Configuration
Configure the client once at boot (e.g., in Rails an initializer) using Fal.configure.
“by Fal.configure do |config| config.api_key = “your-key” # Optional. Defaults to ENV[FAL_KEY] if not set. config.queue_base = “https://queue.fal.run” # Optional (default: https://queue.fal.run) config.sync_base = “https://fal.run” # Optional (default: https://fal.run) config.api_base = “https://api.fal.ai/v1” # Optional (default: https://api.fal.ai/v1) config.request_timeout = 120 # Optional (default: 120) end
“
Create a queued request
The Queue API is the recommended way to call models on fal. Provide a endpoint_id in “namespace/name” format and an input payload.
“by endpoint_id = “fal-ai/fast-sdxl”
request = Fal::Request.create!( endpoint_id: endpoint_id, input: { prompt: “a cat” } )
request.id # => request_id from fal request.status # => “IN_QUEUE” | “IN_PROGRESS” | “COMPLETED”
“
You can also specify a webhook URL to be notified when the request is finished.
“by request = Fal::Request.create!( endpoint_id: endpoint_id, input: { prompt: “a cat playing piano” }, webhook_url: “https://example.com/fal/webhook” )
“
Get request status (find and reload)
Fetch the current status by id:
“by status = Fal::Request.find_by!(id: request.id, endpoint_id: endpoint_id) status.in_queue? # => true/false status.in_progress? # => true/false status.completed? # => true/false
“
Reload an instance in-place, optionally including logs.
“by request.reload! # refreshes state request.reload!(logs: true) request.logs # => array of log entries (if provided by model and logs=1)
When status is COMPLETED, reload! will also fetch and set request.response
“
Status constants are available for direct comparisons:
“by Fal::Request::Status::IN_QUEUE Fal::Request::Status::IN_PROGRESS Fal::Request::Status::COMPLETED
“
Fetch the response payload after completion
Call reload! to populate request.response:
“by
poll until completed
until request.completed? request.reload! sleep 1 end
request.response # => model-specific response body
“
Cancel a request
Requests that are still in the queue can be cancelled:
“by request.cancel! # => { “status” => “CANCELLATION_REQUESTED” }
“
Webhooks
fal can POST a webhook to your server when a request completes. Use Fal::WebhookRequest to parse the incoming payload.
“by
rails controller example
class FalWebhooksController < ApplicationController skip_before_action :verify_authenticity_token
def create webhook = Fal::WebhookRequest.from_rack_request(request)
if webhook.success?
# webhook.response contains the model-specific payload
# webhook.logs, webhook.metrics may also be present
head :ok
else
Rails.logger.error("fal webhook error: #{webhook.error} detail=#{webhook.error_detail}")
head :ok
end
end end
“
Error handling
HTTP and API errors raise typed exceptions:
Fal::UnauthorizedError(401)Fal::ForbiddenError(403)Fal::NotFoundError(404)Fal::ServerError(other non-success)
Rescue them as needed:
“by begin Fal::Request.create!(endpoint_id: endpoint_id, input: { prompt: “hi” }) rescue Fal::UnauthorizedError # handle invalid/missing FAL_KEY end
“
Stream synchronous responses
Use stream! for SSE streaming from synchronous endpoints. It yields each chunk’s data Hash and returns a Fal::Request whose response contains the last chunk’s payload.
“by endpoint_id = “fal-ai/flux/dev”
last = Fal::Request.stream!(endpoint_id: endpoint_id, input: { prompt: “a cat” }) do |chunk| # chunk is a Hash, e.g. { images: [] } puts chunk end
last.completed? # => true/false last.response # => last streamed data hash (e.g., { “response” => { … } } or final payload)
“
Pricing
Use the Platform API to fetch per-endpoint pricing.
Find pricing for a single endpoint:
“by price = Fal::Price.find_by(endpoint_id: “fal-ai/flux/dev”) price.unit_price # => e.g., 0.025 price.unit # => e.g., “image” price.currency # => e.g., “USD”
“
Iterate through all prices (auto-paginates):
“by Fal::Price.each do |p| puts “#pp.endpoint_id => #pp.unit_price #pp.currency per #pp.unit” end
“
Collect all prices as an array:
“by prices = Fal::Price.all
“
Estimate cost
Compute a total cost estimate across endpoints using historical API price or unit price.
Unit price (uses billing units like images/videos):
“by estimate = Fal::PriceEstimate.create( estimate_type: Fal::PriceEstimate::EstimateType::UNIT_PRICE, endpoints: [# You can pass unit_quantity directly Fal::PriceEstimate::Endpoint.new(endpoint_id: fal-ai/flux/dev, unit_quantity: 50), # Or use call_quantity as a convenience alias for units Fal::PriceEstimate::Endpoint.new(endpoint_id: fal-ai/flux-pro, call_quantity: 25)] )
estimate.estimate_type # => “unit_price” estimate.total_cost # => e.g., 1.88 estimate.currency # => “USD”
“
Historical API price (uses calls per endpoint):
“by estimate = Fal::PriceEstimate.create( estimate_type: Fal::PriceEstimate::EstimateType::HISTORICAL_API_PRICE, endpoints: [Fal::PriceEstimate::Endpoint.new(endpoint_id: fal-ai/flux/dev, call_quantity: 100)] )
“
Models
List, search, and find models via the Models API.
Find a model by endpoint ID:
“by model = Fal::Model.find_by(endpoint_id: “fal-ai/flux/dev”) model.endpoint_id # => “fal-ai/flux/dev” model.display_name # => e.g., “FLUX.1 [dev]” model.category # => e.g., “text-to-image” model.status # => “active” | “deprecated” model.tags # => [fast, pro] model.model_url # => “https://fal.run/…” model.thumbnail_url # => “https://…”
“
Iterate or collect all models (auto-paginates):
“by Fal::Model.each do |m| puts m.endpoint_id end
all_models = Fal::Model.all
“
Search with filters:
“by results = Fal::Model.search(query: “text to image”, status: “active”)
“
Get a model’s price (memoized):
“by price = model.price price.unit_price # => e.g., 0.025
“
Run a request for a model (uses the model’s endpoint_id as endpoint_id):
“by request = model.run(input: { prompt: “a cat” })
“
Development
After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.
For local development, copy the example environment file and set your API key so bin/console can load it automatically:
“p .env.example .env echo ‘FAL_KEY=your_api_key_here’ » .env
“
The console uses dotenv to load .env, so Fal.configure will default to ENV["FAL_KEY"].