1. fal Direct Generation

Use POST /threads/messages with operation=generate_image, generate_video, or generate_audio. Set the matching {kind}_model_provider to fal, {kind}_model_name to the endpoint ID, and {kind}_config to its settings. The operation describes the output, not the input.

Support is specific to each endpoint. A model’s presence in the library does not guarantee every input combination or every option available on fal. Python and JavaScript SDK version 1.5.20 adds audio-generation fields and typed fal discovery/quote helpers. Endpoint-specific image/video/audio configs accept the settings returned by discovery. Existing audio_file / audioFile fields are for chat transcription.

​
Discover and quote an endpoint

All paths below use the API base https://app.backboard.io/api and your Backboard X-API-Key.

  • GET /models/fal/catalog lists available catalog endpoints; use limit and offset to paginate.
  • GET /models/fal/catalog?available=false lists unavailable entries and their reasons.
  • GET /models/fal/tools lists hand-configured tools, including some outside the generic catalog.
  • GET /models/fal/tools/{endpoint_id} returns the selected tool’s inputs, prompt requirements, settings, and pricing inputs.
  • POST /models/fal/quote estimates a request without running generation. Supply tool, config, and any required prompt, seconds, or audio_seconds. The returned amount is before any app markup.

Endpoints with required structured inputs that Backboard cannot represent are unavailable. Examples include keyframe objects, bounding-box lists, LoRA lists, and audio-inpainting segments. Optional structured settings are not exposed either. Use only settings returned by the tool-detail endpoint.

​
Use the SDKs

import os
from backboard import BackboardClient

async with BackboardClient(api_key=os.environ["BACKBOARD_API_KEY"], timeout=600) as client:
    catalog = await client.list_fal_catalog(category="text-to-audio", limit=100)
    tool = await client.get_fal_tool("mirelo-ai/sfx2.0/text-to-audio")
    estimate = await client.quote_fal(tool.id, config={"num_samples": 1}, prompt="Gentle waves")
    print(estimate.usd)  # Decimal, before app markup; quoting does not generate media.
    result = await client.send_message(
        "Gentle waves", operation="generate_audio",
        audio_model_provider="fal", audio_model_name=tool.id,
        audio_config={"num_samples": 1},
    )
    print(result.generated_media)

For audio input, use input_audio="track.wav" in Python or input_audio: 'track.wav' in TypeScript. For mixed inputs, combine it with input_image, input_video, and/or input_references as the selected endpoint permits. The SDKs serialize the upload roles as multipart files, including when stream=True / stream: true.

list_fal_tools() / listFalTools() returns the hand-configured tools. list_fal_catalog() / listFalCatalog() paginates the larger catalog. Use available=False / available: false to inspect unsupported endpoints and their reasons.

​
Send media inputs

FieldAccepted filesAssignment
input_imageOne imageFirst image input for the selected tool.
input_videoOne videoSource video input.
input_audioOne audio fileFirst audio input.
Repeated input_referencesImages, audio, or videoRemaining inputs of each media type, in upload order.

The adapter fills the tool’s input slots in their listed order within each media type. For example, a tool with an image and a mask takes input_image first, then the mask as an image input_references upload. Filenames do not assign roles. Unused files and missing required inputs are rejected.

The fal path does not accept input_last_frame; use the ordered image slots returned by discovery for endpoints with multiple frame inputs. Supply additional videos through input_references when the tool accepts a video list. Discovery exposes min_items and max_items where known; audio lists without a tool-specific limit accept at most three files. The server’s overall attachment limit also applies (10 files by default). Tool-specific duration and reference limits also apply. Duration-priced video inputs must have readable MP4/MOV metadata. content is required only when the selected tool says its prompt is required; omit it for tools that take no prompt.

​
Extend a video with Seedance

Editing and extension require a source video. Reference mode also supports image-only inputs and multiple video/audio references. Each video/audio reference must be 1.8–30.2 seconds, with a combined maximum of 30.2 seconds per media type. The tool allows up to 10 video or audio references and 30 images, subject to the server’s overall attachment limit.

Duration settings are strings from "4" through "30", or "auto". Legacy numeric values are normalized to strings. For reference and extension, the "auto" quote budgets for the maximum 30-second output; choose an explicit duration for a tighter quote. Editing follows the source duration.

curl --fail-with-body https://app.backboard.io/api/threads/messages \
  -H "X-API-Key: $BACKBOARD_API_KEY" \
  -F 'operation=generate_video' \
  -F 'video_model_provider=fal' \
  -F 'video_model_name=bytedance/seedance-2.5/reference-to-video' \
  -F 'content=Continue the camera movement smoothly.' \
  -F 'video_config={"task":"extension","duration":"5","resolution":"720p"}' \
  -F 'input_video=@source.mp4;type=video/mp4'

​
Generate sound effects

curl --fail-with-body https://app.backboard.io/api/threads/messages \
  -H "X-API-Key: $BACKBOARD_API_KEY" \
  -F 'operation=generate_audio' \
  -F 'audio_model_provider=fal' \
  -F 'audio_model_name=mirelo-ai/sfx2.0/text-to-audio' \
  -F 'content=Gentle waves washing onto a sandy beach.' \
  -F 'audio_config={"num_samples":1}'

Read all returned generated_media entries: some endpoints produce multiple audio or video files. The examples above have schema and mocked-transport coverage; they are not evidence that every provider or input combination has passed live generation tests.

​
Server setup and catalog updates

Configure BACKBOARD_FAL_KEY on the server; FAL_KEY remains a fallback. Client applications use their Backboard API key, not the fal key.

After deploying the adapter, run python add_fal_models.py --dry-run to review catalog reconciliation and python add_fal_models.py to apply it. The importer includes hand-configured overrides and removes known unavailable fal entries while preserving unknown entries unless --replace is requested. No database schema migration is needed.

python update_fal_models.py refreshes the local catalog from fal’s public schemas and authenticated pricing metadata. It submits no generation jobs. Review generated catalog changes before deployment.