<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: chenxiao5580-cmd</title>
    <description>The latest articles on DEV Community by chenxiao5580-cmd (@chenxiao5580cmd).</description>
    <link>https://dev.to/chenxiao5580cmd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3987605%2Ff3aac0e1-6573-4803-9918-662302f1fa04.png</url>
      <title>DEV Community: chenxiao5580-cmd</title>
      <link>https://dev.to/chenxiao5580cmd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chenxiao5580cmd"/>
    <language>en</language>
    <item>
      <title>Cut your LLM bill by matching the model to the task — a real price comparison</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Tue, 07 Jul 2026 11:25:12 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/cut-your-llm-bill-by-matching-the-model-to-the-task-a-real-price-comparison-2j57</link>
      <guid>https://dev.to/chenxiao5580cmd/cut-your-llm-bill-by-matching-the-model-to-the-task-a-real-price-comparison-2j57</guid>
      <description>&lt;p&gt;With per-token pricing, the model you pick is the single biggest lever on your bill. Running a frontier model on a simple classification job can cost 10–90× more than a smaller model that handles it just as well. Here's a real price comparison and where the cheaper option is usually enough.&lt;/p&gt;

&lt;p&gt;All prices are USD per 1M tokens (input / output), list prices — the savings below come from &lt;strong&gt;model choice&lt;/strong&gt;, not a discount.&lt;/p&gt;

&lt;h2&gt;
  
  
  The price spread
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 4.8&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;td&gt;$25.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Sonnet 4.6&lt;/td&gt;
&lt;td&gt;$3.00&lt;/td&gt;
&lt;td&gt;$15.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Haiku 4.5&lt;/td&gt;
&lt;td&gt;$1.00&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4o&lt;/td&gt;
&lt;td&gt;$2.50&lt;/td&gt;
&lt;td&gt;$10.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4o mini&lt;/td&gt;
&lt;td&gt;$0.15&lt;/td&gt;
&lt;td&gt;$0.60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 2.5 Pro&lt;/td&gt;
&lt;td&gt;$1.25&lt;/td&gt;
&lt;td&gt;$10.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 2.5 Flash&lt;/td&gt;
&lt;td&gt;$0.30&lt;/td&gt;
&lt;td&gt;$2.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeepSeek V4 Flash&lt;/td&gt;
&lt;td&gt;$0.10&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Where a cheaper model is usually enough
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Simple tasks (classification, extraction, rewriting, batch jobs) → GPT-4o mini instead of GPT-4o&lt;/strong&gt;&lt;br&gt;
$0.15 vs $2.50 input, $0.60 vs $10 output — &lt;strong&gt;~94% cheaper&lt;/strong&gt;. For structured, well-defined tasks the mini model rarely loses quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everyday coding &amp;amp; general work → Claude Sonnet 4.6 instead of Opus 4.8&lt;/strong&gt;&lt;br&gt;
$3 vs $5 input, $15 vs $25 output — &lt;strong&gt;40% cheaper&lt;/strong&gt;. Save Opus for genuinely hard reasoning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;High-concurrency lightweight calls → Claude Haiku 4.5 instead of Sonnet 4.6&lt;/strong&gt;&lt;br&gt;
$1 vs $3 input, $5 vs $15 output — &lt;strong&gt;~67% cheaper&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long-document summarization &amp;amp; retrieval QA → Gemini 2.5 Flash instead of 2.5 Pro&lt;/strong&gt;&lt;br&gt;
$0.30 vs $1.25 input, $2.50 vs $10 output — &lt;strong&gt;~75% cheaper&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chinese-language work &amp;amp; high-volume throughput → DeepSeek V4 Flash instead of GPT-4o&lt;/strong&gt;&lt;br&gt;
$0.10 vs $2.50 input, $0.20 vs $10 output — &lt;strong&gt;96–98% cheaper&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch: routing by hand is tedious
&lt;/h2&gt;

&lt;p&gt;Knowing the cheaper model exists is one thing; actually picking it per request — and remembering to switch back for the hard prompts — is friction nobody keeps up with.&lt;/p&gt;

&lt;p&gt;That's the problem &lt;strong&gt;Modelis&lt;/strong&gt; is built around: it's an OpenAI-compatible gateway that &lt;strong&gt;classifies each request by difficulty and routes it to a fitted model automatically&lt;/strong&gt;, then bills a flat per-call price so your cost stays predictable regardless of which model answered. Every response carries an &lt;code&gt;X-Modelis-Routed-Model&lt;/code&gt; header so you can see exactly which model handled it.&lt;/p&gt;

&lt;p&gt;Free tier — &lt;a href="https://modelishub.com/" rel="noopener noreferrer"&gt;get a key&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
      <category>programming</category>
    </item>
    <item>
      <title>Use GPT, Claude, and Gemini with the OpenAI SDK — one base_url, any language</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Sat, 04 Jul 2026 01:35:07 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/use-gpt-claude-and-gemini-with-the-openai-sdk-one-baseurl-any-language-7kb</link>
      <guid>https://dev.to/chenxiao5580cmd/use-gpt-claude-and-gemini-with-the-openai-sdk-one-baseurl-any-language-7kb</guid>
      <description>&lt;p&gt;If you're juggling separate SDKs and API keys for OpenAI, Anthropic, and Google, here's a simpler setup: point the &lt;strong&gt;OpenAI SDK&lt;/strong&gt; at an OpenAI-compatible gateway and call GPT, Claude, and Gemini through &lt;strong&gt;one &lt;code&gt;base_url&lt;/code&gt; and one key&lt;/strong&gt; — at a flat, predictable per-call price instead of three separate per-token bills.&lt;/p&gt;

&lt;p&gt;Here's the exact change in five common stacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python (OpenAI SDK)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://modelishub.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_MODELIS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rest of your code stays the same — only &lt;code&gt;base_url&lt;/code&gt; and &lt;code&gt;api_key&lt;/code&gt; change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node.js (openai v4)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;OpenAI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://modelishub.com/v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MODELIS_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  curl (works in any language)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://modelishub.com/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_MODELIS_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hello"}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same pattern works in Go, Java, PHP, Rust — anywhere you can make an HTTP request.&lt;/p&gt;

&lt;h2&gt;
  
  
  LangChain
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://modelishub.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_MODELIS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Switching between GPT, Claude, and Gemini
&lt;/h2&gt;

&lt;p&gt;To use a different model, just change the &lt;code&gt;model&lt;/code&gt; id — &lt;code&gt;claude-sonnet-4-6&lt;/code&gt;, &lt;code&gt;gemini-2.5-flash&lt;/code&gt;, and so on. Same endpoint, same key. Fetch the full list any time with &lt;code&gt;GET /v1/models&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-sonnet-4-6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;# or gemini-2.5-flash, gpt-4o, ...
&lt;/span&gt;    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;This runs on &lt;strong&gt;Modelis&lt;/strong&gt;, an OpenAI-compatible LLM gateway that auto-routes each request to a model fitted to the task and bills a &lt;strong&gt;flat per-call price&lt;/strong&gt; (not per-token), so your bill stays predictable regardless of which model answered. Free tier to try it — &lt;a href="https://modelishub.com/" rel="noopener noreferrer"&gt;details + free key&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>python</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Call GPT, Claude, and Gemini from one API key — a 3-step setup</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Wed, 01 Jul 2026 01:35:04 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/call-gpt-claude-and-gemini-from-one-api-key-a-3-step-setup-pc5</link>
      <guid>https://dev.to/chenxiao5580cmd/call-gpt-claude-and-gemini-from-one-api-key-a-3-step-setup-pc5</guid>
      <description>&lt;p&gt;If you want to try GPT, Claude, and Gemini without signing up for three separate platforms and juggling three billing dashboards, here's a 3-step setup using an OpenAI-compatible gateway.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create an account
&lt;/h2&gt;

&lt;p&gt;Go to &lt;a href="https://modelishub.com/" rel="noopener noreferrer"&gt;modelishub.com&lt;/a&gt;, sign up with a username/email + password, and pass the quick human check. You're logged into the console immediately — no approval wait.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create an API key
&lt;/h2&gt;

&lt;p&gt;In the console, open &lt;strong&gt;API Tokens&lt;/strong&gt; → &lt;strong&gt;New Token&lt;/strong&gt; and give it a name (e.g. &lt;code&gt;my-app&lt;/code&gt;). Optionally set a quota cap so you can control spend per project. Copy the key (it starts with &lt;code&gt;sk-&lt;/code&gt;) — that's what you call the API with. Keep it private; usage and quota are tracked per key.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Make your first call
&lt;/h2&gt;

&lt;p&gt;Point any OpenAI-compatible tool at &lt;code&gt;https://modelishub.com/v1&lt;/code&gt; with that key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://modelishub.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To switch models, just change the &lt;code&gt;model&lt;/code&gt; id — &lt;code&gt;claude-sonnet-4-6&lt;/code&gt;, &lt;code&gt;gemini-2.5-flash&lt;/code&gt;, and so on. Same endpoint, same key. Fetch the full list any time with &lt;code&gt;GET /v1/models&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking your usage
&lt;/h2&gt;

&lt;p&gt;The console &lt;strong&gt;Dashboard&lt;/strong&gt; shows overall consumption; the &lt;strong&gt;Logs&lt;/strong&gt; view shows every call (model, tokens used, quota spent, success or error), so you can pinpoint a wrong model id or a quota issue in seconds.&lt;/p&gt;




&lt;p&gt;This runs on &lt;strong&gt;Modelis&lt;/strong&gt;, an OpenAI-compatible LLM gateway that auto-routes each request to a fitted model and bills a flat per-call price (not per-token). Free tier to try it — &lt;a href="https://modelishub.com/" rel="noopener noreferrer"&gt;get a key&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A flat per-call endpoint for summarize / classify / extract in your n8n and Make automations</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Sun, 28 Jun 2026 13:00:34 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/a-flat-per-call-endpoint-for-summarize-classify-extract-in-your-n8n-and-make-automations-548h</link>
      <guid>https://dev.to/chenxiao5580cmd/a-flat-per-call-endpoint-for-summarize-classify-extract-in-your-n8n-and-make-automations-548h</guid>
      <description>&lt;p&gt;If you run automations that summarize, classify, or pull fields out of text at volume, the LLM step is where per-token pricing turns budgeting into a guessing game: one batch of long inputs and the bill spikes. For these &lt;strong&gt;bounded-output jobs&lt;/strong&gt;, a flat price per call fits better than a per-token frontier model. Here is how I wire it into n8n / Make, and when not to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why flat-per-call fits automation
&lt;/h2&gt;

&lt;p&gt;Automation runs are repetitive and high-volume, and the outputs are short by nature: a summary, a label, a few extracted fields. I route them through &lt;a href="https://rapidapi.com/chenxiao5580/api/modelis-auto-chat" rel="noopener noreferrer"&gt;Modelis&lt;/a&gt;, an OpenAI-compatible gateway that auto-routes each request to a fitting model and charges a &lt;strong&gt;flat price per call&lt;/strong&gt; with output capped at ~1024 tokens. Because the output is bounded, each run costs the same and your monthly total stays predictable no matter the input size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wiring it into n8n / Make
&lt;/h2&gt;

&lt;p&gt;It is a standard OpenAI-compatible &lt;code&gt;POST /v1/chat/completions&lt;/code&gt;. Use an HTTP Request node:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Method: &lt;code&gt;POST&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;URL: &lt;code&gt;https://modelis-auto-chat.p.rapidapi.com/v1/chat/completions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Headers: &lt;code&gt;x-rapidapi-host: modelis-auto-chat.p.rapidapi.com&lt;/code&gt;, &lt;code&gt;x-rapidapi-key: YOUR_KEY&lt;/code&gt;, &lt;code&gt;content-type: application/json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Body:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"modelis-auto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Label sentiment (positive/negative/neutral): {{ $json.text }}"&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The curl equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://modelis-auto-chat.p.rapidapi.com/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-rapidapi-host: modelis-auto-chat.p.rapidapi.com'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-rapidapi-key: YOUR_KEY'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"modelis-auto","messages":[{"role":"user","content":"Summarize in 2 sentences: ..."}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you would rather use a built-in OpenAI node that expects an &lt;code&gt;Authorization: Bearer&lt;/code&gt; key and a custom base URL, run the tiny open-source adapter next to your workflow runner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx modelis-openai      &lt;span class="c"&gt;# local proxy on 127.0.0.1:8787, MIT, ~120 lines&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then point the node at &lt;code&gt;http://127.0.0.1:8787/v1&lt;/code&gt; with model &lt;code&gt;modelis-auto&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompts that fit (short outputs)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Summarize:&lt;/strong&gt; &lt;code&gt;Summarize in 2 sentences: ...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Classify:&lt;/strong&gt; &lt;code&gt;Label sentiment (positive/negative/neutral): ...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extract:&lt;/strong&gt; &lt;code&gt;Return JSON with {name, email, company} from: ...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All produce short outputs, so the flat per-call price keeps high-volume runs cheap to reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  When NOT to use it
&lt;/h2&gt;

&lt;p&gt;Long-form generation (articles, whole files, large code) will hit the ~1024-token cap and get truncated. Keep a high-output model for those. Use this for the short, structured outputs that automations actually need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Free tier: &lt;a href="https://rapidapi.com/chenxiao5580/api/modelis-auto-chat" rel="noopener noreferrer"&gt;https://rapidapi.com/chenxiao5580/api/modelis-auto-chat&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Adapter source (read it before you run it): &lt;a href="https://github.com/modelishub/modelis-openai" rel="noopener noreferrer"&gt;https://github.com/modelishub/modelis-openai&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built the adapter. I am most curious which extraction and classification tasks the routing handles well versus badly. If you point an automation at it, I would love to hear how it routed.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>ai</category>
      <category>llm</category>
      <category>api</category>
    </item>
    <item>
      <title>When a flat-price, capped-output LLM API is exactly right (and when it isn't)</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Fri, 26 Jun 2026 01:59:53 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/when-a-flat-price-capped-output-llm-api-is-exactly-right-and-when-it-isnt-5g</link>
      <guid>https://dev.to/chenxiao5580cmd/when-a-flat-price-capped-output-llm-api-is-exactly-right-and-when-it-isnt-5g</guid>
      <description>&lt;p&gt;Per-token pricing makes LLM bills hard to predict: a chatty model on a verbose prompt can cost several times what you budgeted, and that variance compounds at volume. For one whole class of work, though — &lt;strong&gt;bounded-output tasks&lt;/strong&gt; — a flat price per call with a capped output is a better fit than the usual per-token frontier model. Here's the trade-off, honestly, and how I wire it up.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea: flat per call, output bounded
&lt;/h2&gt;

&lt;p&gt;I've been routing this kind of work through &lt;a href="https://rapidapi.com/chenxiao5580/api/modelis-auto-chat" rel="noopener noreferrer"&gt;Modelis&lt;/a&gt;, an OpenAI-compatible gateway that auto-routes each request to a fitting model (GPT / Claude / Gemini) and charges a &lt;strong&gt;flat price per call&lt;/strong&gt;. Output is capped at ~1024 tokens.&lt;/p&gt;

&lt;p&gt;That cap sounds like a pure limitation — and for some work it is (see the end). But for bounded-output tasks, the capped output is exactly &lt;em&gt;why&lt;/em&gt; the price can stay flat and predictable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it shines (bounded output is a feature)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chat / support bots&lt;/strong&gt; — replies are short, so cost per message is fixed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Summarization&lt;/strong&gt; — summaries are short by definition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Classification / tagging / extraction&lt;/strong&gt; — outputs are tiny.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAG answer generation&lt;/strong&gt; — you want concise, source-grounded answers, not essays.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For all of these, a capped flat price means high volume stays cheap and your monthly bill is predictable regardless of input size.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;It's a standard OpenAI-compatible &lt;code&gt;POST /v1/chat/completions&lt;/code&gt;. Plain HTTP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://modelis-auto-chat.p.rapidapi.com/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-rapidapi-host: modelis-auto-chat.p.rapidapi.com'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-rapidapi-key: YOUR_KEY'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"modelis-auto","messages":[{"role":"user","content":"Summarize this in one line: ..."}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your tool or SDK expects the standard &lt;code&gt;Authorization: Bearer&lt;/code&gt; header, there's a tiny open-source adapter that bridges it (MIT, ~120 lines, runs locally):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx modelis-openai      &lt;span class="c"&gt;# local proxy on 127.0.0.1:8787&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Point any OpenAI client at it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://127.0.0.1:8787/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;modelis-auto&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Classify sentiment: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;shipping was slow but product is great&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, in &lt;a href="https://continue.dev" rel="noopener noreferrer"&gt;Continue&lt;/a&gt; (&lt;code&gt;~/.continue/config.yaml&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Modelis&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;modelis-auto&lt;/span&gt;
    &lt;span class="na"&gt;apiBase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:8787/v1&lt;/span&gt;
    &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;YOUR_KEY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When NOT to use it (being honest)
&lt;/h2&gt;

&lt;p&gt;Do &lt;strong&gt;not&lt;/strong&gt; point this at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generating whole files or large multi-file diffs,&lt;/li&gt;
&lt;li&gt;autonomous coding agents (large refactors in Aider, or Cline / Roo).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ~1024-token output cap will truncate those. For code generation, keep a high-output model configured and switch to it. Use the flat-price endpoint for the bounded-output jobs above, where short output is what you want anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Free tier: &lt;a href="https://rapidapi.com/chenxiao5580/api/modelis-auto-chat" rel="noopener noreferrer"&gt;https://rapidapi.com/chenxiao5580/api/modelis-auto-chat&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Adapter source (read it before you run it): &lt;a href="https://github.com/modelishub/modelis-openai" rel="noopener noreferrer"&gt;https://github.com/modelishub/modelis-openai&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built the adapter. I'm most curious which bounded-output tasks the routing handles well versus badly — if you try it for summaries, classification, or RAG answers, I'd love to hear how it routed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>api</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Use a flat-priced, auto-routing LLM API in Aider or Cline — one npx command</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Tue, 23 Jun 2026 04:03:09 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/use-a-flat-priced-auto-routing-llm-api-in-aider-or-cline-one-npx-command-3k5l</link>
      <guid>https://dev.to/chenxiao5580cmd/use-a-flat-priced-auto-routing-llm-api-in-aider-or-cline-one-npx-command-3k5l</guid>
      <description>&lt;p&gt;Coding assistants like &lt;strong&gt;Aider&lt;/strong&gt;, &lt;strong&gt;Cline&lt;/strong&gt;, and &lt;strong&gt;Continue&lt;/strong&gt; all speak the OpenAI wire protocol — point them at a &lt;code&gt;base_url&lt;/code&gt;, give them an API key, done. That makes swapping in a different LLM backend trivial... &lt;em&gt;if&lt;/em&gt; that backend uses &lt;code&gt;Authorization: Bearer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The flat-priced, auto-routing API I'd been using doesn't. It's distributed through RapidAPI, which authenticates with an &lt;code&gt;X-RapidAPI-Key&lt;/code&gt; header instead of &lt;code&gt;Bearer&lt;/code&gt;. So I couldn't just drop it into Aider. The fix turned out to be ~120 lines, so I open-sourced it.&lt;/p&gt;

&lt;h2&gt;
  
  
  modelis-openai
&lt;/h2&gt;

&lt;p&gt;A zero-dependency local proxy (MIT, Node 18+). It listens on &lt;code&gt;127.0.0.1&lt;/code&gt;, speaks plain OpenAI, rewrites the auth header, and forwards to the upstream gateway. Streaming (&lt;code&gt;stream: true&lt;/code&gt;) is piped straight through, so token-by-token output works exactly as with the OpenAI API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your tool ──OpenAI(Bearer)──▶ modelis-openai (localhost) ──X-RapidAPI-Key──▶ upstream ──▶ best model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quickstart
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx modelis-openai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then point any OpenAI-compatible tool at it:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Base URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:8787/v1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API key&lt;/td&gt;
&lt;td&gt;your RapidAPI key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;&lt;code&gt;modelis-auto&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Drop it into your tool
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Aider&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_BASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://127.0.0.1:8787/v1
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your-rapidapi-key&amp;gt;
aider &lt;span class="nt"&gt;--model&lt;/span&gt; openai/modelis-auto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cline / Roo Code&lt;/strong&gt; — API Provider &lt;code&gt;OpenAI Compatible&lt;/code&gt;, Base URL &lt;code&gt;http://127.0.0.1:8787/v1&lt;/code&gt;, Model ID &lt;code&gt;modelis-auto&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continue&lt;/strong&gt; (&lt;code&gt;~/.continue/config.yaml&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Modelis&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;modelis-auto&lt;/span&gt;
    &lt;span class="na"&gt;apiBase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:8787/v1&lt;/span&gt;
    &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your-rapidapi-key&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Any OpenAI SDK&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://127.0.0.1:8787/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;your-rapidapi-key&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;modelis-auto&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Reads the key from &lt;code&gt;Authorization: Bearer &amp;lt;key&amp;gt;&lt;/code&gt; (or &lt;code&gt;MODELIS_RAPIDAPI_KEY&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Rewrites the request &lt;code&gt;model&lt;/code&gt; to &lt;code&gt;modelis-auto&lt;/code&gt; (configurable).&lt;/li&gt;
&lt;li&gt;Forwards to the RapidAPI gateway with &lt;code&gt;X-RapidAPI-Key&lt;/code&gt; / &lt;code&gt;X-RapidAPI-Host&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Relays the response — including SSE streams and rate-limit headers — unchanged.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It also answers &lt;code&gt;GET /v1/models&lt;/code&gt; and &lt;code&gt;GET /health&lt;/code&gt; so tools that probe on startup don't choke.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It routes to a &lt;strong&gt;paid&lt;/strong&gt; API (there's a free tier to start). The point of the proxy is to remove the integration friction, not to give anything away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cursor isn't supported&lt;/strong&gt; — it sends requests from its own servers, so a &lt;code&gt;localhost&lt;/code&gt; endpoint can't be reached. This is for tools that call the API from your machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/modelishub/modelis-openai" rel="noopener noreferrer"&gt;https://github.com/modelishub/modelis-openai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/modelis-openai" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/modelis-openai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The API it bridges: &lt;a href="https://rapidapi.com/chenxiao5580/api/modelis-auto-chat" rel="noopener noreferrer"&gt;https://rapidapi.com/chenxiao5580/api/modelis-auto-chat&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try it in a tool I didn't list, I'd love to hear how it goes.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>One OpenAI-compatible API that auto-picks the model — and tells you which one answered</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Mon, 22 Jun 2026 13:04:38 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/one-openai-compatible-api-that-auto-picks-the-model-and-tells-you-which-one-answered-4lmc</link>
      <guid>https://dev.to/chenxiao5580cmd/one-openai-compatible-api-that-auto-picks-the-model-and-tells-you-which-one-answered-4lmc</guid>
      <description>&lt;p&gt;I had three API keys in my &lt;code&gt;.env&lt;/code&gt; — OpenAI, Anthropic, Google — plus an unwritten&lt;br&gt;
rule in my head: "cheap model for easy stuff, big model for the hard stuff."&lt;/p&gt;

&lt;p&gt;In practice I'd forget to switch, burn a frontier model on a one-line prompt, and&lt;br&gt;
then watch a per-token bill swing 5x week to week with no real change in what I&lt;br&gt;
was doing. So I built a small gateway to take that decision off my plate, and&lt;br&gt;
wrote a cookbook of drop-in examples for it. Sharing in case the same thing bugs&lt;br&gt;
you.&lt;/p&gt;
&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Modelis&lt;/strong&gt; is an OpenAI-compatible &lt;code&gt;/chat/completions&lt;/code&gt; API. You send one model&lt;br&gt;
name — &lt;code&gt;modelis-auto&lt;/code&gt; — and it routes each request to the right model (GPT,&lt;br&gt;
Claude, Gemini, …). Two things make it more than "yet another gateway":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Flat per-call pricing.&lt;/strong&gt; You pay a fixed rate per request, not per token, so
the bill doesn't balloon when a model gets chatty. It's predictable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It tells you who answered.&lt;/strong&gt; The response's &lt;code&gt;model&lt;/code&gt; field is the &lt;em&gt;real&lt;/em&gt; model
that handled the request. No black box.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's the OpenAI API with a different &lt;code&gt;base_url&lt;/code&gt;, so there's no new SDK to learn —&lt;br&gt;
your existing code keeps working.&lt;/p&gt;
&lt;h2&gt;
  
  
  How the routing actually works
&lt;/h2&gt;

&lt;p&gt;You pick a quality &lt;strong&gt;tier&lt;/strong&gt; (&lt;code&gt;basic&lt;/code&gt; / &lt;code&gt;standard&lt;/code&gt; / &lt;code&gt;premium&lt;/code&gt;). For each request,&lt;br&gt;
Modelis classifies it (how hard is it? code? reasoning? a one-liner?) and routes&lt;br&gt;
to the &lt;strong&gt;cheapest model that clears that tier's quality floor&lt;/strong&gt; for that kind of&lt;br&gt;
task. A trivial prompt might land on Gemini Flash; a gnarly reasoning task gets&lt;br&gt;
bumped to Claude or GPT — but you pay the &lt;strong&gt;same flat per-call rate for the tier&lt;/strong&gt;&lt;br&gt;
either way. The model choice is the system's problem; your cost stays fixed.&lt;/p&gt;
&lt;h2&gt;
  
  
  30-second integration
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_MODELIS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;# free key at https://modelishub.com
&lt;/span&gt;    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://modelishub.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# &amp;lt;- the only change
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;modelis-auto&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;In one sentence, what is an LLM gateway?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answered by:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output — note the second line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;An LLM gateway is a middleware service that routes, manages, and secures
requests to one or more large language models.

answered by: openai/gpt-4.1-2025-04-14
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I sent &lt;code&gt;modelis-auto&lt;/code&gt;; for that easy prompt the router picked &lt;code&gt;gpt-4.1&lt;/code&gt; and said&lt;br&gt;
so. Ask something harder and it moves up; ask something trivial and it drops to a&lt;br&gt;
cheaper model — the per-call price doesn't move.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use it from the tools you already have
&lt;/h2&gt;

&lt;p&gt;Because it's just the OpenAI API with a different &lt;code&gt;base_url&lt;/code&gt;, it drops into most&lt;br&gt;
stacks unchanged. Runnable examples for each are in the cookbook:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;curl&lt;/strong&gt; — one request, see the &lt;code&gt;model&lt;/code&gt; field&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI Python / Node SDKs&lt;/strong&gt; — change &lt;code&gt;base_url&lt;/code&gt;, done&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LangChain&lt;/strong&gt; — &lt;code&gt;ChatOpenAI(base_url=...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel AI SDK&lt;/strong&gt; — &lt;code&gt;createOpenAI({ baseURL })&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool / function calling&lt;/strong&gt; — works on the direct endpoint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Cookbook:&lt;/strong&gt; &lt;a href="https://github.com/chenxiao5580-cmd/modelis-cookbook" rel="noopener noreferrer"&gt;https://github.com/chenxiao5580-cmd/modelis-cookbook&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How it's different from per-token gateways
&lt;/h2&gt;

&lt;p&gt;Most multi-model gateways still bill you per token and still expect you to name a&lt;br&gt;
model. That's fine until your spend becomes a function of how verbose a model&lt;br&gt;
decides to be, and until "which model for this call?" becomes a decision you make&lt;br&gt;
hundreds of times. Modelis trades that for a flat per-call price and an automatic&lt;br&gt;
choice — and then tells you what it chose so you can sanity-check it. Different&lt;br&gt;
trade-off, not a silver bullet; whether it fits depends on your workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Text chat is the first-class path today. Tool calling works on the direct
endpoint; vision isn't the focus yet.&lt;/li&gt;
&lt;li&gt;The free signup quota is small — it's for kicking the tires, not running
production for free.&lt;/li&gt;
&lt;li&gt;There's a managed pay-as-you-go option on RapidAPI, but that plan is &lt;strong&gt;basic
text chat only&lt;/strong&gt; (no tools/vision) — the auto-routing across premium models
lives on the direct endpoint.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I bother
&lt;/h2&gt;

&lt;p&gt;Per-token billing punishes you for verbose models and makes spend unpredictable;&lt;br&gt;
hand-picking a model per request is busywork you forget to do. A flat per-call&lt;br&gt;
price + automatic routing + a response that's honest about which model ran felt&lt;br&gt;
like the gateway I actually wanted to use.&lt;/p&gt;

&lt;p&gt;If you try it, I'd genuinely like feedback on the routing quality and whether flat&lt;br&gt;
pricing matters for your workload — drop a comment.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>openai</category>
      <category>api</category>
    </item>
    <item>
      <title>Use GPT, Claude, and Gemini with the OpenAI SDK - one base_url, any language</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Fri, 19 Jun 2026 15:24:17 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/use-gpt-claude-and-gemini-with-the-openai-sdk-one-baseurl-any-language-475n</link>
      <guid>https://dev.to/chenxiao5580cmd/use-gpt-claude-and-gemini-with-the-openai-sdk-one-baseurl-any-language-475n</guid>
      <description>&lt;p&gt;If you're juggling separate SDKs and API keys for OpenAI, Anthropic, and Google, here's a simpler setup: point the &lt;strong&gt;OpenAI SDK&lt;/strong&gt; at an OpenAI-compatible gateway and call GPT, Claude, and Gemini through &lt;strong&gt;one &lt;code&gt;base_url&lt;/code&gt; and one key&lt;/strong&gt; — at a flat, predictable per-call price instead of three separate per-token bills.&lt;/p&gt;

&lt;p&gt;Here's the exact change in five common stacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python (OpenAI SDK)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://modelishub.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_MODELIS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rest of your code stays the same — only &lt;code&gt;base_url&lt;/code&gt; and &lt;code&gt;api_key&lt;/code&gt; change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node.js (openai v4)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;OpenAI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://modelishub.com/v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MODELIS_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  curl (works in any language)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://modelishub.com/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_MODELIS_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hello"}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same pattern works in Go, Java, PHP, Rust — anywhere you can make an HTTP request.&lt;/p&gt;

&lt;h2&gt;
  
  
  LangChain
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://modelishub.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_MODELIS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Switching between GPT, Claude, and Gemini
&lt;/h2&gt;

&lt;p&gt;To use a different model, just change the &lt;code&gt;model&lt;/code&gt; id — &lt;code&gt;claude-sonnet-4-6&lt;/code&gt;, &lt;code&gt;gemini-2.5-flash&lt;/code&gt;, and so on. Same endpoint, same key. Fetch the full list any time with &lt;code&gt;GET /v1/models&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-sonnet-4-6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;# or gemini-2.5-flash, gpt-4o, ...
&lt;/span&gt;    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;This runs on &lt;strong&gt;Modelis&lt;/strong&gt;, an OpenAI-compatible LLM gateway that auto-routes each request to a model fitted to the task and bills a &lt;strong&gt;flat per-call price&lt;/strong&gt; (not per-token), so your bill stays predictable regardless of which model answered. Free tier to try it — &lt;a href="https://modelishub.com/" rel="noopener noreferrer"&gt;details + free key&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>python</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Stop guessing your AI bill: one endpoint for GPT-5.5, Claude &amp; Gemini at a flat per-call price</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Thu, 18 Jun 2026 16:17:46 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/stop-guessing-your-ai-bill-one-endpoint-for-gpt-55-claude-gemini-at-a-flat-per-call-price-3m8a</link>
      <guid>https://dev.to/chenxiao5580cmd/stop-guessing-your-ai-bill-one-endpoint-for-gpt-55-claude-gemini-at-a-flat-per-call-price-3m8a</guid>
      <description>&lt;p&gt;If you build on top of LLMs, you've probably hit this: you ship a feature, traffic spikes, and the API bill comes back way higher than you expected. Per-token pricing makes costs hard to predict — you're billed by how verbose the model is, not by the value you ship.&lt;/p&gt;

&lt;p&gt;I got tired of that (plus juggling three API keys), so here's a setup that fixes both: &lt;strong&gt;one OpenAI-compatible endpoint that auto-picks the best model and charges a flat price per call.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The core idea
&lt;/h2&gt;

&lt;p&gt;Instead of calling each provider directly, you point your existing OpenAI SDK at a single gateway and send one model name: &lt;code&gt;modelis-auto&lt;/code&gt;. It routes each request to the best model for the task (GPT-5.5, Claude Opus 4.8, Gemini 3.1, Grok, DeepSeek…) and bills a &lt;strong&gt;flat per-call rate&lt;/strong&gt; — so your cost is predictable regardless of which model handled it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero migration: just change base_url
&lt;/h2&gt;

&lt;p&gt;If you already use the OpenAI SDK, this is a one-line change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_MODELIS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://modelishub.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# the only change
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;modelis-auto&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                    &lt;span class="c1"&gt;# let it pick the best model
&lt;/span&gt;    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Explain CRDTs in two sentences.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or with curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://modelishub.com/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_MODELIS_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"modelis-auto","messages":[{"role":"user","content":"Hi"}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Your existing code, SDKs, and OpenAI-compatible tools keep working.&lt;/p&gt;

&lt;h2&gt;
  
  
  "But which model actually answered?"
&lt;/h2&gt;

&lt;p&gt;Fair question — auto-routing shouldn't be a black box. Every response returns a header telling you exactly which model handled the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X-Modelis-Routed-Model: claude-opus-4-8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you want control, you can stay in a quality tier or call a specific model directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;modelis-auto:premium"&lt;/span&gt;     &lt;span class="c1"&gt;# stay in a quality tier&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-5.5"&lt;/span&gt;                   &lt;span class="c1"&gt;# or pin a specific model&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why flat per-call instead of per-token
&lt;/h2&gt;

&lt;p&gt;The point isn't "cheaper than everyone" — it's &lt;strong&gt;predictable&lt;/strong&gt;. With a flat per-call price:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A verbose response doesn't cost more than a terse one.&lt;/li&gt;
&lt;li&gt;A busy day scales with calls, not with token noise.&lt;/li&gt;
&lt;li&gt;You can actually budget, and price your own product with confidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Honest take: when per-token is still fine
&lt;/h2&gt;

&lt;p&gt;If your workload is steady, you control prompt/response sizes tightly, and you've already optimized model choice per route, per-token billing can be cheaper. Flat per-call shines when traffic is bursty, prompts vary, or you just don't want to babysit model selection and cost. Pick what fits your reality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;There's a free tier: &lt;a href="https://modelishub.com" rel="noopener noreferrer"&gt;modelishub.com&lt;/a&gt;. I'd genuinely love feedback — especially whether predictable pricing actually matters for how you build, or if you prefer per-token control.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>api</category>
      <category>python</category>
    </item>
    <item>
      <title>Stop hand-picking an LLM per request: a practical case for auto-routing</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Tue, 16 Jun 2026 16:24:38 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/stop-hand-picking-an-llm-per-request-a-practical-case-for-auto-routing-2d4b</link>
      <guid>https://dev.to/chenxiao5580cmd/stop-hand-picking-an-llm-per-request-a-practical-case-for-auto-routing-2d4b</guid>
      <description>&lt;p&gt;Most LLM features ship with the model name hardcoded. You picked it once — usually the strongest one you could justify — and now every request, trivial or gnarly, hits the same expensive model. The easy ones overpay; if you down-picked to save money, the hard ones quietly degrade. You're paying the frontier price for "reformat this list," or shipping a weak answer on "find the bug in this trace."&lt;/p&gt;

&lt;p&gt;Routing per request fixes the mismatch: classify each request's difficulty, then send it to the cheapest model in your quality tier that can actually handle it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "difficulty" can mean in practice
&lt;/h2&gt;

&lt;p&gt;You don't need a research model to route well. Cheap, legible signals get you most of the way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input shape and length.&lt;/strong&gt; A 30-token reformat is not a 6,000-token "reason over this codebase" request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task type keywords / structure.&lt;/strong&gt; Extraction and classification skew easy; multi-step reasoning, code debugging, and math skew hard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A tiny classifier up front.&lt;/strong&gt; A small, fast model can score difficulty in a few milliseconds and a fraction of a cent, then hand off to the right tier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The router doesn't have to be perfect. It has to be &lt;em&gt;better than a single hardcoded choice&lt;/em&gt; — which is a low bar, because a hardcoded choice is wrong for half your distribution by construction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where routing misfires (and why you must plan for it)
&lt;/h2&gt;

&lt;p&gt;Anyone who's run this in production will tell you the failure modes are the interesting part:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deceptively short hard prompts.&lt;/strong&gt; "Prove this is NP-complete" is 5 tokens and very hard. Length-only routing sends it to a weak model and you get a confident-wrong answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Misclassification is silent.&lt;/strong&gt; A bad route doesn't error — it just returns a worse answer. Without eval, you won't see it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tier boundaries are fuzzy.&lt;/strong&gt; Requests near the easy/hard line will flip routes run-to-run, making behavior feel non-deterministic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So routing is not "set and forget." It needs guardrails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping it safe
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Route within a quality floor, never below it.&lt;/strong&gt; Let the user pick a tier; the router chooses &lt;em&gt;within&lt;/em&gt; it, so the worst case is still acceptable. Never silently drop to a model the user wouldn't accept.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bias toward the stronger model on uncertainty.&lt;/strong&gt; When the difficulty score is ambiguous, round &lt;em&gt;up&lt;/em&gt;. A few cents of overspend beats a wrong answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make routing decisions observable.&lt;/strong&gt; Log which model served each request and why. You can't debug or tune a router you can't see.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eval the routes, not just the models.&lt;/strong&gt; Periodically check that easy-routed requests would've gotten the same answer from the strong model, and that hard-routed ones aren't degrading.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it buys you
&lt;/h2&gt;

&lt;p&gt;When it's tuned, you stop overpaying on the (usually majority) easy traffic without down-grading the hard tail — and you stop hand-maintaining a model choice that drifts out of date every time providers ship something new. The routing logic lives in one place instead of smeared across feature code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Hardcoding one model per feature optimizes for nothing — it's a coin flip that's wrong for half your request distribution. Difficulty-based routing within a quality tier, with an "round up when unsure" bias and real observability, is a better default. I've built this into a small OpenAI-compatible gateway called &lt;strong&gt;Modelis&lt;/strong&gt; (send &lt;code&gt;model: "auto"&lt;/code&gt;, it routes within your tier and bills a flat per-call price, free tier) at &lt;a href="https://modelishub.com/" rel="noopener noreferrer"&gt;modelishub.com&lt;/a&gt; — but you can build the same idea yourself with a small front classifier. I'd love to hear the nastiest "short prompt, secretly hard" example you've hit — those are the routing killers.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>api</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>One base_url for GPT, Claude, and Gemini: cutting three SDKs down to one</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Tue, 16 Jun 2026 16:16:17 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/one-baseurl-for-gpt-claude-and-gemini-cutting-three-sdks-down-to-one-24ii</link>
      <guid>https://dev.to/chenxiao5580cmd/one-baseurl-for-gpt-claude-and-gemini-cutting-three-sdks-down-to-one-24ii</guid>
      <description>&lt;p&gt;The first time you add a second LLM provider to a codebase, it feels manageable. By the third, you've got three SDKs, three auth schemes, three slightly different &lt;code&gt;messages&lt;/code&gt; shapes, three retry policies, and three places a model deprecation can break you. The "use the best model for each job" advice is correct — but the integration tax is real, and it compounds.&lt;/p&gt;

&lt;p&gt;Here's the pattern I keep coming back to: put everything behind &lt;strong&gt;one OpenAI-compatible endpoint&lt;/strong&gt; and stop maintaining three clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual cost of multi-SDK glue
&lt;/h2&gt;

&lt;p&gt;It's not the happy path that hurts — it's everything around it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auth drift.&lt;/strong&gt; OpenAI wants a Bearer key, Anthropic wants &lt;code&gt;x-api-key&lt;/code&gt; + a version header, Google wants its own scheme. Three secrets, three rotation schedules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response-shape divergence.&lt;/strong&gt; &lt;code&gt;choices[0].message.content&lt;/code&gt; vs. a &lt;code&gt;content&lt;/code&gt; block array vs. &lt;code&gt;candidates[].content.parts[]&lt;/code&gt;. Every call site that reads a response needs a per-provider branch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streaming differences.&lt;/strong&gt; SSE framing and event names differ enough that your stream parser grows a switch statement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failure-mode sprawl.&lt;/strong&gt; Rate-limit codes, timeout behavior, and error bodies all differ. Your retry/backoff logic forks per provider.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of it is hard. All of it is &lt;em&gt;maintenance&lt;/em&gt; — the kind that quietly slows a small team down.&lt;/p&gt;

&lt;h2&gt;
  
  
  The OpenAI-compatible shim
&lt;/h2&gt;

&lt;p&gt;Most providers can be normalized to the OpenAI Chat Completions contract, because the ecosystem already standardized on it. So you point the official OpenAI SDK at a different &lt;code&gt;base_url&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://your-gateway/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_GATEWAY_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;# or claude-*, gemini-*, etc.
&lt;/span&gt;    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize this PR in two lines.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same call site, same response shape, one key. To switch the underlying model you change one string. Your retry logic, your streaming parser, your logging — all written once, against one contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you actually gain
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One auth + one secret to rotate&lt;/strong&gt;, not three.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One response shape&lt;/strong&gt; at every call site — no per-provider branching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No lock-in.&lt;/strong&gt; Because you code against the OpenAI contract (an open de-facto standard), moving off any single provider — or off the gateway itself — is a &lt;code&gt;base_url&lt;/code&gt; change, not a rewrite. That cuts both ways, and that's the point.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What you give up (the honest part)
&lt;/h2&gt;

&lt;p&gt;A normalization layer can't be a free lunch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Provider-specific features get flattened.&lt;/strong&gt; Anthropic's prompt caching, Google's grounding, OpenAI's structured-output modes — anything that doesn't map cleanly to the common contract is either unavailable or exposed through non-standard fields you'll have to special-case anyway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You add a hop.&lt;/strong&gt; One more network segment and one more thing that can be down. For latency-sensitive paths, measure it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You inherit the shim's coverage gaps.&lt;/strong&gt; If the gateway hasn't mapped a parameter you need, you're blocked until it does. Pick one whose mapping is transparent and documented.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trade is: lose access to the long tail of provider-specific knobs, gain a dramatically smaller integration surface. For most app teams — who use maybe 5% of any provider's surface — that's a good deal. For teams leaning hard on one provider's exclusive features, it isn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;If your codebase has grown a per-provider branch at every LLM call site, collapsing to one OpenAI-compatible &lt;code&gt;base_url&lt;/code&gt; removes a whole category of maintenance — at the cost of the provider-specific long tail. I build this into a small gateway called &lt;strong&gt;Modelis&lt;/strong&gt; (one key for GPT/Claude/Gemini, optional &lt;code&gt;auto&lt;/code&gt; routing, free tier) at &lt;a href="https://modelishub.com/" rel="noopener noreferrer"&gt;modelishub.com&lt;/a&gt;, but the shim pattern works with anything OpenAI-compatible. Curious which provider-specific feature you'd &lt;em&gt;refuse&lt;/em&gt; to give up — that's usually the deciding factor.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>api</category>
      <category>openai</category>
      <category>ai</category>
    </item>
    <item>
      <title>Stop getting surprise per-token LLM bills: a flat-rate, auto-routing API approach</title>
      <dc:creator>chenxiao5580-cmd</dc:creator>
      <pubDate>Tue, 16 Jun 2026 16:13:36 +0000</pubDate>
      <link>https://dev.to/chenxiao5580cmd/stop-getting-surprise-per-token-llm-bills-a-flat-rate-auto-routing-api-approach-20fb</link>
      <guid>https://dev.to/chenxiao5580cmd/stop-getting-surprise-per-token-llm-bills-a-flat-rate-auto-routing-api-approach-20fb</guid>
      <description>&lt;p&gt;If you ship anything on top of an LLM API, you've probably had this moment: you check the dashboard at the end of the month and the bill is 3x what you modeled. Nothing broke. Usage just... drifted. A few prompts got chattier, one model started "thinking" more, and your per-token math quietly fell apart.&lt;/p&gt;

&lt;p&gt;I've been living in that loop, so I want to lay out &lt;em&gt;why&lt;/em&gt; per-token pricing is hard to forecast, and a different billing shape that trades some theoretical savings for a number you can actually predict.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why per-token spend is so hard to model
&lt;/h2&gt;

&lt;p&gt;Per-token billing looks simple — price × tokens — but three things make it slippery in practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Output length is not yours to control.&lt;/strong&gt; &lt;code&gt;max_tokens&lt;/code&gt; is a hard ceiling, but the model decides how much of that ceiling it actually uses. Two models given the identical prompt can produce wildly different output lengths, and the verbose one costs you more for the &lt;em&gt;same task&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. "Reasoning" tokens are invisible until billed.&lt;/strong&gt; Some newer models (e.g. OpenAI's o-series) emit internal reasoning tokens that you're charged for but don't see in the default response. Your logs show a 200-token answer; the invoice counts the 1,500 tokens it took to get there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Input grows silently.&lt;/strong&gt; RAG context, longer chat histories, system prompts that accrete over time — input token counts creep up release by release, and without active monitoring nobody notices until the bill does.&lt;/p&gt;

&lt;p&gt;Individually these are fine. Together they mean your cost-per-request has a fat tail, and a fat tail is exactly what you can't put in a pricing page or a unit-economics spreadsheet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The alternative: bill a flat price per call
&lt;/h2&gt;

&lt;p&gt;The idea is simple: instead of charging for whatever tokens happened, charge a &lt;strong&gt;flat rate per request&lt;/strong&gt; within a quality tier you pick. The bill becomes &lt;code&gt;calls × tier_price&lt;/code&gt;, full stop. Output length, reasoning tokens, which specific model answered — none of it changes what &lt;em&gt;you&lt;/em&gt; pay.&lt;/p&gt;

&lt;p&gt;You give up something real here (more on that below), but you gain the one thing per-token can't offer: &lt;strong&gt;a cost you can forecast before you ship&lt;/strong&gt;. For a lot of products — fixed-price SaaS features, internal tools with a budget, anything where you quote a customer a number — that predictability is worth more than shaving a few percent off the theoretical optimum.&lt;/p&gt;

&lt;p&gt;Concretely: say a request averages 1,000 tokens and a cheap model bills $0.0005/1K — that's ~$0.0005/call. A flat tier at, say, $0.002/call costs more &lt;em&gt;on that uniform workload&lt;/em&gt;. But the moment your requests vary — some 200 tokens, some 8,000, some routed to a frontier model — the per-token average climbs and its variance explodes, while the flat price stays put. Flat pricing wins on the spread, not the average.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pairing it with auto-routing
&lt;/h2&gt;

&lt;p&gt;Flat-per-call pricing gets more interesting when you stop hand-picking the model. If every request costs the same regardless of which model serves it, you can let a router classify each request's difficulty and send it to the cheapest model that can actually handle it — a small model for "summarize this", a frontier model for "debug this race condition" — without you wiring up that logic or eating a surprise when a hard request lands on an expensive model.&lt;/p&gt;

&lt;p&gt;The developer-facing contract stays boring on purpose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://your-gateway/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "auto",
    "messages": [{"role":"user","content":"Explain quantum entanglement in one sentence."}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's an OpenAI-compatible &lt;code&gt;/chat/completions&lt;/code&gt; body, so existing SDKs work by changing &lt;code&gt;base_url&lt;/code&gt; and the key. You send one model name (&lt;code&gt;auto&lt;/code&gt;) and let routing + a flat tier price do the rest. Zero migration is part of the pitch — if it needs a rewrite, nobody switches.&lt;/p&gt;

&lt;h2&gt;
  
  
  When flat pricing does NOT pay off (the honest part)
&lt;/h2&gt;

&lt;p&gt;This isn't a free lunch, and pretending otherwise would be dishonest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High-volume, short, predictable calls.&lt;/strong&gt; If your requests are tiny and uniform (think: classification of one-line inputs at scale), per-token on a cheap model will almost certainly beat a flat per-call rate. Flat pricing's value is in &lt;em&gt;variance reduction&lt;/em&gt;, and you have no variance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You've already done the FinOps work.&lt;/strong&gt; If you have tight token budgets, prompt-length guards, and good observability, you've manufactured your own predictability and a flat tier buys you less.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need features flat tiers cap.&lt;/strong&gt; Vision inputs, tool/function-calling, huge outputs — flat per-call tiers often bound these (depending on the gateway) to keep the price honest. If you need them, a metered model fits better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You have strict latency SLAs.&lt;/strong&gt; Cost-only routing can pick a cheap-but-slow model. If you're under a hard latency budget, the router needs a latency filter too — extra complexity that eats some of the simplicity win.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rule of thumb: &lt;strong&gt;flat pricing is insurance against variance.&lt;/strong&gt; The more your per-request cost jumps around — mixed task difficulty, verbose or reasoning-heavy models, growing context — the more that insurance is worth. The flatter your workload already is, the less you need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Per-token billing isn't wrong, but it optimizes for a metric (tokens) that isn't the one you're trying to control (a predictable bill). If you're quoting fixed prices to customers, or you just want your LLM line item to stop surprising you, a flat per-call rate — ideally with auto-routing underneath — is worth a look.&lt;/p&gt;

&lt;p&gt;I've been building this approach into a small OpenAI-compatible gateway called &lt;strong&gt;Modelis&lt;/strong&gt; (one key for GPT/Claude/Gemini, &lt;code&gt;auto&lt;/code&gt; routing, flat per-plan pricing, free tier to try). If you want to kick the tires, it's at &lt;a href="https://modelishub.com/" rel="noopener noreferrer"&gt;modelishub.com&lt;/a&gt;. But the billing argument stands on its own — I'd genuinely like to hear where flat-vs-metered breaks for your workload in the comments.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>api</category>
      <category>openai</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
