{"skill":{"slug":"fal-ai-api","displayName":"fal.ai","summary":"fal.ai API integration with managed API key authentication. Run AI models for image generation, video generation, audio processing, and more. Use this skill...","description":"---\nname: fal-ai\ndescription: |\n  fal.ai API integration with managed API key authentication. Run AI models for image generation, video generation, audio processing, and more.\n  Use this skill when users want to generate images (Flux, SDXL), create videos (Minimax), upscale images, transcribe audio, or run other AI models on fal.ai.\n  For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).\ncompatibility: Requires network access and valid Maton API key\nmetadata:\n  author: maton\n  version: \"1.0\"\n  clawdbot:\n    emoji: 🧠\n    homepage: \"https://maton.ai\"\n    requires:\n      env:\n        - MATON_API_KEY\n---\n\n# fal.ai\n\nAccess the fal.ai queue API with managed API key authentication. Run 1000+ AI models including image generation (Flux, SDXL), video generation (Minimax), image upscaling, text-to-speech, and more.\n\n## Quick Start\n\n```bash\n# Generate an image with Flux Schnell\npython <<'EOF'\nimport urllib.request, os, json\n\ndata = json.dumps({\n    \"prompt\": \"a tiny cute cat\",\n    \"image_size\": \"square_hd\",\n    \"num_images\": 1\n}).encode()\n\nreq = urllib.request.Request('https://gateway.maton.ai/fal-ai/fal-ai/flux/schnell', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n## Base URL\n\n```\nhttps://gateway.maton.ai/fal-ai/{native-api-path}\n```\n\nThe gateway proxies requests to `queue.fal.run`. For model inference, paths follow the pattern:\n\n```\n/fal-ai/fal-ai/{model-id}\n/fal-ai/fal-ai/{model-id}/requests/{request_id}/status\n/fal-ai/fal-ai/{model-id}/requests/{request_id}\n/fal-ai/fal-ai/{model-id}/requests/{request_id}/cancel\n```\n\n## Authentication\n\nAll requests require the Maton API key in the Authorization header:\n\n```\nAuthorization: Bearer $MATON_API_KEY\n```\n\n**Environment Variable:** Set your API key as `MATON_API_KEY`:\n\n```bash\nexport MATON_API_KEY=\"YOUR_API_KEY\"\n```\n\n### Getting Your API Key\n\n1. Sign in or create an account at [maton.ai](https://maton.ai)\n2. Go to [maton.ai/settings](https://maton.ai/settings)\n3. Copy your API key\n\n## Connection Management\n\nManage your fal.ai API key connections at `https://ctrl.maton.ai`.\n\n### List Connections\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections?app=fal-ai&status=ACTIVE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n### Create Connection\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json\ndata = json.dumps({'app': 'fal-ai'}).encode()\nreq = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n**Response:**\n```json\n{\n  \"connection\": {\n    \"connection_id\": \"7355bd0b-8aaf-4c58-9122-a1e3d454414d\",\n    \"status\": \"PENDING\",\n    \"url\": \"https://connect.maton.ai/?session_token=...\",\n    \"app\": \"fal-ai\",\n    \"method\": \"API_KEY\"\n  }\n}\n```\n\nOpen the returned `url` in a browser to enter your fal.ai API key.\n\n### Get Connection\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n### Delete Connection\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n## API Reference\n\n### Queue API\n\nThe fal.ai queue API provides asynchronous model inference with status polling.\n\n#### Submit Request\n\nSubmit a request to run a model. Returns immediately with a request ID.\n\n```bash\nPOST /fal-ai/fal-ai/{model-id}\nContent-Type: application/json\n\n{\n  \"prompt\": \"model-specific parameters\",\n  ...\n}\n```\n\n**Response:**\n```json\n{\n  \"status\": \"IN_QUEUE\",\n  \"request_id\": \"3229f185-a99a-48c0-a292-e25bf9baaeba\",\n  \"response_url\": \"https://queue.fal.run/fal-ai/flux/requests/3229f185-a99a-48c0-a292-e25bf9baaeba\",\n  \"status_url\": \"https://queue.fal.run/fal-ai/flux/requests/3229f185-a99a-48c0-a292-e25bf9baaeba/status\",\n  \"cancel_url\": \"https://queue.fal.run/fal-ai/flux/requests/3229f185-a99a-48c0-a292-e25bf9baaeba/cancel\",\n  \"queue_position\": 0\n}\n```\n\n#### Check Status\n\nPoll for request status until completion.\n\n```bash\nGET /fal-ai/fal-ai/{model-id}/requests/{request_id}/status\n```\n\n**Response (IN_PROGRESS):**\n```json\n{\n  \"status\": \"IN_PROGRESS\",\n  \"request_id\": \"3229f185-a99a-48c0-a292-e25bf9baaeba\"\n}\n```\n\n**Response (COMPLETED):**\n```json\n{\n  \"status\": \"COMPLETED\",\n  \"request_id\": \"3229f185-a99a-48c0-a292-e25bf9baaeba\",\n  \"metrics\": {\n    \"inference_time\": 0.3334658145904541\n  }\n}\n```\n\n#### Get Result\n\nRetrieve the completed result.\n\n```bash\nGET /fal-ai/fal-ai/{model-id}/requests/{request_id}\n```\n\n**Response (image generation):**\n```json\n{\n  \"images\": [\n    {\n      \"url\": \"https://v3b.fal.media/files/...\",\n      \"width\": 1024,\n      \"height\": 1024,\n      \"content_type\": \"image/jpeg\"\n    }\n  ],\n  \"timings\": {\n    \"inference\": 0.1587670766748488\n  },\n  \"seed\": 761506470,\n  \"prompt\": \"a tiny cute cat\"\n}\n```\n\n#### Cancel Request\n\nCancel a queued or in-progress request.\n\n```bash\nPUT /fal-ai/fal-ai/{model-id}/requests/{request_id}/cancel\n```\n\n### Popular Models\n\n#### Flux Schnell (Fast Image Generation)\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json\n\ndata = json.dumps({\n    \"prompt\": \"a serene mountain landscape at sunset\",\n    \"image_size\": \"landscape_16_9\",\n    \"num_images\": 1,\n    \"num_inference_steps\": 4\n}).encode()\n\nreq = urllib.request.Request('https://gateway.maton.ai/fal-ai/fal-ai/flux/schnell', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n**Parameters:**\n- `prompt` (required): Text description of the image\n- `image_size`: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`\n- `num_images`: Number of images to generate (default: 1)\n- `num_inference_steps`: Number of steps (default: 4)\n- `seed`: Random seed for reproducibility\n\n#### Fast SDXL (Stable Diffusion XL)\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json\n\ndata = json.dumps({\n    \"prompt\": \"a futuristic city skyline at night\",\n    \"negative_prompt\": \"blurry, low quality\",\n    \"image_size\": \"landscape_16_9\",\n    \"num_images\": 1\n}).encode()\n\nreq = urllib.request.Request('https://gateway.maton.ai/fal-ai/fal-ai/fast-sdxl', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n**Parameters:**\n- `prompt` (required): Text description\n- `negative_prompt`: What to avoid in the image\n- `image_size`: Output dimensions\n- `num_images`: Number of images\n- `guidance_scale`: CFG scale (default: 7.5)\n- `num_inference_steps`: Number of steps\n\n#### Clarity Upscaler (Image Upscaling)\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json\n\ndata = json.dumps({\n    \"image_url\": \"https://example.com/image.jpg\",\n    \"scale\": 2\n}).encode()\n\nreq = urllib.request.Request('https://gateway.maton.ai/fal-ai/fal-ai/clarity-upscaler', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n**Parameters:**\n- `image_url` (required): URL of the image to upscale\n- `scale`: Upscale factor (2, 4)\n\n#### Minimax Video Generation\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json\n\ndata = json.dumps({\n    \"prompt\": \"A cat playing with a ball in slow motion\"\n}).encode()\n\nreq = urllib.request.Request('https://gateway.maton.ai/fal-ai/fal-ai/minimax/video-01', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n#### F5-TTS (Text-to-Speech)\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json\n\ndata = json.dumps({\n    \"gen_text\": \"Hello world, this is a test of fal ai text to speech.\"\n}).encode()\n\nreq = urllib.request.Request('https://gateway.maton.ai/fal-ai/fal-ai/f5-tts', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n### Request Status Values\n\n| Status | Description |\n|--------|-------------|\n| `IN_QUEUE` | Request received, waiting for runner |\n| `IN_PROGRESS` | Model is processing the request |\n| `COMPLETED` | Processing finished, result available |\n| `FAILED` | Processing failed (check error details) |\n\n### Request Headers\n\n| Header | Description |\n|--------|-------------|\n| `X-Fal-Request-Timeout` | Server-side deadline in seconds |\n| `X-Fal-Runner-Hint` | Session affinity for routing |\n| `X-Fal-Queue-Priority` | `normal` (default) or `low` |\n| `X-Fal-No-Retry` | Disable automatic retries |\n\n## Complete Workflow Example\n\n```bash\npython <<'EOF'\nimport urllib.request, os, json, time\n\napi_key = os.environ[\"MATON_API_KEY\"]\nbase_url = \"https://gateway.maton.ai/fal-ai\"\n\n# 1. Submit request\ndata = json.dumps({\n    \"prompt\": \"a beautiful sunset over the ocean\",\n    \"image_size\": \"landscape_16_9\",\n    \"num_images\": 1\n}).encode()\n\nreq = urllib.request.Request(f'{base_url}/fal-ai/flux/schnell', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {api_key}')\nreq.add_header('Content-Type', 'application/json')\nsubmit_response = json.load(urllib.request.urlopen(req))\nrequest_id = submit_response['request_id']\nprint(f\"Submitted: {request_id}\")\n\n# 2. Poll for completion\nwhile True:\n    req = urllib.request.Request(f'{base_url}/fal-ai/flux/requests/{request_id}/status')\n    req.add_header('Authorization', f'Bearer {api_key}')\n    status_response = json.load(urllib.request.urlopen(req))\n    print(f\"Status: {status_response['status']}\")\n\n    if status_response['status'] == 'COMPLETED':\n        break\n    elif status_response['status'] == 'FAILED':\n        print(\"Request failed\")\n        exit(1)\n\n    time.sleep(1)\n\n# 3. Get result\nreq = urllib.request.Request(f'{base_url}/fal-ai/flux/requests/{request_id}')\nreq.add_header('Authorization', f'Bearer {api_key}')\nresult = json.load(urllib.request.urlopen(req))\nprint(f\"Image URL: {result['images'][0]['url']}\")\nEOF\n```\n\n## Code Examples\n\n### JavaScript\n\n```javascript\nconst submitRequest = async () => {\n  // Submit\n  const submitRes = await fetch('https://gateway.maton.ai/fal-ai/fal-ai/flux/schnell', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'Authorization': `Bearer ${process.env.MATON_API_KEY}`\n    },\n    body: JSON.stringify({\n      prompt: 'a tiny cute cat',\n      image_size: 'square_hd',\n      num_images: 1\n    })\n  });\n  const { request_id } = await submitRes.json();\n\n  // Poll\n  let status = 'IN_QUEUE';\n  while (status !== 'COMPLETED') {\n    await new Promise(r => setTimeout(r, 1000));\n    const statusRes = await fetch(\n      `https://gateway.maton.ai/fal-ai/fal-ai/flux/requests/${request_id}/status`,\n      { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } }\n    );\n    status = (await statusRes.json()).status;\n  }\n\n  // Get result\n  const resultRes = await fetch(\n    `https://gateway.maton.ai/fal-ai/fal-ai/flux/requests/${request_id}`,\n    { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } }\n  );\n  return await resultRes.json();\n};\n```\n\n### Python (requests)\n\n```python\nimport os\nimport time\nimport requests\n\napi_key = os.environ[\"MATON_API_KEY\"]\nheaders = {\"Authorization\": f\"Bearer {api_key}\"}\n\n# Submit\nresponse = requests.post(\n    \"https://gateway.maton.ai/fal-ai/fal-ai/flux/schnell\",\n    headers=headers,\n    json={\"prompt\": \"a tiny cute cat\", \"image_size\": \"square_hd\", \"num_images\": 1}\n)\nrequest_id = response.json()[\"request_id\"]\n\n# Poll\nwhile True:\n    status = requests.get(\n        f\"https://gateway.maton.ai/fal-ai/fal-ai/flux/requests/{request_id}/status\",\n        headers=headers\n    ).json()[\"status\"]\n    if status == \"COMPLETED\":\n        break\n    time.sleep(1)\n\n# Get result\nresult = requests.get(\n    f\"https://gateway.maton.ai/fal-ai/fal-ai/flux/requests/{request_id}\",\n    headers=headers\n).json()\nprint(result[\"images\"][0][\"url\"])\n```\n\n## Notes\n\n- The gateway proxies to `queue.fal.run` for model inference\n- All model requests are queued - poll for status until completion\n- Model parameters vary by model - check fal.ai documentation for specifics\n- Image URLs from fal.ai CDN are temporary - download or store them\n- Video generation models may take longer to complete\n- Use webhooks for long-running tasks (add `?fal_webhook=URL` to submit request)\n- IMPORTANT: When piping curl output to `jq`, environment variables may not expand correctly. Use Python examples instead.\n\n## Error Handling\n\n| Status | Meaning |\n|--------|---------|\n| 400 | Missing fal-ai connection or invalid request |\n| 401 | Invalid or missing Maton API key |\n| 422 | Invalid model parameters |\n| 429 | Rate limited |\n| 4xx/5xx | Passthrough error from fal.ai API |\n\n### Troubleshooting\n\n1. **Check connection exists:**\n```bash\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections?app=fal-ai&status=ACTIVE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n```\n\n2. **Verify path format:** Paths must start with `/fal-ai/fal-ai/{model-id}`\n\n3. **Check model exists:** Some model IDs include organization prefix (e.g., `fal-ai/flux/schnell`)\n\n## Resources\n\n- [fal.ai Documentation](https://fal.ai/docs)\n- [Model Gallery](https://fal.ai/models)\n- [Queue API Reference](https://fal.ai/docs/model-endpoints/queue)\n- [Maton Community](https://discord.com/invite/dBfFAcefs2)\n- [Maton Support](mailto:support@maton.ai)\n","tags":{"latest":"1.0.0"},"stats":{"comments":0,"downloads":666,"installsAllTime":2,"installsCurrent":2,"stars":0,"versions":1},"createdAt":1773398925371,"updatedAt":1778491880948},"latestVersion":{"version":"1.0.0","createdAt":1773398925371,"changelog":"Initial release of fal-ai skill: integrate fal.ai queue API with managed authentication.\n\n- Enables image generation (Flux, SDXL), video creation, image upscaling, and audio processing using fal.ai models.\n- Uses managed Maton API key authentication for secure access.\n- Provides example Python scripts for connecting, submitting jobs, managing connections, and polling results.\n- Includes instructions for connection management through the Maton control portal.\n- Supports over 1,000 model endpoints accessible via Maton gateway proxy.\n- Designed for easy integration with clear authentication and usage documentation.","license":"MIT-0"},"metadata":{"setup":[{"key":"MATON_API_KEY","required":true}],"os":null,"systems":null},"owner":{"handle":"byungkyu","userId":"s174c3s2kc1ehqj1ytzntezj2983e2aj","displayName":"byungkyu","image":"https://avatars.githubusercontent.com/u/16563684?v=4"},"moderation":null}