{"slug": "one-openai-compatible-endpoint-for-gpt-claude-gemini-and-deepseek-python-node", "title": "One OpenAI-compatible endpoint for GPT, Claude, Gemini and DeepSeek (Python + Node examples)", "summary": "The team behind Gisoo, an OpenAI-compatible LLM gateway, detailed how a single base URL and API key can route requests to 682 models across vendors including GPT, Claude, Gemini and DeepSeek using the unmodified official openai SDKs in Python and Node. The gateway exposes chat, responses, embeddings, images, audio and video endpoints in the OpenAI format, plus an Anthropic-compatible endpoint and a remote MCP server for tools like Claude Code, Cursor and Cline. The team said the service was built for developers in Iran who cannot pay OpenAI, Anthropic or Google directly, with credit billed in local currency and an Iran-optimized mirror.", "body_md": "Most LLM projects end up talking to more than one vendor: GPT for one job, Claude for another, Gemini or DeepSeek when cost matters. Each vendor has its own SDK, key, billing account and rate limits. An OpenAI-compatible gateway removes most of that: one base URL, one key, and the model is just a string.\n\nThis post shows the pattern with [Gisoo](https://gisoo.pro), the gateway we run (disclosure: I'm on the team). It exposes 680+ models behind the standard OpenAI API shape, so the official `openai` SDKs work unchanged. The same code works with any OpenAI-compatible gateway; only the base URL and key change.\n\n```\ncurl -s https://gisoo.pro/api/v1/models | jq '.data | length'\n# 682\n\ncurl -s https://gisoo.pro/api/v1/models \\\n  | jq -r '.data[] | select(.type==\"chat\") | .id' | head\n```\n\nEach entry has an `id`, an `owned_by` vendor and a `type` (`chat`, `image`, `audio`, `embedding`, `video`, `music`). Directly connected models use their own name (` gpt-5-mini`, `deepseek-flash`, `gemini-3.6-flash`); the rest carry an `openrouter/` prefix (`openrouter/anthropic/claude-sonnet-4.5`).\n\n``` python\nfrom openai import OpenAI\n\nclient = OpenAI(\n    base_url=\"https://gisoo.pro/api/v1\",\n    api_key=\"sk-gisoo-v1-...\",  # created in the Gisoo app\n)\n\nquestion = \"Explain idempotency keys in two sentences.\"\n\nfor model in [\"gpt-5-mini\", \"gemini-3.6-flash\", \"deepseek-flash\"]:\n    r = client.chat.completions.create(\n        model=model,\n        messages=[{\"role\": \"user\", \"content\": question}],\n    )\n    print(f\"--- {model}\\n{r.choices[0].message.content}\\n\")\n```\n\nSwitching vendor is a one-word change. That makes it cheap to A/B models on your own prompts instead of trusting benchmarks.\n\n``` python\nimport OpenAI from \"openai\";\n\nconst client = new OpenAI({\n  baseURL: \"https://gisoo.pro/api/v1\",\n  apiKey: process.env.GISOO_API_KEY,\n});\n\nconst stream = await client.chat.completions.create({\n  model: \"openrouter/anthropic/claude-sonnet-4.5\",\n  messages: [{ role: \"user\", content: \"Write a haiku about retries.\" }],\n  stream: true,\n});\n\nfor await (const chunk of stream) {\n  process.stdout.write(chunk.choices[0]?.delta?.content ?? \"\");\n}\n```\n\nStreaming is plain SSE in the OpenAI format, so existing UI code (Vercel AI SDK, LangChain, LiteLLM clients) keeps working.\n\nBecause every model sits behind the same endpoint, fallback is a loop, not three SDKs:\n\n``` python\nfrom openai import OpenAI, APIError\n\nclient = OpenAI(base_url=\"https://gisoo.pro/api/v1\", api_key=\"sk-gisoo-v1-...\")\n\ndef ask(messages, models=(\"deepseek-flash\", \"gemini-3.6-flash\", \"gpt-5-mini\")):\n    last = None\n    for m in models:\n        try:\n            return m, client.chat.completions.create(model=m, messages=messages, timeout=60)\n        except APIError as e:\n            last = e  # vendor busy or refused: try the next one\n    raise last\n\nmodel, r = ask([{\"role\": \"user\", \"content\": \"Summarise RFC 9110 in one line.\"}])\nprint(model, r.choices[0].message.content)\n```\n\nOrder the list cheapest-first and you only pay for the expensive model when the cheap one fails.\n\nThe same key covers the other OpenAI endpoints:\n\n| Task | Endpoint | \n|---|---|\n| Chat / tools / JSON output | `POST /chat/completions` ,`POST /responses` | \n| Embeddings | `POST /embeddings` | \n| Images | `POST /images/generations` | \n| Speech-to-text / text-to-speech | `POST /audio/transcriptions` ,`POST /audio/speech` | \n| Video | `POST /videos` | \n\nThere is also an Anthropic-compatible endpoint (`https://gisoo.pro/api`) for tools that only speak the Anthropic Messages API, and a remote MCP server (`https://gisoo.pro/api/mcp`) for Claude Code, Cursor and Cline.\n\nGisoo started for developers and teams in Iran, who can't pay OpenAI, Anthropic or Google directly: credit is paid in local currency, and there is an Iran-optimised mirror at `ir.gisoo.pro`. The API itself is the standard one, so the code above runs from anywhere.\n\nDocs (Persian, code is universal): [https://gisoo.pro/docs](https://gisoo.pro/docs). Questions and corrections are welcome in the comments.", "url": "https://wpnews.pro/news/one-openai-compatible-endpoint-for-gpt-claude-gemini-and-deepseek-python-node", "canonical_source": "https://dev.to/aliasghar_ramin_9faaf6ccc/one-openai-compatible-endpoint-for-gpt-claude-gemini-and-deepseek-python-node-examples-3l18", "published_at": "2026-10-24 19:32:48+00:00", "updated_at": "2026-10-24 19:42:43.849757+00:00", "lang": "en", "topics": ["ai-tools", "large-language-models", "ai-agents", "agent-protocols", "developer-tools"], "entities": ["Gisoo", "OpenAI", "Anthropic", "Google", "DeepSeek", "Claude Code", "Cursor", "Cline"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/one-openai-compatible-endpoint-for-gpt-claude-gemini-and-deepseek-python-node", "markdown": "https://wpnews.pro/news/one-openai-compatible-endpoint-for-gpt-claude-gemini-and-deepseek-python-node.md", "text": "https://wpnews.pro/news/one-openai-compatible-endpoint-for-gpt-claude-gemini-and-deepseek-python-node.txt", "jsonld": "https://wpnews.pro/news/one-openai-compatible-endpoint-for-gpt-claude-gemini-and-deepseek-python-node.jsonld"}}