Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
A TypeScript/Deno port of the FastAPI fal.ai proxy. Forwards every request to an upstream base URL, auto-rotates the fal.ai key, sanitizes OpenAI-style payloads, and supports both streaming and non-streaming responses.
Point your OpenAI-compatible client at the val's endpoint. The path is passed straight through to the upstream, so:
POST <endpoint>/openrouter/router/openai/v1/chat/completions
forwards to <UPSTREAM_URL>/openrouter/router/openai/v1/chat/completions.
GET / returns a health check.
| Key | What it is |
|---|---|
UPSTREAM_URL | Base URL to proxy to (e.g. https://fal.run) — secret |
FAL_KEY | Initial / fallback fal.ai key — secret |
KEY_ENDPOINT | URL returning { "apiKey": "..." } for rotation |
Edit them here:
- 👉 https://www.val.town/x/aisss/fal-proxy/environment-variables?key=UPSTREAM_URL
- 👉 https://www.val.town/x/aisss/fal-proxy/environment-variables?key=FAL_KEY
- 👉 https://www.val.town/x/aisss/fal-proxy/environment-variables?key=KEY_ENDPOINT
Val Town has no long-lived background process, so rotation happens on-demand (state persisted in blob storage) rather than via a background loop:
- A freshly fetched key is kept until it's actually used.
- Once used, it rotates after 7 minutes.
- A
402(out of balance) or a403"locked/insufficient/quota" response forces an immediate rotation and retry (up to 5 attempts).
Rendering mermaid diagram...
main.ts— HTTP handler; proxying, streaming, retries.keyManager.ts— key fetch/rotation + blob-persisted state.sanitize.ts— payload cleanup and dead-key detection.