<?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: Erika</title>
    <description>The latest articles on DEV Community by Erika (@erika_minamitsu).</description>
    <link>https://dev.to/erika_minamitsu</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%2F4102644%2Fc579ee60-9a69-4826-9acf-764d4ad921c8.jpg</url>
      <title>DEV Community: Erika</title>
      <link>https://dev.to/erika_minamitsu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/erika_minamitsu"/>
    <language>en</language>
    <item>
      <title>I Tried 5 Free LLM APIs With One Python Script</title>
      <dc:creator>Erika</dc:creator>
      <pubDate>Mon, 31 Aug 2026 11:31:04 +0000</pubDate>
      <link>https://dev.to/erika_minamitsu/i-tried-5-free-llm-apis-with-one-python-script-1p1j</link>
      <guid>https://dev.to/erika_minamitsu/i-tried-5-free-llm-apis-with-one-python-script-1p1j</guid>
      <description>&lt;p&gt;I wanted to find a free LLM API for small tools and experiments.&lt;/p&gt;

&lt;p&gt;There are many lists online, but free plans change often. Some model names and&lt;br&gt;
limits were already old when I checked them. So I opened new accounts and tried&lt;br&gt;
five providers myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Groq&lt;/li&gt;
&lt;li&gt;Google AI Studio&lt;/li&gt;
&lt;li&gt;OpenRouter&lt;/li&gt;
&lt;li&gt;Cloudflare Workers AI&lt;/li&gt;
&lt;li&gt;Token Harbor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I did not add a credit card to any account. I used the same Python script and&lt;br&gt;
the same two tasks as much as possible.&lt;/p&gt;

&lt;p&gt;One disclosure: I work with Token Harbor. To keep the comparison fair, I used&lt;br&gt;
the same test method for all five providers. I also kept failed requests and&lt;br&gt;
problems in the results. This includes the weak points of Token Harbor.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider and model&lt;/th&gt;
&lt;th&gt;Setup&lt;/th&gt;
&lt;th&gt;Free limit in my test&lt;/th&gt;
&lt;th&gt;Coding task&lt;/th&gt;
&lt;th&gt;Context test&lt;/th&gt;
&lt;th&gt;Main problem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Groq&lt;/strong&gt; — &lt;code&gt;qwen/qwen3.8-27b&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1–2 min&lt;/td&gt;
&lt;td&gt;30 RPM, 1K RPD, 8K TPM, 2M TPD&lt;/td&gt;
&lt;td&gt;Passed in 1.85s&lt;/td&gt;
&lt;td&gt;7,521 input tokens passed in 2.13s&lt;/td&gt;
&lt;td&gt;8K TPM limits the size of one request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Google AI Studio&lt;/strong&gt; — &lt;code&gt;gemini-3.5-flash-lite&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;3–4 min&lt;/td&gt;
&lt;td&gt;15 RPM, 250K input TPM, 500 RPD&lt;/td&gt;
&lt;td&gt;Passed in 6.54s&lt;/td&gt;
&lt;td&gt;First request failed; 84,424-token retry passed in 24.35s&lt;/td&gt;
&lt;td&gt;One temporary 503 error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;OpenRouter&lt;/strong&gt; — &lt;code&gt;poolside/laguna-s-2.1:free&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;A few minutes&lt;/td&gt;
&lt;td&gt;50 free requests per day&lt;/td&gt;
&lt;td&gt;First request got 429; retry passed&lt;/td&gt;
&lt;td&gt;First request got 429; 80,464-token retry passed in 9.35s&lt;/td&gt;
&lt;td&gt;Shared free pool was busy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Cloudflare Workers AI&lt;/strong&gt; — &lt;code&gt;@cf/google/gemma-4-26b-a4b-it&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Longest&lt;/td&gt;
&lt;td&gt;10K neurons per day&lt;/td&gt;
&lt;td&gt;Returned JSON, but code had one edge-case bug&lt;/td&gt;
&lt;td&gt;20K words failed; 42,268-token smaller test passed in 5.93s&lt;/td&gt;
&lt;td&gt;Setup was harder and long calls disconnected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Token Harbor&lt;/strong&gt; — &lt;code&gt;deepseek-v4-flash:free&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1–2 min&lt;/td&gt;
&lt;td&gt;Rolling 7-day value allowance&lt;/td&gt;
&lt;td&gt;Passed in 1.84s&lt;/td&gt;
&lt;td&gt;63,887 input tokens passed in 34.62s&lt;/td&gt;
&lt;td&gt;Dashboard shows a percentage, not an exact cap&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These results are from August 28–29, 2026. They are only a snapshot. Free plans&lt;br&gt;
and models can change.&lt;/p&gt;
&lt;h2&gt;
  
  
  Test method
&lt;/h2&gt;

&lt;p&gt;I used two small tests. My goal was not to make a full model benchmark. I only&lt;br&gt;
wanted to check if the API was really usable.&lt;/p&gt;
&lt;h3&gt;
  
  
  Test 1: Python debugging
&lt;/h3&gt;

&lt;p&gt;I gave each model a short Python function with several bugs. The model had to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;remove a mutable default argument;&lt;/li&gt;
&lt;li&gt;ignore duplicate order IDs;&lt;/li&gt;
&lt;li&gt;exclude cancelled orders;&lt;/li&gt;
&lt;li&gt;return the correct count and total;&lt;/li&gt;
&lt;li&gt;return the answer as JSON.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I checked both the JSON format and the corrected code.&lt;/p&gt;
&lt;h3&gt;
  
  
  Test 2: long-context retrieval
&lt;/h3&gt;

&lt;p&gt;The script created a synthetic incident log. I placed three exact values near&lt;br&gt;
the start, middle, and end. The model had to find all three values and return&lt;br&gt;
them as JSON.&lt;/p&gt;

&lt;p&gt;The normal test was about 20,000 words. I used a smaller input for Groq because&lt;br&gt;
its free plan had an 8K TPM limit. I also reduced the Cloudflare test after the&lt;br&gt;
20K-word requests failed.&lt;/p&gt;

&lt;p&gt;I turned off automatic SDK retries. If I retried by hand, I saved both the&lt;br&gt;
failed request and the successful request.&lt;/p&gt;

&lt;p&gt;All requests used the same local HTTP proxy from APAC. The latency may be&lt;br&gt;
different in another region.&lt;/p&gt;

&lt;p&gt;The basic request looked like this:&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="n"&gt;API_KEY&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="n"&gt;PROVIDER_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;response&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="n"&gt;MODEL_ID&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="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&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;max_completion_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3000&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;All five providers supported an OpenAI-style Chat Completions request. Cloudflare&lt;br&gt;
also needed an Account ID in the base URL.&lt;/p&gt;
&lt;h2&gt;
  
  
  Groq
&lt;/h2&gt;

&lt;p&gt;Groq was the easiest provider to start using. I signed in with Google and made&lt;br&gt;
an API key. I did not need another email verification step or a credit card.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;qwen/qwen3.8-27b&lt;/code&gt;, my account showed these limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;30 requests per minute&lt;/li&gt;
&lt;li&gt;1,000 requests per day&lt;/li&gt;
&lt;li&gt;8,000 tokens per minute&lt;/li&gt;
&lt;li&gt;2,000,000 tokens per day&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The daily limit is large, but the per-minute token limit is much smaller. This&lt;br&gt;
means I could not send the normal 20K-word test in one request.&lt;/p&gt;

&lt;p&gt;I used a smaller prompt with 7,521 input tokens. The model found all three&lt;br&gt;
values in 2.13 seconds. The coding task also returned correct code in 1.85&lt;br&gt;
seconds. One sentence in its bug explanation was not correct, but the fixed&lt;br&gt;
function worked.&lt;/p&gt;

&lt;p&gt;Groq was the best fit for short and fast requests in this test. For large&lt;br&gt;
prompts, it is important to check TPM and not only TPD.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://console.groq.com/docs/rate-limits" rel="noopener noreferrer"&gt;Groq rate limits&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Google AI Studio
&lt;/h2&gt;

&lt;p&gt;Google AI Studio took about three or four minutes to set up. I signed in with&lt;br&gt;
Google, created a project, and generated an API key. It did not require a card.&lt;/p&gt;

&lt;p&gt;My project showed 15 RPM, 250K input TPM, and 500 RPD for&lt;br&gt;
&lt;code&gt;gemini-3.5-flash-lite&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The coding task passed in 6.54 seconds. The code was correct, but one sentence&lt;br&gt;
in the explanation was wrong.&lt;/p&gt;

&lt;p&gt;The first long-context request failed with HTTP 503 &lt;code&gt;UNAVAILABLE&lt;/code&gt;. I tried again&lt;br&gt;
about one minute later. The second request passed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;84,424 input tokens&lt;/li&gt;
&lt;li&gt;67 output tokens&lt;/li&gt;
&lt;li&gt;24.35 seconds&lt;/li&gt;
&lt;li&gt;all three values were correct&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found one difference in Google's usage numbers. The API response reported&lt;br&gt;
84,424 prompt tokens, but the rate-limit page showed a 64.72K TPM peak. I kept&lt;br&gt;
both numbers in my notes because they may use different accounting methods.&lt;/p&gt;

&lt;p&gt;Google's terms for unpaid Gemini API services also need attention. Content may&lt;br&gt;
be used to improve Google products, and the rules can be different by region. I&lt;br&gt;
only used synthetic data in this test.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ai.google.dev/gemini-api/docs/rate-limits" rel="noopener noreferrer"&gt;Gemini API rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai.google.dev/gemini-api/terms" rel="noopener noreferrer"&gt;Gemini API terms&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  OpenRouter
&lt;/h2&gt;

&lt;p&gt;OpenRouter did not require a credit card or another email verification step.&lt;br&gt;
There were some signup questions, and it showed an option to add a card. I could&lt;br&gt;
skip it.&lt;/p&gt;

&lt;p&gt;I used &lt;code&gt;poolside/laguna-s-2.1:free&lt;/code&gt;. I chose a fixed model instead of the&lt;br&gt;
&lt;code&gt;openrouter/free&lt;/code&gt; router because I wanted to test the same model again on a&lt;br&gt;
retry.&lt;/p&gt;

&lt;p&gt;The first coding request returned 429. The first long-context request also&lt;br&gt;
returned 429. Both errors came from the shared upstream free pool. They were not&lt;br&gt;
caused by using all 50 daily requests.&lt;/p&gt;

&lt;p&gt;Both manual retries worked. The long-context retry used 80,464 input tokens,&lt;br&gt;
finished in 9.35 seconds, and found all three values.&lt;/p&gt;

&lt;p&gt;The OpenRouter Dashboard showed two successful requests, about 81.1K tokens,&lt;br&gt;
and $0.00 spend. However, I could not find a simple counter showing how many of&lt;br&gt;
the 50 daily free requests were still available.&lt;/p&gt;

&lt;p&gt;OpenRouter is useful for trying many free models with one API. I would still add&lt;br&gt;
retry logic because the shared free pool can be busy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://openrouter.ai/docs/faq" rel="noopener noreferrer"&gt;OpenRouter free-model limits&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Cloudflare Workers AI
&lt;/h2&gt;

&lt;p&gt;Cloudflare did not require a card, but the setup was harder for me. I had to&lt;br&gt;
find the Workers AI REST API page, create a scoped API token, and copy the&lt;br&gt;
Account ID. This was different from a normal API-key page.&lt;/p&gt;

&lt;p&gt;The first coding request used all 3,000 output tokens for model thinking and&lt;br&gt;
returned no visible answer. Cloudflare's example for this Gemma model showed&lt;br&gt;
how to turn thinking off:&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;extra_body&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;chat_template_kwargs&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;enable_thinking&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&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;After this change, the model returned valid JSON in 4.32 seconds. It used 10.82&lt;br&gt;
neurons. The answer was close, but the fixed function missed one edge case. A&lt;br&gt;
cancelled order ID could be accepted later if the same ID appeared again.&lt;/p&gt;

&lt;p&gt;The long-context test had another problem. Three 20K-word requests failed before&lt;br&gt;
the client received an answer. Two connections stayed open for about 120 and&lt;br&gt;
111 seconds. The third failed during TLS after 3.48 seconds.&lt;/p&gt;

&lt;p&gt;I reduced the prompt to about 10,000 words. This request passed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;42,268 input tokens&lt;/li&gt;
&lt;li&gt;54 output tokens&lt;/li&gt;
&lt;li&gt;5.93 seconds&lt;/li&gt;
&lt;li&gt;all three values were correct&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Dashboard later showed 2.02K of the daily 10K neurons used. Successful&lt;br&gt;
responses explained only about 482 neurons. The remaining amount was close to&lt;br&gt;
the estimated input cost of the two long requests that disconnected after about&lt;br&gt;
two minutes.&lt;/p&gt;

&lt;p&gt;This suggests that Cloudflare processed and counted those requests even though&lt;br&gt;
my client did not receive the answers. This is only an estimate from the total&lt;br&gt;
Dashboard usage. I cannot say if Cloudflare, the proxy, or another network part&lt;br&gt;
caused the disconnects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.cloudflare.com/workers-ai/platform/pricing/" rel="noopener noreferrer"&gt;Workers AI pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.cloudflare.com/workers-ai/models/gemma-4-26b-a4b-it/" rel="noopener noreferrer"&gt;Gemma model page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Token Harbor
&lt;/h2&gt;

&lt;p&gt;Token Harbor took about two minutes to set up. I registered, verified my email,&lt;br&gt;
and generated an API key. It did not require a card.&lt;/p&gt;

&lt;p&gt;I tested &lt;code&gt;deepseek-v4-flash:free&lt;/code&gt;. The coding task passed in 1.84 seconds. The&lt;br&gt;
normal long-context request also passed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;20,075 words&lt;/li&gt;
&lt;li&gt;63,887 input tokens&lt;/li&gt;
&lt;li&gt;293 output tokens&lt;/li&gt;
&lt;li&gt;34.62 seconds&lt;/li&gt;
&lt;li&gt;all three values were correct&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The free limit is different from the other providers. It is a value-based&lt;br&gt;
allowance with a personal rolling seven-day period. The Dashboard shows the&lt;br&gt;
used percentage, but it does not show a fixed token number.&lt;/p&gt;

&lt;p&gt;About 70K tokens moved the meter from 0% to 4%. A simple estimate gives around&lt;br&gt;
1.5 to 2 million similar DeepSeek tokens for one period. This is not an official&lt;br&gt;
limit. The Dashboard percentage is rounded, and another model may use the&lt;br&gt;
value-based allowance at a different rate.&lt;/p&gt;

&lt;p&gt;Permanent free routes are opt-in. Token Harbor may retain prompts and responses&lt;br&gt;
sent through these routes. Paid routes use a different zero-retention policy. I&lt;br&gt;
would not send private code or customer data through the free route.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tokenharbor.ai/faq" rel="noopener noreferrer"&gt;Token Harbor free-access rules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.tokenharbor.ai/terms" rel="noopener noreferrer"&gt;Token Harbor terms&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My final view
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Need&lt;/th&gt;
&lt;th&gt;My choice from this test&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Short and fast requests&lt;/td&gt;
&lt;td&gt;Groq&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A large free request with clear project limits&lt;/td&gt;
&lt;td&gt;Google AI Studio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Many models through one API&lt;/td&gt;
&lt;td&gt;OpenRouter, with retry logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Existing Cloudflare project&lt;/td&gt;
&lt;td&gt;Workers AI, after learning its setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rolling allowance without a separate TPM limit&lt;/td&gt;
&lt;td&gt;Token Harbor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All five APIs worked without a credit card. They were good enough for testing,&lt;br&gt;
personal tools, and low-volume automation.&lt;/p&gt;

&lt;p&gt;I would not depend on a free endpoint alone for a user-facing product. Google&lt;br&gt;
returned one 503. OpenRouter returned two shared-pool 429 errors. Cloudflare's&lt;br&gt;
long requests disconnected, and some of that work appeared in the usage meter.&lt;/p&gt;

&lt;p&gt;There was also a model-quality issue. Four providers returned functionally&lt;br&gt;
correct Python fixes, but three of those answers included at least one wrong&lt;br&gt;
explanation. Cloudflare returned valid JSON, but its code still had one edge-case&lt;br&gt;
bug.&lt;/p&gt;

&lt;p&gt;For me, a free API still needs timeouts, retry rules, logs, and a paid fallback.&lt;br&gt;
The quota number alone is not enough to choose a provider.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I used synthetic prompts only. Limits and available models may change, so&lt;br&gt;
please check the official pages before using them. I used AI to help organize&lt;br&gt;
and edit this article. I checked the final numbers against my saved test files.&lt;/em&gt;&lt;/p&gt;

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