Shared helper that routes ALL paid media generation (FAL image/video, ElevenLabs music) through the GooseWorks proxies so every call bills the Ads agent — never a provider SDK's default host. Host-swaps the FAL queue URLs, loads the agent token from ~/.gooseworks/credentials.json, and returns the result CDN URL. Every video-ad media capability imports this; templates never call a provider directly.
Scanned 9/4/2026
Install to Claude Code
npx -y skills add gooseworks-ai/goose-skills --skill media-proxy --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Media Proxy?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/gooseworks-ai-media-proxy)More formats (shields.io, HTML) on the badges page.
---
name: media-proxy
description: Shared helper that routes ALL paid media generation (FAL image/video, ElevenLabs music) through the GooseWorks proxies so every call bills the Ads agent — never a provider SDK's default host. Host-swaps the FAL queue URLs, loads the agent token from ~/.gooseworks/credentials.json, and returns the result CDN URL. Every video-ad media capability imports this; templates never call a provider directly.
status: active
---
# media-proxy
The foundation capability for paid media in the video-ad pipeline. It fixes the
auth-path conflict where engine scripts called FAL/ElevenLabs **directly** (billing
the wrong account): all paid calls now go through
`<api_base>/api/internal/{fal-proxy,elevenlabs-proxy}` with `?token=&agent_id=`, which
**bills the Ads agent**.
## Crash-resume (never lose / double-bill a paid render)
A FAL submit BILLS immediately, but the local backend can blip during a multi-minute
render. Two built-in protections (automatic for every capability that imports this):
- **Poll-through-outage** — `_fal_run`'s poll loop re-attaches to the same status/result
URL through `connection refused` / timeout blips instead of crashing.
- **Persist + resume** — each submit's `request_id` + poll URLs are written to
`~/.gooseworks/pending-fal-jobs/`. If the poller still dies, **re-attach instead of
re-firing** (re-firing double-bills): `resume_fal(request_id)` in Python, or the CLI:
```bash
resume.py --list # resumable (submitted, unfinished) jobs
resume.py --request-id <id> --out final.mp4 # poll to completion + download
```
`resume_fal` NEVER re-submits, so it can't double-charge.
## Use it
```python
from media_proxy import fal_generate, fal_generate_video, eleven_music, download
# image (nano-banana / gpt-image / etc.) — inputs must be PUBLIC urls
img = fal_generate("fal-ai/nano-banana/edit",
{"prompt": p, "image_urls": [product_url], "aspect_ratio": "9:16"})
# video i2v (kling / seedance / veo)
vid = fal_generate_video("fal-ai/kling-video/v2.1/standard/image-to-video",
{"prompt": p, "image_url": keyframe_url, "duration": "10"})
# music bed
eleven_music(prompt, 10500, "music.mp3", force_instrumental=True)
```
## Contracts (load-bearing)
- **Bills the Ads agent** — `?token=&agent_id=` from `~/.gooseworks/credentials.json`
(the CLI writes it; run `gooseworks login` if missing).
- **Host-swap the FAL queue URLs** — submit returns `status_url`/`response_url` on
`queue.fal.run`; the helper rewrites them to the proxy base (keeps the path). Never
poll `queue.fal.run` directly (401 + burns credits).
- **FAL inputs that are local files must be PUBLIC urls.** The orchestrator hosts a
local image/audio via the MCP `get_upload_url` → `get_download_url` presigned URL and
passes THAT url in. This module does not do MCP uploads (prefer the presigned url;
`fal-storage-proxy` may 404).
- **Only the final `*.fal.media` url is a real public URL** — everything else is behind
the proxy.
## Related
- Used by `create-image-fal`, `create-video-fal`, `create-music-elevenlabs`.
- The `goose-video` orchestrator hosts local inputs (MCP upload → presign) before calling these.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!