<?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: Yucong Chen</title>
    <description>The latest articles on DEV Community by Yucong Chen (@moozechen).</description>
    <link>https://dev.to/moozechen</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%2F4038368%2F2fdbcc6b-ac4a-48fa-b6b1-70356c50d332.png</url>
      <title>DEV Community: Yucong Chen</title>
      <link>https://dev.to/moozechen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/moozechen"/>
    <language>en</language>
    <item>
      <title>A real consulting deliverable, unedited</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 14:31:27 +0000</pubDate>
      <link>https://dev.to/moozechen/a-real-consulting-deliverable-unedited-2a4j</link>
      <guid>https://dev.to/moozechen/a-real-consulting-deliverable-unedited-2a4j</guid>
      <description>&lt;p&gt;This is the &lt;strong&gt;unedited output&lt;/strong&gt; of a consulting pipeline, for a prompt about a 5-person B2B SaaS&lt;br&gt;
at 30k MRR with 40 customers on a flat 750/month plan, asking whether to raise prices 20% for&lt;br&gt;
new customers or add a cheaper tier. The question is generic, so nothing here is confidential.&lt;/p&gt;

&lt;p&gt;Two honest facts before you read it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It took about six minutes&lt;/strong&gt; end to end. A trivial prompt finishes in about 30–80 seconds; a real
decision question does not. Anyone claiming a strategy document in two seconds is returning a
single model's stream-of-consciousness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It cost a few cents of tokens&lt;/strong&gt;, metered from the balance — not a retainer, not a seat license.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Consulting Report: Pricing Decision for a B2B SaaS at $30k MRR
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Executive Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Decision: Raise prices 20% for new customers. Do not add a cheaper tier at this time.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raise the standard rate from &lt;strong&gt;$750/month to $900/month for new customers&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Grandfather the existing 40 customers at $750/month, at least for a defined period.&lt;/li&gt;
&lt;li&gt;Hold off on a cheaper tier until there is clear evidence of a distinct lower-price segment with acceptable unit economics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The company is at a scale where improving ARPU, margin, and positioning matters more than adding operational complexity or chasing lower-end volume. A 20% increase is moderate, protects the existing revenue base, and requires minimal operational change.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Current Economics
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&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;Customers&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price&lt;/td&gt;
&lt;td&gt;$750/month flat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MRR&lt;/td&gt;
&lt;td&gt;$30,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARR run rate&lt;/td&gt;
&lt;td&gt;$360,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARPU&lt;/td&gt;
&lt;td&gt;$750/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team size&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The business has a single plan, one price point, and a small team. This means pricing changes should be simple and should avoid creating new support, onboarding, or packaging burdens unless the ROI is very clear.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Option Analysis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option A: Raise prices 20% for new customers
&lt;/h3&gt;

&lt;p&gt;Proposed new price: &lt;strong&gt;$900/month&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revenue impact:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Each new customer adds &lt;strong&gt;$150/month more&lt;/strong&gt; than under the current price. Existing revenue remains stable at $30k MRR.&lt;/p&gt;

&lt;p&gt;For example, acquiring 10 new customers in a year would generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Current pricing: &lt;code&gt;10 × $750 × 12 = $90,000&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;New pricing: &lt;code&gt;10 × $900 × 12 = $108,000&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Incremental revenue: &lt;strong&gt;$18,000&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The short-term revenue lift is modest because the existing base is grandfathered, but the strategic benefit is meaningful: you reset the value anchor without risking current customers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key advantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low operational complexity: only sales and marketing pricing updates.&lt;/li&gt;
&lt;li&gt;Low churn risk for existing customers.&lt;/li&gt;
&lt;li&gt;Improves unit economics and ARPU.&lt;/li&gt;
&lt;li&gt;Positions the product as more valuable.&lt;/li&gt;
&lt;li&gt;Keeps the product and packaging unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Main concern:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some new prospects may push back on the higher price if the value story is weak.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Option B: Add a cheaper tier
&lt;/h3&gt;

&lt;p&gt;A cheaper tier might be, for example, &lt;strong&gt;$390–$450/month&lt;/strong&gt; with limited features or usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revenue impact depends heavily on mix.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose a cheaper tier is set at $450/month:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If one existing $750 customer downgrades, the company loses &lt;strong&gt;$300/month&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It takes &lt;strong&gt;two new lower-tier customers just to replace the revenue&lt;/strong&gt; of one downgrade.&lt;/li&gt;
&lt;li&gt;If lower-tier customers also demand more support relative to their spend, the ne&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;The full, unstyled version (with the risk section) is here:&lt;/em&gt;&lt;br&gt;
&lt;a href="https://flintapi.ai/blog/2026-10-28-sample-consulting-report" rel="noopener noreferrer"&gt;https://flintapi.ai/blog/2026-10-28-sample-consulting-report&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to try the same thing on your own problem, describe it and you get the plan first,&lt;br&gt;
then decide whether to run it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>consulting</category>
      <category>ai</category>
      <category>startup</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What an 81-second strategy deliverable actually looks like</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 13:21:11 +0000</pubDate>
      <link>https://dev.to/moozechen/what-an-81-second-strategy-deliverable-actually-looks-like-2c5k</link>
      <guid>https://dev.to/moozechen/what-an-81-second-strategy-deliverable-actually-looks-like-2c5k</guid>
      <description>&lt;p&gt;We build a consulting product. Not an API, not a chatbot — a thing you describe a business&lt;br&gt;
problem to, and 81 seconds later a structured, CEO-ready document comes back that you could&lt;br&gt;
put in front of a board.&lt;/p&gt;

&lt;p&gt;That number came from a deliberate measurement, not marketing. Last night I ran the smallest&lt;br&gt;
possible request through our pipeline and timed it end to end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /v1/consulting/tasks   { query: "Say hi in one sentence.", mode: consulting_report }
→ 11s running
→ 21s running
→ 71s running
→ 81s succeeded          answer length: 2,178 characters   artifacts: 1
→ balance charged, usage row written
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A trivial prompt, and it still took 81 seconds. That is the honest cost of a multi-stage&lt;br&gt;
pipeline: reframe the question, decompose it into sub-tasks, route each sub-task to a&lt;br&gt;
different model, synthesise the results, then assemble a report. Anyone who tells you their&lt;br&gt;
LLM product answers a &lt;em&gt;strategic&lt;/em&gt; question in two seconds is either caching, or returning a&lt;br&gt;
single model's stream-of-consciousness and calling it a deliverable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the deliverable is made of
&lt;/h2&gt;

&lt;p&gt;The output is not a paragraph. It is a document with a fixed skeleton:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Executive summary&lt;/strong&gt; — the answer, in the form you could read aloud in a meeting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context and goals&lt;/strong&gt; — what we understood the problem to be&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key findings&lt;/strong&gt; — the parts that surprised us, or that constrain the answer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended design&lt;/strong&gt; — the actual proposal, with options and trade-offs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risks and mitigations&lt;/strong&gt; — what would make this fail, and what we'd do about it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interesting engineering problem is not generating text. It is &lt;strong&gt;making five sections that&lt;br&gt;
agree with each other&lt;/strong&gt;, when each was produced by a different model with a different context&lt;br&gt;
window. That is where most of the 81 seconds goes, and it is why a single-model answer reads&lt;br&gt;
fluent but incoherent if you check one section against another.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boring parts nobody shows you
&lt;/h2&gt;

&lt;p&gt;Three things we had to fix before the pipeline was worth shipping:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A dead upstream must not kill the whole run.&lt;/strong&gt; Our router used to pick models from a&lt;br&gt;
fixed per-domain list. When one provider's account ran out of credit, every request died with&lt;br&gt;
&lt;code&gt;HTTP 403 用户额度不足&lt;/code&gt; — and the failure surfaced as a &lt;em&gt;content&lt;/em&gt; string inside a 200 response.&lt;br&gt;
Now: failures are detected as failures, the run does not get billed, and the router fails over&lt;br&gt;
to a provider that is actually healthy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A thinking model leaks its thinking.&lt;/strong&gt; Some upstreams stream the entire answer in a&lt;br&gt;
&lt;code&gt;reasoning_content&lt;/code&gt; field and leave &lt;code&gt;content&lt;/code&gt; empty. Our first fix was to copy it into&lt;br&gt;
&lt;code&gt;content&lt;/code&gt; so clients saw &lt;em&gt;something&lt;/em&gt;; the second fix was to buffer it and only emit it if no&lt;br&gt;
real content ever arrives. Streaming should give you the answer, not the rehearsal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Never promise a channel you cannot deliver on.&lt;/strong&gt; The product page used to say "leave and&lt;br&gt;
we'll email you the report." For one day our transactional email quota was exhausted, which&lt;br&gt;
meant leaving the page meant losing the report. The copy now says the report stays on the page,&lt;br&gt;
and email is a &lt;em&gt;if available&lt;/em&gt; extra. Two words change, one broken promise avoided.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it's not
&lt;/h2&gt;

&lt;p&gt;It is not a replacement for a consultant who knows your industry. It is the thing you do&lt;br&gt;
&lt;em&gt;before&lt;/em&gt; hiring one: getting a structured initial position, in a minute, so that the expensive&lt;br&gt;
conversation starts from a draft instead of a blank page.&lt;/p&gt;

&lt;p&gt;And it costs tokens, not retainer hours — which is exactly why it runs on a token-metered&lt;br&gt;
pipeline rather than a per-seat subscription.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to see the shape of the output, describe a problem you actually have. The report&lt;br&gt;
appears in the page, usually under two minutes.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>consulting</category>
      <category>ai</category>
      <category>startup</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Build a Multimodal App in an Afternoon with FlintAPI</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:34:10 +0000</pubDate>
      <link>https://dev.to/moozechen/build-a-multimodal-app-in-an-afternoon-with-flintapi-5g62</link>
      <guid>https://dev.to/moozechen/build-a-multimodal-app-in-an-afternoon-with-flintapi-5g62</guid>
      <description>&lt;p&gt;FlintAPI unifies a dozen Chinese AI models behind one OpenAI-compatible endpoint. Swap your base URL to &lt;a href="https://flintapi.ai/v1" rel="noopener noreferrer"&gt;https://flintapi.ai/v1&lt;/a&gt; and start building in minutes. New accounts get free starter credit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a unified API
&lt;/h2&gt;

&lt;p&gt;Managing multiple provider accounts wastes engineering time. One key, one SDK, every model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;Send a request to /v1/chat/completions and switch models by changing one field.&lt;/p&gt;

&lt;p&gt;Learn more at &lt;a href="https://flintapi.ai" rel="noopener noreferrer"&gt;https://flintapi.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>api</category>
      <category>programming</category>
    </item>
    <item>
      <title>How Flint-Smart Routing Can Cut Your AI Bill</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:33:29 +0000</pubDate>
      <link>https://dev.to/moozechen/how-flint-smart-routing-can-cut-your-ai-bill-1l6a</link>
      <guid>https://dev.to/moozechen/how-flint-smart-routing-can-cut-your-ai-bill-1l6a</guid>
      <description>&lt;p&gt;FlintAPI unifies a dozen Chinese AI models behind one OpenAI-compatible endpoint. Instead of juggling a dozen provider accounts, you send every request to &lt;a href="https://flintapi.ai/v1/chat/completions" rel="noopener noreferrer"&gt;https://flintapi.ai/v1/chat/completions&lt;/a&gt; and switch models by changing a single field.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why automatic routing matters
&lt;/h2&gt;

&lt;p&gt;Picking the right model per task is tedious and expensive. A flagship model is overkill for classification; a small model struggles with reasoning. Flint-Smart analyzes each prompt and routes to the best model for the job — usually the cheapest one that still does it well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;Point your OpenAI-compatible client at FlintAPI, set model=flint-smart, and ship. New accounts get free starter credit — no credit card required.&lt;/p&gt;

&lt;p&gt;Learn more at &lt;a href="https://flintapi.ai" rel="noopener noreferrer"&gt;https://flintapi.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>api</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Chinese LLM Landscape in 2026: A Practical Guide</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:32:47 +0000</pubDate>
      <link>https://dev.to/moozechen/the-chinese-llm-landscape-in-2026-a-practical-guide-522h</link>
      <guid>https://dev.to/moozechen/the-chinese-llm-landscape-in-2026-a-practical-guide-522h</guid>
      <description>&lt;p&gt;FlintAPI unifies a dozen Chinese AI models behind one OpenAI-compatible endpoint. Swap your base URL to &lt;a href="https://flintapi.ai/v1" rel="noopener noreferrer"&gt;https://flintapi.ai/v1&lt;/a&gt; and start building in minutes. New accounts get free starter credit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a unified API
&lt;/h2&gt;

&lt;p&gt;Managing multiple provider accounts wastes engineering time. One key, one SDK, every model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;Send a request to /v1/chat/completions and switch models by changing one field.&lt;/p&gt;

&lt;p&gt;Learn more at &lt;a href="https://flintapi.ai" rel="noopener noreferrer"&gt;https://flintapi.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>china</category>
      <category>programming</category>
    </item>
    <item>
      <title>What we tell users when 9 of our 13 models are down</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:30:01 +0000</pubDate>
      <link>https://dev.to/moozechen/what-we-tell-users-when-9-of-our-13-models-are-down-21j9</link>
      <guid>https://dev.to/moozechen/what-we-tell-users-when-9-of-our-13-models-are-down-21j9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-10-28, 21:44 UTC+8).&lt;/strong&gt; The upstream account behind these models recovered within hours: &lt;code&gt;GET /api/health/models&lt;/code&gt; now reports &lt;strong&gt;11 of 13 healthy&lt;/strong&gt;. The numbers below (four healthy, one account at minus three cents) are the state at the time of writing and are kept as the reason this contract exists — not as the current status. For the live number, always call the endpoint.&lt;br&gt;
A gateway fails in two ways. The loud way is a 500. The quiet way is a model that&lt;br&gt;
has been returning &lt;code&gt;503&lt;/code&gt; for six hours while every dashboard says "active".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We shipped the quiet way twice this month. This is what we changed, and the&lt;br&gt;
contract you can now check before you build against us.&lt;/p&gt;
&lt;h2&gt;
  
  
  The mistake
&lt;/h2&gt;

&lt;p&gt;We had a health checker that did this, more or less:&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;catalogue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;upstream_returns_2xx&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;   &lt;span class="nf"&gt;mark_healthy&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;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                        &lt;span class="nf"&gt;mark_unhealthy&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;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unhealthy_for_2_checks&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nf"&gt;deactivate&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;Two assumptions in four lines, both wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One: "unhealthy" is not always the model's fault.&lt;/strong&gt; When the upstream account&lt;br&gt;
runs out of balance, &lt;em&gt;every&lt;/em&gt; model behind it fails at the same instant, with the&lt;br&gt;
same error. My checker saw eight failures and dutifully deactivated eight models.&lt;br&gt;
The models were fine. The account was empty. Deactivating them made the outage&lt;br&gt;
longer, because now they would not even be retried.&lt;/p&gt;

&lt;p&gt;The fix was a distinction the code did not previously have:&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="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;all_checks_failed_with_account_level_error&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SKIP auto-isolate: account-level failure (balance) -- do NOT deactivate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;isolate_the_single_bad_model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that line exists in the log, and it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[auto-isolate] SKIP kimi-k3: account-level failure (balance) -- do NOT deactivate the model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Two: "2xx from upstream" does not mean "works for this model name".&lt;/strong&gt; Some&lt;br&gt;
suppliers route by model name and return a perfectly valid 200 with an error body,&lt;br&gt;
or accept the name in &lt;code&gt;/models&lt;/code&gt; and reject it in &lt;code&gt;/chat/completions&lt;/code&gt;. A health&lt;br&gt;
check that only looks at status codes will mark those models healthy forever.&lt;/p&gt;
&lt;h2&gt;
  
  
  The contract we publish now
&lt;/h2&gt;

&lt;p&gt;If a model is unavailable, the response is not a mystery. It is this, with&lt;br&gt;
&lt;code&gt;HTTP 503&lt;/code&gt;:&lt;br&gt;
&lt;/p&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Service temporarily unavailable: upstream model capacity is exhausted for the requested model. Please retry later or contact support@flintapi.ai."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"service_unavailable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"upstream_capacity_exhausted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"hint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Other models may still be available right now: https://flintapi.ai/api/health/models"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"available_models"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"deepseek-v4-pro"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deepseek-v4.1-flash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"glm-5.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"glm-5.3-flash"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&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;Three properties matter here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A machine-readable code&lt;/strong&gt; (&lt;code&gt;upstream_capacity_exhausted&lt;/code&gt;), so your retry and
failover logic does not have to parse English.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The list of models that are working right now&lt;/strong&gt;, so a 503 is actionable
— you can fall back without a human.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Retry-After&lt;/code&gt;&lt;/strong&gt;, so a naive client does not hammer us in a loop.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And the single source of truth, which is public and needs no auth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET https://flintapi.ai/api/health/models
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returns &lt;code&gt;total&lt;/code&gt; and &lt;code&gt;healthy&lt;/code&gt; counts joined against the catalogue that we&lt;br&gt;
actually serve. If that endpoint says four models are healthy, then four models&lt;br&gt;
are healthy — we do not keep a second, prettier number anywhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we do not "just multiply the model list"
&lt;/h2&gt;

&lt;p&gt;It is tempting to advertise thirty models and route whatever works. That converts&lt;br&gt;
our availability problem into your correctness problem: your temperature, your&lt;br&gt;
token budget, your structured-output assumptions silently run on a different model&lt;br&gt;
than the one you named. We would rather return a loud 503 for a named model than a&lt;br&gt;
quiet 200 from a substitute.&lt;/p&gt;

&lt;p&gt;If you &lt;em&gt;do&lt;/em&gt; want substitution, it is opt-in: send &lt;code&gt;model: "flint"&lt;/code&gt; and the router&lt;br&gt;
decomposes the prompt and picks per sub-task, and it says which model answered.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers, dated
&lt;/h2&gt;

&lt;p&gt;As of 2026-10-28: &lt;strong&gt;13 models in the catalogue, 4 healthy&lt;/strong&gt;, because one upstream&lt;br&gt;
account is at a negative balance of about three cents. This post exists partly&lt;br&gt;
because that is an embarrassing ratio and partly because the interesting part is&lt;br&gt;
not the ratio — it is that the ratio is &lt;em&gt;published, checkable, and per-model&lt;/em&gt;&lt;br&gt;
rather than hidden behind a green dashboard.&lt;/p&gt;

&lt;p&gt;If you are running something similar, two checks are worth adding today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distinguish &lt;strong&gt;account-level&lt;/strong&gt; failures from &lt;strong&gt;model-level&lt;/strong&gt; failures before any
automated isolation runs. Otherwise one billing problem takes out your whole
catalogue and looks like thirteen separate bugs.&lt;/li&gt;
&lt;li&gt;Return the &lt;strong&gt;currently-available list&lt;/strong&gt; inside your error body. It costs one
join and turns every 503 into a self-healing instruction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Related: &lt;a href="https://dev.to/blog/chinese-llm-api-pricing-2026"&gt;What Chinese LLM APIs actually cost in 2026&lt;/a&gt; and&lt;br&gt;
&lt;a href="https://dev.to/blog/health-check-said-up-model-was-gone"&gt;Why your health check said "up" while the model was gone&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>api</category>
      <category>programming</category>
    </item>
    <item>
      <title>Flint-Smart: The Model That Picks the Best Model</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:29:03 +0000</pubDate>
      <link>https://dev.to/moozechen/flint-smart-the-model-that-picks-the-best-model-21nb</link>
      <guid>https://dev.to/moozechen/flint-smart-the-model-that-picks-the-best-model-21nb</guid>
      <description>&lt;h1&gt;
  
  
  Flint-Smart: The Model That Picks the Best Model
&lt;/h1&gt;

&lt;p&gt;Choosing the right AI model for every request wastes engineering time. Flint-Smart does it automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Send request with model: flint-smart&lt;/li&gt;
&lt;li&gt;FlintAPI analyzes your prompt&lt;/li&gt;
&lt;li&gt;Routes to the best model&lt;/li&gt;
&lt;li&gt;Same API, smarter backend&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;No model selection overhead&lt;/li&gt;
&lt;li&gt;Always up-to-date&lt;/li&gt;
&lt;li&gt;Cost-aware routing&lt;/li&gt;
&lt;li&gt;One key, zero decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://flintapi.ai" rel="noopener noreferrer"&gt;Try flint-smart free&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>api</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why Your AI Stack Needs a Unified API in 2026</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:28:44 +0000</pubDate>
      <link>https://dev.to/moozechen/why-your-ai-stack-needs-a-unified-api-in-2026-nod</link>
      <guid>https://dev.to/moozechen/why-your-ai-stack-needs-a-unified-api-in-2026-nod</guid>
      <description>&lt;h1&gt;
  
  
  Why Your AI Stack Needs a Unified API in 2026
&lt;/h1&gt;

&lt;p&gt;Managing 15 different AI provider accounts in 2026 is like managing 15 different bank accounts. Every provider has their own SDK, auth scheme, rate limit, and pricing model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FlintAPI solves this with one API key, a dozen models.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost
&lt;/h2&gt;

&lt;p&gt;A typical AI startup in 2026 juggles: DeepSeek for reasoning, Qwen for long context, GLM for Chinese, Kimi for coding. That is 4 API keys, 4 dashboards, 4 rate limit monitors. Engineering time spent on glue instead of product.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Endpoint, All Models
&lt;/h2&gt;

&lt;p&gt;Send requests to &lt;a href="https://flintapi.ai/v1/chat/completions" rel="noopener noreferrer"&gt;https://flintapi.ai/v1/chat/completions&lt;/a&gt;. Switch models by changing one field.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Free
&lt;/h2&gt;

&lt;p&gt;New accounts get 20 dollars free credit. No credit card.&lt;br&gt;
&lt;a href="https://flintapi.ai" rel="noopener noreferrer"&gt;Get started&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Related: &lt;a href="https://dev.to/blog/chinese-llm-api-pricing-2026"&gt;what Chinese LLM APIs actually cost per 1M tokens&lt;/a&gt;, and &lt;a href="https://dev.to/pricing"&gt;the exact prices on this site&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
      <category>startup</category>
    </item>
    <item>
      <title>DeepSeek V4 Pro on FlintAPI: Quick Start</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:28:25 +0000</pubDate>
      <link>https://dev.to/moozechen/deepseek-v4-pro-on-flintapi-quick-start-4m6i</link>
      <guid>https://dev.to/moozechen/deepseek-v4-pro-on-flintapi-quick-start-4m6i</guid>
      <description>&lt;h1&gt;
  
  
  DeepSeek V4 Pro on FlintAPI: Quick Start
&lt;/h1&gt;

&lt;p&gt;DeepSeek V4 Pro is one of the strongest reasoning models available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why DeepSeek V4 Pro
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Top-tier reasoning for math, logic, code&lt;/li&gt;
&lt;li&gt;128K context window&lt;/li&gt;
&lt;li&gt;Competitive pricing through FlintAPI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;Use the standard OpenAI-compatible endpoint with model deepseek-v4-pro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model Guide
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Best Model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;deepseek-v4-pro, kimi-k2.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chinese&lt;/td&gt;
&lt;td&gt;glm-5.1, qwen3.7-max&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long docs&lt;/td&gt;
&lt;td&gt;qwen3.7-max&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fast/cheap&lt;/td&gt;
&lt;td&gt;flint-smart&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://flintapi.ai" rel="noopener noreferrer"&gt;Get your API key&lt;/a&gt;&lt;/p&gt;

</description>
      <category>deepseek</category>
      <category>ai</category>
      <category>tutorial</category>
      <category>api</category>
    </item>
    <item>
      <title>Selling tokens below cost — what a margin audit found in our own gateway</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:25:07 +0000</pubDate>
      <link>https://dev.to/moozechen/selling-tokens-below-cost-what-a-margin-audit-found-in-our-own-gateway-2665</link>
      <guid>https://dev.to/moozechen/selling-tokens-below-cost-what-a-margin-audit-found-in-our-own-gateway-2665</guid>
      <description>&lt;p&gt;We run a small OpenAI-compatible gateway in front of Chinese LLMs. Today we did&lt;br&gt;
something uncomfortable: we took our own rate card, divided every sell price by the&lt;br&gt;
cost we pay upstream, and looked at the ratios. We expected a narrow spread. What we&lt;br&gt;
found was a range from 0.13x to 12.5x, with five models priced below cost.&lt;/p&gt;

&lt;p&gt;The worst offender was also the easiest to measure, because the upstream publishes its&lt;br&gt;
price page and we have our own usage logs.&lt;/p&gt;
&lt;h2&gt;
  
  
  The arithmetic
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;deepseek-v4-pro&lt;/code&gt; is quoted by its vendor, per 1M tokens, in USD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                        input (cache miss)   output
off-peak                        $0.66         $1.98
peak                            $1.32         $3.96
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Peak hours are 01:00–04:00 and 06:00–10:00 UTC on weekdays; everything else is&lt;br&gt;
off-peak. We were charging &lt;strong&gt;$0.98 in / $1.96 out&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then we pulled every usage row for that model from our own database — 23 rows, 800&lt;br&gt;
input tokens and 6,341 output tokens total, split by whether the request fell in peak&lt;br&gt;
hours:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;period     rows   input tok   output tok   we charged   upstream cost   margin
off-peak     10         680        6,121      $0.00647        $0.01257   -$0.00610
peak         13         120          220      $0.00030        $0.00103   -$0.00073
total        23         800        6,341      $0.00676        $0.01360   -$0.00683
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Minus 101%. We were paying roughly two dollars for every dollar we billed, and the&lt;br&gt;
sample was small enough that nobody had noticed. The input side was fine; the output&lt;br&gt;
side was underwater at every hour of the day.&lt;/p&gt;

&lt;h2&gt;
  
  
  How this happens
&lt;/h2&gt;

&lt;p&gt;Not through one bad decision. Through a series of locally reasonable ones:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The rate card was a collage.&lt;/strong&gt; Some models were priced at 1.43x cost (sane), some
at 3.3x (also fine, cheap models), some at 1.00x (no margin at all), and five below
1.0x. Each number was defensible when it was typed. Nobody ever computed the whole
column.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost drifted under a fixed price.&lt;/strong&gt; The upstream changed its price list at least
once while our sell price sat still. A price you set once is a price you are
accidentally holding against a moving cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cost field itself was untrustworthy.&lt;/strong&gt; One model's stored cost implied a 12x
markup would be needed to break even — a strong signal that the stored number was
wrong, not the price. If you multiply a bad cost by any margin, you get a confident
wrong answer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That third point is the one that generalizes. Before you reprice, audit the&lt;br&gt;
denominator.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "peak" does to a flat price
&lt;/h2&gt;

&lt;p&gt;The same model costs twice as much between 06:00 and 10:00 UTC on a weekday. A single&lt;br&gt;
flat output price therefore has to cover the peak, or it is only profitable on&lt;br&gt;
weekends. If you publish one number per model, that number is a peak-hours number and&lt;br&gt;
should be set that way — or you should say plainly that you route around the peak.&lt;/p&gt;

&lt;p&gt;We have not finished repricing. The honest status is: we know which rows are safely&lt;br&gt;
above cost, which rows are safely below, and which rows are blocked on getting a real&lt;br&gt;
bill from a supplier whose price list we do not have. Guessing the last group would&lt;br&gt;
just move the error.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four checks we now run
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ratio audit, per row.&lt;/strong&gt; &lt;code&gt;sell / cost&lt;/code&gt; for input and output, weekly. Any row below
1.25x opens a ticket; below 1.0x is an incident.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Official list prices, not memory.&lt;/strong&gt; Fetch the vendor's pricing page when auditing;
third-party comparison sites disagreed with the vendor by up to 2x in our sample.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Realized margin from your own logs, not from the rate card.&lt;/strong&gt; The rate card says
what you intended. The usage table says what happened. Split by peak/off-peak and by
cached/uncached input if the vendor bills them differently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not reprice off an unaudited cost field.&lt;/strong&gt; If the implied markup is absurd in
either direction, the cost is the suspect.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why publish this
&lt;/h2&gt;

&lt;p&gt;Because the alternative is a quiet number that quietly gets worse. A gateway is a&lt;br&gt;
margin business with a thin spread and a moving denominator; the failure mode is not a&lt;br&gt;
crash, it is a ratio. And because a price article without a date is a rumour — so the&lt;br&gt;
numbers above are dated 2026-10-28, and the live model list is at&lt;br&gt;
&lt;a href="https://flintapi.ai/api/health/models" rel="noopener noreferrer"&gt;&lt;code&gt;/api/health/models&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are running something similar: pull one week of usage, join it to your cost&lt;br&gt;
table, and compute the ratio per row. It takes twenty minutes and it is the most&lt;br&gt;
uncomfortable twenty minutes of the quarter.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Related: &lt;a href="https://dev.to/blog/chinese-llm-api-pricing-2026"&gt;What Chinese LLM APIs actually cost in 2026&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>startup</category>
      <category>programming</category>
    </item>
    <item>
      <title>What Chinese LLM APIs actually cost in 2026 (measured per 1M tokens)</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:24:54 +0000</pubDate>
      <link>https://dev.to/moozechen/what-chinese-llm-apis-actually-cost-in-2026-measured-per-1m-tokens-1l8k</link>
      <guid>https://dev.to/moozechen/what-chinese-llm-apis-actually-cost-in-2026-measured-per-1m-tokens-1l8k</guid>
      <description>&lt;p&gt;Prices for Chinese LLM APIs are quoted per million tokens, which is the least useful unit if you have never billed a request. A $0.01 model and a $2.45 model are not two points on one line: they are two different products, and the cheap one usually fails differently.&lt;/p&gt;

&lt;p&gt;This is the table we measured on 2026-10-28 across the models our gateway serves. Every number below is the charged rate, per 1M tokens, in USD.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model                       input / 1M    output / 1M
doubao-seed-2-0-lite          $0.0100        $0.0300
doubao-seed-2-0-pro           $0.0100        $0.0400
doubao-seed-2-1-pro           $0.0120        $0.0500
glm-5.3-flash                 $0.0686        $0.2400
deepseek-v4.1-flash           $0.1286        $0.5143
glm-5.3                       $0.1500        $0.6000
qwen3.7-plus                  $0.3300        $1.3100
deepseek-v4-pro               $0.9800        $1.9600
kimi-k2.7-code                $1.0600        $4.4100
deepseek-v4-pro-thinking      $1.2000        $2.4000
kimi-k3                       $2.0000        $1.3400
qwen3.7-max                   $2.4500        $7.3500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two rows deserve a second look, because they break the assumption that output costs more than input.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kimi-k3&lt;/code&gt; charges $2.00 in and $1.34 out. &lt;code&gt;deepseek-v4-pro-thinking&lt;/code&gt; charges $1.20 in and $2.40 out. If you estimate cost by multiplying input price by total tokens, you will be wrong on both, in opposite directions.&lt;/p&gt;

&lt;h2&gt;
  
  
  List price is not your bill
&lt;/h2&gt;

&lt;p&gt;A price table multiplies tokens by rate. Your bill also depends on three things the table cannot show you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cached input.&lt;/strong&gt; Some providers charge a fraction of list for a repeated prefix. A long system prompt that is billed once instead of forty times changes the arithmetic more than switching models does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reasoning tokens.&lt;/strong&gt; A reasoning model can emit thousands of internal tokens before it writes anything. They are billed, they are not in your output, and they are the reason "why did this one-shot query cost ten times what I expected" has an answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Failures.&lt;/strong&gt; A request that returns 200 with an empty &lt;code&gt;choices[0].message.content&lt;/code&gt; still costs whatever was generated. In an early version of our own gateway we billed it as zero, and our margin silently inflated, because the only thing we counted was the response body.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one line that shows your real number
&lt;/h2&gt;

&lt;p&gt;Ask the API, not the pricing page. On an OpenAI-compatible endpoint, the response usually carries usage:&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;-s&lt;/span&gt; https://flintapi.ai/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 &lt;/span&gt;&lt;span class="nv"&gt;$FLINT_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;-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":"deepseek-v4.1-flash","messages":[{"role":"user","content":"Say OK"}],"max_tokens":64}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'import json,sys; d=json.load(sys.stdin); print(d.get("usage"))'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;usage&lt;/code&gt; comes back &lt;code&gt;null&lt;/code&gt;, that provider is not telling you what it charged, and no price table will save you. This is not hypothetical: it is one of the first things we had to fix, because a gateway that cannot report usage cannot be audited by its own customer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually decides your monthly cost
&lt;/h2&gt;

&lt;p&gt;Not the per-token price. These three, in this order.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Which model you call by default.&lt;/strong&gt; The gap between the cheapest and the most expensive row above is 245× on input. Nothing else you can change in one afternoon moves the number that much.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How much you send in the prompt.&lt;/strong&gt; At $0.01/1M input, a 50,000-token context costs half a cent. At $2.45/1M it costs twelve cents. Same prompt, different order of magnitude.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How often you retry.&lt;/strong&gt; A retry loop against a model that times out under load doubles your spend and gives you nothing to show for it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is the argument for routing rather than picking: the right model is per-request, not per-company. If the cheap model answers your classification step correctly, paying 245× for the expensive one is not caution, it is waste. And when the cheap one fails the check, you want the fallback in the same request, not in a retry you wrote yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to read this table honestly
&lt;/h2&gt;

&lt;p&gt;These are the rates we charged on 2026-10-28: a dated snapshot of our own rate card, not an advertisement. They move, and they move without notice when a provider reprices, so the table above is dated on purpose — a price article without a date is a rumour. We do not currently publish a live per-model price endpoint: &lt;code&gt;GET /api/health/models&lt;/code&gt; tells you which models are serving right now (no prices), and &lt;code&gt;/pricing&lt;/code&gt; covers our consulting product only. For the current rate card, mail &lt;a href="mailto:support@flintapi.ai"&gt;support@flintapi.ai&lt;/a&gt; and you will get today's numbers.&lt;/p&gt;

&lt;p&gt;If you want the current numbers:&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;-s&lt;/span&gt; https://flintapi.ai/v1/models | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-40&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you want to know what a specific prompt costs before you send it, run it once with a small &lt;code&gt;max_tokens&lt;/code&gt; and read &lt;code&gt;usage&lt;/code&gt; from the response. That number is the only one that is about you.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Related: &lt;a href="https://dev.to/blog/why-unified-ai-api"&gt;How one API key covers twelve Chinese models&lt;/a&gt;, and &lt;a href="https://dev.to/blog/what-breaks-chinese-llm-gateway"&gt;what actually broke when we put four providers behind one endpoint&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>api</category>
      <category>pricing</category>
    </item>
    <item>
      <title>The character limit that silently killed our AI replies</title>
      <dc:creator>Yucong Chen</dc:creator>
      <pubDate>Tue, 27 Oct 2026 07:19:31 +0000</pubDate>
      <link>https://dev.to/moozechen/the-character-limit-that-silently-killed-our-ai-replies-2nek</link>
      <guid>https://dev.to/moozechen/the-character-limit-that-silently-killed-our-ai-replies-2nek</guid>
      <description>&lt;p&gt;A customer asked us a normal question. They got a reply that looked like a form letter.&lt;/p&gt;

&lt;p&gt;It was polite. It was fast. It was completely useless. And nobody got an alert, because nothing failed in a way that looked like failing.&lt;/p&gt;

&lt;p&gt;That is the kind of bug I want to talk about.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we thought was happening
&lt;/h2&gt;

&lt;p&gt;We have an internal helper that answers support mail. The idea is simple. Take the incoming question, add our own notes about the product, ask a model, send the answer.&lt;/p&gt;

&lt;p&gt;The notes are not huge. About a page of text. We appended them to every prompt because it was easy, and because the model seemed happier with context.&lt;/p&gt;

&lt;p&gt;For a while it worked. Then replies started degrading in a way nobody could name. Less specific. More filler. Shorter.&lt;/p&gt;

&lt;p&gt;We blamed the model at first. Then we blamed the prompt. Both were wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  What was actually happening
&lt;/h2&gt;

&lt;p&gt;Our consulting endpoint validates the incoming message length. There is a cap: 3000 characters. Anything longer is rejected before it reaches a model.&lt;/p&gt;

&lt;p&gt;Our helper never saw the rejection as a rejection. The call came back as HTTP 400, the code treated anything that was not a success as "provider unavailable", and the fallback fired. The fallback is a friendly template. So the customer got a template, and our logs got one quiet line.&lt;/p&gt;

&lt;p&gt;The annoying part is that HTTP 400 is not an outage. It is the server telling you the request was wrong. We read it as bad luck and tried again.&lt;/p&gt;

&lt;p&gt;We found it by replaying the customer's own message through the helper. That took about a minute. What took days was not believing the evidence, because the logs said the reply had been sent, and it had. It was just the wrong reply.&lt;/p&gt;

&lt;p&gt;If you want the shortest version of this story: our monitoring watched the wrong layer. The prompt assembly was broken, the transport was fine, and we were staring at the transport.&lt;/p&gt;

&lt;p&gt;Nobody reads the quiet line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this one took so long to find
&lt;/h2&gt;

&lt;p&gt;Three things lined up badly.&lt;/p&gt;

&lt;p&gt;The failure was silent by design. We had built a fallback so that users never see a raw error. That is usually a good instinct. Here it meant the symptom and the cause lived in different places.&lt;/p&gt;

&lt;p&gt;The error was classified wrong. A length check returning a client error is not the same as a provider being down. Ours went into the same bucket, so the retry logic kept retrying something that could never succeed.&lt;/p&gt;

&lt;p&gt;And the input was only sometimes too long. Short questions passed. Long ones with pasted logs did not. So it looked random, and random makes people guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we changed
&lt;/h2&gt;

&lt;p&gt;The validation error now has its own name in our code, and it does not retry. Retrying a too-long message is just spending money to fail again.&lt;/p&gt;

&lt;p&gt;We also log the actual length of the message, next to the cap. That one number would have ended the investigation on day one.&lt;/p&gt;

&lt;p&gt;And the fallback stopped being silent. When the fallback fires, it says so. A template that pretends to be an answer is worse than an error, tbh.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I am still thinking about
&lt;/h2&gt;

&lt;p&gt;We removed the whole-document paste, which fixed the immediate problem. But the underlying shape is still there. Any time we add context to a prompt, we are spending a budget we do not measure.&lt;/p&gt;

&lt;p&gt;So now we trim the notes per question, and we check the assembled size before sending. It is a few lines of code. It should have been there from the start.&lt;/p&gt;

&lt;p&gt;If you run a helper like this, I would check one thing today. When your fallback fires, does anything actually tell you?&lt;/p&gt;

&lt;p&gt;I think most of us have a template quietly answering for us right now, and we just do not know it yet.&lt;/p&gt;

&lt;p&gt;If you want the token budget and the trimming rules we settled on, &lt;a href="https://flintapi.ai/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=art03-character-limit-replies" rel="noopener noreferrer"&gt;they're here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>python</category>
      <category>api</category>
    </item>
  </channel>
</rss>
