{"openapi":"3.1.0","info":{"title":"🐝 APIarium","description":"\n# 🐝 APIarium\n\n**OpenAI-compatible LLM API gateway** with multi-provider routing, encrypted configuration, and admin management.\n\n## ✨ Features\n\n- 🔄 **Multi-Model Routing** — Route requests to multiple LLM providers through a unified OpenAI-compatible API\n- 🔐 **Encrypted Config** — Sensitive values stored as AES-256-GCM encrypted blobs\n- 🛡️ **Cloudflare Turnstile** — Bot protection for admin endpoints\n- 🌐 **VPN Detection** — Free VPN/proxy detection via proxycheck.io\n- 🚫 **IP Blocking** — Built-in IP blocklist support\n- 💾 **GitHub Gist Storage** — API key persistence via encrypted GitHub Gists\n- 📊 **HuggingFace Dataset Logging** — Request/response logging to HF Datasets\n- ⚡ **Dynamic Providers** — Add/remove upstream providers at runtime\n\n## 🔑 Authentication\n\nAll proxy endpoints require a Bearer token:\n\n```\nAuthorization: Bearer <your-api-key>\n```\n\nAdmin endpoints require the master key.\n\n## 📚 Endpoints\n\n### Proxy (OpenAI-compatible)\n- `POST /v1/chat/completions` — Chat completions (streaming supported)\n- `POST /v1/completions` — Text completions\n- `GET /v1/models` — List available model aliases\n\n### Admin (Turnstile protected)\n- `GET /admin` — Dashboard\n- `GET /admin/keys` — API key management\n- `GET /admin/providers` — Provider management\n- `GET /admin/balance` — Balance monitoring\n- `POST /admin/verify-turnstile` — Turnstile token verification\n\n### Health\n- `GET /health` — Health check\n\n## 🔗 Links\n\n- **Space:** [huggingface.co/spaces/rnilkyway/APIarium](https://huggingface.co/spaces/rnilkyway/APIarium)\n- **Redoc:** [/redoc](/redoc)\n- **OpenAPI JSON:** [/openapi.json](/openapi.json)\n","version":"0.4.0"},"paths":{"/":{"get":{"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/models":{"get":{"summary":"List Models","description":"List all available models.\n\nBuilt-in aliases are listed by their alias id.\nDynamic provider models are listed as ``{prefix}/{custom_alias}`` if the\nprovider has a prefix configured; otherwise the raw model id is used.","operationId":"list_models_v1_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/dashboard":{"get":{"summary":"Dashboard Usage","description":"Usage dashboard with charts and API keys. Auth handled client-side via /admin/keys.","operationId":"dashboard_usage_v1_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/upstream-models":{"get":{"summary":"Upstream Models","description":"Show what models each upstream reports.","operationId":"upstream_models_v1_upstream_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/keys":{"get":{"summary":"Admin Keys Page","operationId":"admin_keys_page_admin_keys_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}},"post":{"summary":"Admin Create Key","description":"Create a new IP-bound API key. Requires MASTER_KEY auth.","operationId":"admin_create_key_admin_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminKeyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/stats":{"get":{"summary":"Admin Stats","description":"Return aggregated stats for dashboard charts. Requires MASTER_KEY auth.","operationId":"admin_stats_admin_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/models":{"get":{"summary":"Admin Models Page","operationId":"admin_models_page_admin_models_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/keys/{key_id}":{"delete":{"summary":"Admin Revoke Key","description":"Revoke an admin-created API key. Requires MASTER_KEY auth.","operationId":"admin_revoke_key_admin_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/providers":{"get":{"summary":"Admin Providers Page","operationId":"admin_providers_page_admin_providers_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/providers/preview":{"post":{"summary":"Admin Preview Provider","description":"Preview models available from an OpenAI-compatible provider (no persistence).","operationId":"admin_preview_provider_admin_providers_preview_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderImportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/providers/import":{"post":{"summary":"Admin Import Provider","description":"Import an OpenAI-compatible provider: fetch models, register routing, persist.","operationId":"admin_import_provider_admin_providers_import_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderImportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/providers/{provider_id}":{"patch":{"summary":"Admin Update Provider","description":"Update an existing dynamic provider: rename, change prefix, edit model selection/aliases, or replace keys.","operationId":"admin_update_provider_admin_providers__provider_id__patch","parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Admin Delete Provider","description":"Remove a dynamic provider and unregister its routes.","operationId":"admin_delete_provider_admin_providers__provider_id__delete","parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/balance/check/{provider_id}":{"get":{"summary":"Admin Balance Check","operationId":"admin_balance_check_admin_balance_check__provider_id__get","parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/balance/check-all":{"get":{"summary":"Admin Balance Check All","operationId":"admin_balance_check_all_admin_balance_check_all_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/providers/{provider_id}/keys":{"post":{"summary":"Admin Append Provider Keys","operationId":"admin_append_provider_keys_admin_providers__provider_id__keys_post","parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppendKeysRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/providers/{provider_id}/keys/{idx}":{"delete":{"summary":"Admin Remove Provider Key","operationId":"admin_remove_provider_key_admin_providers__provider_id__keys__idx__delete","parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}},{"name":"idx","in":"path","required":true,"schema":{"type":"integer","title":"Idx"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/verify-turnstile":{"post":{"summary":"Admin Verify Turnstile","operationId":"admin_verify_turnstile_admin_verify_turnstile_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnstileVerifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin":{"get":{"summary":"Admin Root","operationId":"admin_root_admin_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/login":{"get":{"summary":"Admin Login Page","operationId":"admin_login_page_admin_login_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/balance":{"get":{"summary":"Admin Balance Page","operationId":"admin_balance_page_admin_balance_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/settings":{"get":{"summary":"Admin Settings Page","operationId":"admin_settings_page_admin_settings_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/v1/images/generations":{"post":{"summary":"Generate Images","description":"OpenAI-compatible image generation.\n\nRoutes by model id:\n  • ``gpt-image-1`` / ``gpt-image-2``        → internal image backend\n  • ``gemini-3-image`` / ``gemini-3-flash-image`` / ``gemini-3.1-flash-image``\n    (optionally suffixed ``-pro``)            → Gemini Hub generar_imagen\n\nResponse is always OpenAI-shaped: ``{\"created\": …, \"data\": [{\"url\"|\"b64_json\", \"revised_prompt\"}]}``.","operationId":"generate_images_v1_images_generations_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/videos/generations":{"post":{"summary":"Generate Videos","description":"Video generation endpoint shaped like ``/v1/images/generations``.\n\nAccepts any of the Veo 3 model ids (``veo-3``, ``veo-3-fast``,\n``veo-3.1-fast``). Body fields:\n\n* ``prompt`` *(required)* — text description\n* ``size``           — ``\"16:9\"`` / ``\"9:16\"`` (or an OpenAI WxH string)\n* ``duration_seconds`` — ``\"4\"`` | ``\"6\"`` | ``\"8\"`` (default ``\"8\"``)\n* ``resolution``     — ``\"720p\"`` | ``\"1080p\"`` (default ``\"720p\"``)\n* ``image_url``      — seed frame for image-to-video (optional)\n\nResponse: ``{\"created\": …, \"data\": [{\"url\": \"…\"}]}``.","operationId":"generate_videos_v1_videos_generations_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/keys/me":{"get":{"summary":"Get My Key","description":"Return caller's IP and auto-generate a key if they don't have one.","operationId":"get_my_key_v1_keys_me_get","parameters":[{"name":"cf_token","in":"query","required":false,"schema":{"type":"string","title":"Cf Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/completions":{"post":{"summary":"Chat Completions","operationId":"chat_completions_v1_chat_completions_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}}},"components":{"schemas":{"AdminKeyRequest":{"properties":{"ip":{"type":"string","title":"Ip"},"label":{"type":"string","title":"Label","default":""}},"type":"object","required":["ip"],"title":"AdminKeyRequest"},"AppendKeysRequest":{"properties":{"keys":{"items":{},"type":"array","title":"Keys","default":[]}},"type":"object","title":"AppendKeysRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ProviderImportRequest":{"properties":{"name":{"type":"string","title":"Name"},"base_url":{"type":"string","title":"Base Url"},"keys":{"items":{},"type":"array","title":"Keys"},"prefix":{"type":"string","title":"Prefix","default":""},"model_aliases":{"additionalProperties":true,"type":"object","title":"Model Aliases","default":{}}},"type":"object","required":["name","base_url","keys"],"title":"ProviderImportRequest"},"ProviderUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"prefix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prefix"},"keys":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Keys"},"model_aliases":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Model Aliases"}},"type":"object","title":"ProviderUpdateRequest"},"TurnstileVerifyRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"TurnstileVerifyRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}