<?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: hopbase</title>
    <description>The latest articles on DEV Community by hopbase (@hopbase).</description>
    <link>https://dev.to/hopbase</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%2F4143352%2Fab24b36c-c79f-4506-b9f8-80d9bd5892ae.jpg</url>
      <title>DEV Community: hopbase</title>
      <link>https://dev.to/hopbase</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hopbase"/>
    <language>en</language>
    <item>
      <title>How to Reconcile LLM API Usage and Allocate Costs by Department: A Reproducible Method</title>
      <dc:creator>hopbase</dc:creator>
      <pubDate>Wed, 28 Oct 2026 18:42:25 +0000</pubDate>
      <link>https://dev.to/hopbase/how-to-reconcile-llm-api-usage-and-allocate-costs-by-department-a-reproducible-method-1nhj</link>
      <guid>https://dev.to/hopbase/how-to-reconcile-llm-api-usage-and-allocate-costs-by-department-a-reproducible-method-1nhj</guid>
      <description>&lt;p&gt;&lt;strong&gt;The short answer: reconciling an LLM API bill takes three layers of data you can recompute yourself, not a vendor's promise of "transparent billing". Layer one is the individual task: on HopBase, once a video or asynchronous image task finishes, its query response carries &lt;code&gt;usage.cost_usd&lt;/code&gt;, the amount actually deducted from your balance for that task; an uncharged failure reports 0, and one curl command checks it. Layer two is the itemised record: the console Usage page exports a CSV filtered by date, key, member, department or key creator, and every row carries the official cost, discount, exchange rate and charged amount to verify official cost × discount ÷ exchange rate = charged amount line by line. Layer three is allocation: every key shows its creator, per-key spending charts exist, department managers see and manage their own department's keys and usage, and quotas can be set per key, member and department. With all three in place, a department chargeback is just a filter and an export.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why LLM bills are hard to reconcile
&lt;/h2&gt;

&lt;p&gt;A company that runs chat, image and video models at the same time deals with at least four billing units: tokens for chat, images for most image models, seconds or video tokens for video, and flat per-call fees for a few others. Add a handful of practical problems and the numbers stop lining up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous tasks are priced when they end.&lt;/strong&gt; A video submission only carries an estimate; the real charge is known once the task finishes, and vendors differ on whether and how much a failed task costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failed requests.&lt;/strong&gt; A failed request is normally free, but when the client disconnects after output has already been generated, the generated part is usually billed. If the bill does not say so, you get the classic "it errored and I was still charged" dispute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Currencies.&lt;/strong&gt; Official list prices are mostly in US dollars while the account balance may be kept in another currency. Without the exchange rate in between, nobody can recompute the charge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared keys.&lt;/strong&gt; Once several projects share one key, nobody can tell afterwards who spent what.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the goal is concrete: &lt;strong&gt;every charge should trace back to a task or request, a key, the person who created that key and a department, and the amount should be recomputable from published list prices.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: the actual charge, straight from the task query
&lt;/h2&gt;

&lt;p&gt;Once an asynchronous task (video, async image and so on) is completed, failed or cancelled, the single-task query response gains a top-level &lt;code&gt;usage&lt;/code&gt; object:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;usage.cost_usd&lt;/code&gt; is the amount &lt;strong&gt;actually deducted&lt;/strong&gt; from your USD balance for that task — the same number as in the usage record;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;usage.cost&lt;/code&gt; is the same charge expressed in CNY, and &lt;code&gt;usage.currency&lt;/code&gt; names the currency of &lt;code&gt;cost&lt;/code&gt; (always &lt;code&gt;CNY&lt;/code&gt;) — reconcile against &lt;code&gt;cost_usd&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;a failed task that was not charged reports &lt;code&gt;0&lt;/code&gt;; in the rare case an image task fails after its charge was settled (for example, the model returned no usable image), it reports the real charge;&lt;/li&gt;
&lt;li&gt;the field is absent while the task is running, and &lt;strong&gt;only the key that created the task&lt;/strong&gt; sees it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It applies to &lt;code&gt;GET /v1/video/tasks/{task_id}&lt;/code&gt; (Seedance, Grok Imagine, Kling, MiniMax, Midjourney), &lt;code&gt;GET /api/v1/tasks/{task_id}&lt;/code&gt; (Wan, HappyHorse) and &lt;code&gt;GET /v1/images/tasks?task_id=...&lt;/code&gt; (GPT Image and Gemini image async tasks). Checking it takes one command:&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="c"&gt;# Query with the key that submitted the task; jq keeps only status and cost&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.hop-base.com/v1/video/tasks/&lt;span class="nv"&gt;$TASK_ID&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;$HOPBASE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="s1"&gt;'{status: (.task.status // .status), usage}'&lt;/span&gt;

&lt;span class="c"&gt;# Once the task has finished you get something like (amount illustrative):&lt;/span&gt;
&lt;span class="c"&gt;# { "status": "completed", "usage": { "cost_usd": 0.35, "cost": 2.4, "currency": "CNY" } }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a Seedance response, &lt;code&gt;task.usage&lt;/code&gt; is the billable token count and the top-level &lt;code&gt;usage.cost_usd&lt;/code&gt; is the money — do not mix them up. For MiniMax and Wan, which already return a top-level &lt;code&gt;usage&lt;/code&gt;, &lt;code&gt;cost_usd&lt;/code&gt;, &lt;code&gt;cost&lt;/code&gt; and &lt;code&gt;currency&lt;/code&gt; are merged into it. The practical benefit: &lt;strong&gt;your own system can write the real charge into its order or job record the moment the task ends&lt;/strong&gt;, instead of polling the console or booking the submission estimate as cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: itemised records you can recompute row by row
&lt;/h2&gt;

&lt;p&gt;Synchronous chat requests create no task and their responses carry token counts only, so the money lives in the usage records. The export button on the console Usage page downloads a CSV that &lt;strong&gt;follows the filters on the page&lt;/strong&gt; (date range, key, member, department, key creator), up to 50,000 rows and 400 days per file. Each row has nine columns:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; time, model, usage;&lt;/li&gt;
&lt;li&gt; official list-price currency, official cost in that currency;&lt;/li&gt;
&lt;li&gt; discount, exchange rate, charged amount in the balance currency;&lt;/li&gt;
&lt;li&gt; note.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Read left to right, four of those columns are the verification formula itself: &lt;strong&gt;official cost × discount ÷ exchange rate = charged amount&lt;/strong&gt;. When the list-price currency and the balance currency are the same, the exchange-rate cell is empty and the formula becomes official cost × discount = charged amount. You can compute the official cost from the vendor's own price page, and the discount is the one on your account, so every row can be checked independently without trusting anyone's totals. Early records without a list-price snapshot leave those columns empty.&lt;/p&gt;

&lt;p&gt;Failed requests are noted as "Request failed, not charged"; a request interrupted after output was generated is noted as "Request interrupted, charged for the usage already generated", and the end of the file counts both. Those are exactly the rows that cause disputes, so stating the rule in the record beats explaining it afterwards. For automation, &lt;code&gt;GET /v1/usage&lt;/code&gt; with an API key returns the balance and that key's quota usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: allocating by key and by department
&lt;/h2&gt;

&lt;p&gt;Allocation starts with one key per cost centre. HopBase enterprise accounts have members and departments, and a few facts decide whether allocation actually works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Every key shows its creator.&lt;/strong&gt; Keys a member created and keys the owner or a department manager created and assigned to a member stay distinguishable, and exports can filter by creator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spending charts per key.&lt;/strong&gt; The console shows spending trend, request count and model mix per key, so unusual spend points straight at a key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Department manager scope.&lt;/strong&gt; A department manager sees and manages the keys and usage of members in their own department, can create keys for those members, and cannot see other departments. The owner sees the whole company. When a member moves department, the scope follows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layered quotas.&lt;/strong&gt; Quotas can be set per key, per member and per department, and hitting any of them blocks the request with a 402 whose message says whether the key, member or department quota ran out — not a vague "insufficient balance".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A monthly department chargeback is then: pick the department and the month on the Usage page, export. Each department gets its own itemised file and can recompute it with the formula above.&lt;/p&gt;

&lt;h2&gt;
  
  
  A reconciliation checklist you can use on any vendor
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; After an async task ends, can you get its &lt;strong&gt;actual charge&lt;/strong&gt; from the API — not an estimate or a base cost?&lt;/li&gt;
&lt;li&gt; Can you export itemised records with official cost, discount and exchange rate, and &lt;strong&gt;recompute each row&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt; Are failed requests and "interrupted after output was generated" requests &lt;strong&gt;labelled separately&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt; Does every amount state its currency, and is the exchange rate visible when list-price and balance currencies differ?&lt;/li&gt;
&lt;li&gt; Can you filter exports by key, member and department, and does each key record its creator?&lt;/li&gt;
&lt;li&gt; Can quotas be layered, and does a quota error tell you which layer ran out?&lt;/li&gt;
&lt;li&gt; Are you actually getting the model you pay for? Test that yourself with our &lt;a href="https://hop-base.com/blog/verify-your-llm-api-provider" rel="noopener noreferrer"&gt;model fidelity verification method&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every item can be checked with curl or an export file, which makes the list usable against any vendor — including us.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is usage.cost_usd in the task query the same as the charged amount in the console?
&lt;/h3&gt;

&lt;p&gt;Yes. &lt;code&gt;usage.cost_usd&lt;/code&gt; is the charged amount from that task's usage record — the amount by which your balance actually went down — so you can match it one-to-one against the exported records.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is there no usage.cost_usd while the task is still running?
&lt;/h3&gt;

&lt;p&gt;The final charge of an async task is only known when it ends; any number returned earlier could only be an estimate. The field therefore appears once the task is completed, failed or cancelled. While it runs, keep polling as before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are failed tasks charged?
&lt;/h3&gt;

&lt;p&gt;Failed video tasks are never charged, and the query reports &lt;code&gt;usage.cost_usd&lt;/code&gt; as 0. In rare cases an image task fails after its charge was settled; the query then reports the real charge, and the same amount appears in your usage records. Failed synchronous requests are free; a request interrupted after output was generated is charged for what was generated and labelled as such in the export.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does another key not see the cost of my task?
&lt;/h3&gt;

&lt;p&gt;The cost is returned only to the key that created the task. That keeps the "one key per cost centre" boundary intact and stops other keys on the same account from seeing spend that is not theirs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do chat requests have a per-request amount too?
&lt;/h3&gt;

&lt;p&gt;Chat responses carry token counts but no amount. The per-request amount is in the console usage records, the CSV export lets you recompute each row, and filtering plus export gives you totals per key or department.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://hop-base.com/blog/ai-api-usage-reconciliation-chargeback" rel="noopener noreferrer"&gt;HopBase blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
      <category>finops</category>
    </item>
    <item>
      <title>How to Benchmark LLM API Performance: TTFT, Streaming Stability, and a Reproducible Method</title>
      <dc:creator>hopbase</dc:creator>
      <pubDate>Wed, 28 Oct 2026 18:38:23 +0000</pubDate>
      <link>https://dev.to/hopbase/how-to-benchmark-llm-api-performance-ttft-streaming-stability-and-a-reproducible-method-518d</link>
      <guid>https://dev.to/hopbase/how-to-benchmark-llm-api-performance-ttft-streaming-stability-and-a-reproducible-method-518d</guid>
      <description>&lt;p&gt;&lt;strong&gt;The short answer: LLM API performance comes down to three measurable things — the P95/P99 distribution of time-to-first-token (TTFT), streaming stability (the share of long outputs that finish without a silent mid-stream cutoff), and how prompt-cache hits amplify both speed and cost. Total latency and averages will mislead you: generation time is dominated by output length, and a mean hides the tail your users actually feel. A useful benchmark is boring on purpose — a fixed prompt set, temperature 0, at least 30 runs in one time window, percentiles instead of averages, and the same test repeated against the vendor's official API in the same window. Performance should not be an adjective on a vendor page; it should be a number in your terminal. The method below starts from a single curl command and is fully reproducible.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why total latency is a bad metric
&lt;/h2&gt;

&lt;p&gt;Total generation time is dominated by output length: 2000 words take ten times longer than 200 regardless of link quality. In streaming, what users actually feel is two things: &lt;strong&gt;when the first token arrives (TTFT), and whether tokens keep flowing steadily after it&lt;/strong&gt;. TTFT is the true link metric — it contains the entire overhead of ingress, gateway scheduling, and provider-side queueing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read distributions, not means
&lt;/h2&gt;

&lt;p&gt;Averages hide the tail: 90 requests at 1s plus 10 at 8s average to a decent-looking 1.7s, yet every tenth user hits 8 seconds. A fat P95/P99 means queueing or retries — one of the engineering-quality criteria in &lt;a href="https://hop-base.com/blog/verify-your-llm-api-provider" rel="noopener noreferrer"&gt;the fidelity test&lt;/a&gt;. Discipline: fixed prompt, temperature 0, at least 30 consecutive runs in one time window, then read percentiles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Truncation rate: the most ignored metric
&lt;/h2&gt;

&lt;p&gt;A silent mid-stream cutoff on long output is the worst failure mode in streaming: you get half the content and no error code. The test is simple — request long outputs (say 2000 words), repeat N times, and measure the share of streams that finish cleanly with a proper SSE termination. A channel with a high truncation rate makes any TTFT number meaningless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cache hits: performance and cost are the same coin
&lt;/h2&gt;

&lt;p&gt;On a prompt-cache hit, input is billed at a discount and TTFT drops visibly — performance and cost are one thing here. Hit rate depends on routing topology: requests must land on the same backend account, so randomly routed traffic converges toward zero. How affinity scheduling preserves hit rates under load: &lt;a href="https://hop-base.com/blog/how-llm-gateways-survive-high-concurrency" rel="noopener noreferrer"&gt;our high-concurrency engineering notes&lt;/a&gt;; the billing mechanics: &lt;a href="https://hop-base.com/blog/prompt-cache-cost-savings-guide" rel="noopener noreferrer"&gt;the prompt cache guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error codes and retry behavior
&lt;/h2&gt;

&lt;p&gt;An easily missed item: does the gateway pass the model provider's error codes through untouched? A channel that swallows 429s and turns them into timeouts breaks your backoff logic and collapses under peak load. Test it by deliberately triggering rate limits or invalid parameters and comparing behavior with official docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  A benchmark that starts with one command
&lt;/h2&gt;

&lt;p&gt;TTFT is measurable with plain curl (with streaming on, &lt;code&gt;time_starttransfer&lt;/code&gt; is the first-chunk arrival):&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;-N&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"TTFT %{time_starttransfer}s | total %{time_total}s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://api.hop-base.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 &lt;/span&gt;&lt;span class="nv"&gt;$HOPBASE_API_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":"gpt-6-luna","stream":true,"messages":[{"role":"user","content":"Introduce yourself in one sentence"}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap in any model ID your key returns from &lt;code&gt;GET /v1/models&lt;/code&gt;. Loop it 30 times, repeat during peak hours, and you have P95 and jitter. Full discipline: fixed task set, temperature 0, drop the first cold run, retest across time windows, and always compare the vendor's official API against the service under test in the same window.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we instrument ourselves
&lt;/h2&gt;

&lt;p&gt;HopBase records model, usage, latency, and status for every request — the same trail that powers billing audits powers our performance monitoring; resident probes continuously test every channel so anomalies are handled before users notice. That is why we publish the method: &lt;strong&gt;the numbers you measure and the numbers we watch come from the same link.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What counts as a good TTFT?
&lt;/h3&gt;

&lt;p&gt;Absolute values depend on model, region, and ingress. What is comparable is a same-window A/B against the vendor's official API — the gap and the stability of the distribution say more than any absolute number.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is a gateway slower than going direct?
&lt;/h3&gt;

&lt;p&gt;The fixed cost of one extra hop is milliseconds; the gains from less queueing and cache hits are hundreds of milliseconds to seconds. Run both sides with the method above and let the numbers decide — no need to trust anyone.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I keep noise out of the test?
&lt;/h3&gt;

&lt;p&gt;Temperature 0, fixed prompts, N of at least 30, drop cold starts, retest across windows — and never compare across different time windows, or provider-side time-of-day swings will masquerade as gateway differences.&lt;/p&gt;

&lt;p&gt;For enterprise onboarding and comparative benchmarks, &lt;a href="https://hop-base.com/#contact" rel="noopener noreferrer"&gt;contact us&lt;/a&gt;; integration details in the &lt;a href="https://hop-base.com/en/docs" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://hop-base.com/blog/measuring-llm-api-performance-ttft" rel="noopener noreferrer"&gt;HopBase blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
      <category>performance</category>
    </item>
    <item>
      <title>How to Verify Your LLM API Provider Isn't Swapping Models: A Reproducible Fidelity Test</title>
      <dc:creator>hopbase</dc:creator>
      <pubDate>Wed, 28 Oct 2026 18:34:19 +0000</pubDate>
      <link>https://dev.to/hopbase/how-to-verify-your-llm-api-provider-isnt-swapping-models-a-reproducible-fidelity-test-3bec</link>
      <guid>https://dev.to/hopbase/how-to-verify-your-llm-api-provider-isnt-swapping-models-a-reproducible-fidelity-test-3bec</guid>
      <description>&lt;p&gt;&lt;strong&gt;The short answer: you can verify whether an API channel swaps models or degrades quality with three families of reproducible checks — cost-structure checks (prompt-cache behavior cannot be faked economically), behavioral-boundary checks (model families leak their identity at the edges), and blind quality benchmarks (fixed task sets, real sample sizes). Any provider that does not welcome these tests has answered your question already.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The biggest anxieties when buying LLM API access from any third-party provider or aggregator: is the model real, is it silently degraded, and where does my data go. The market's usual answer is a promise — "no routing, no degradation, no swapping." Promises are unverifiable; methods are verifiable. We have run these checks continuously for two years; this is the public version of our internal methodology. Use it on any channel — including us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 0: stop asking the model what it is
&lt;/h2&gt;

&lt;p&gt;One system prompt makes any model claim any name — and official models routinely misreport their own version anyway. &lt;strong&gt;Identity must be verified by behavior, not self-declaration.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 1: prompt-cache economics (hardest to fake)
&lt;/h2&gt;

&lt;p&gt;Claude and GPT prompt caching has an officially defined billing structure: cache writes carry a premium, cache reads are discounted, and &lt;code&gt;cache_read_input_tokens&lt;/code&gt; is visible in &lt;code&gt;usage&lt;/code&gt;. That is a built-in polygraph:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repeat requests with the same long system prompt — from the second call you should see stable cache hits (high read-token share, faster first token);&lt;/li&gt;
&lt;li&gt;Services that randomly route your traffic show dramatically lower or zero hit rates, because your requests land on different accounts and machines;&lt;/li&gt;
&lt;li&gt;Hit rates map to real money. Faking them long-term means the channel subsidizes you — economically unsustainable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Check 2: model-family hard boundaries
&lt;/h2&gt;

&lt;p&gt;Every model family has boundaries it cannot hide: the real context-window limit (push near-limit inputs and watch truncation behavior), tokenizer differences (token counts for identical text differ systematically across families — compare against &lt;code&gt;usage&lt;/code&gt;), parameter surface (unsupported parameters should error or be ignored exactly as the official API does), and stop-sequence / stream-chunking habits. No single item is proof; the combined fingerprint is very hard to fake completely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 3: injection traces
&lt;/h2&gt;

&lt;p&gt;Some channels inject their own instructions around your system prompt — identity rewrites, ads, constraints. Detect by controlled comparison: run the same request set against the vendor's official API and the service under test, and compare obedience details on instruction-recall and role-boundary tasks. We have seen everything from one-line disguises to 4KB injected blocks; all of them show up under A/B contrast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 4: blind degradation testing (sample size matters)
&lt;/h2&gt;

&lt;p&gt;"It feels dumber" is not evidence — output variance is large even on the official API. The credible protocol: fix 20-50 tasks with objective answers (code completion, multi-step reasoning, instruction following), run both channels at temperature 0, compare pass rates, and re-test across weeks to catch time-of-day model swaps. Only a gap that persists beyond noise is a finding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 5: engineering quality
&lt;/h2&gt;

&lt;p&gt;The model can be real while the pipe is bad: look at first-token latency distribution rather than the mean (jittery P95 = unstable path), mid-stream truncation rates on long outputs (silent truncation is the worst failure mode), and whether the model provider's error codes pass through (services that swallow 429/529 into timeouts destroy your retry logic).&lt;/p&gt;

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

&lt;p&gt;Because this is the bar HopBase holds itself to — every route we offer is tested this way before it goes live, and anything that fails is rejected. And because our &lt;a href="https://hop-base.com/pricing" rel="noopener noreferrer"&gt;pricing page&lt;/a&gt; labels each plan's channel attributes in public. &lt;strong&gt;Transparent channel provenance plus reproducible verification beats a hundred repetitions of "we never swap."&lt;/strong&gt; Run every check in this article against us.&lt;/p&gt;

&lt;p&gt;For enterprise onboarding evaluation, &lt;a href="https://hop-base.com/#contact" rel="noopener noreferrer"&gt;talk to an advisor&lt;/a&gt;; integration details are in the &lt;a href="https://hop-base.com/en/docs" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://hop-base.com/blog/verify-your-llm-api-provider" rel="noopener noreferrer"&gt;HopBase blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
      <category>testing</category>
    </item>
    <item>
      <title>Midjourney v8.2 API: Async Calls, 4-Image Jobs, --ar/--hd Sizes and Per-Image Cost</title>
      <dc:creator>hopbase</dc:creator>
      <pubDate>Wed, 28 Oct 2026 18:33:27 +0000</pubDate>
      <link>https://dev.to/hopbase/midjourney-v82-api-async-calls-4-image-jobs-ar-hd-sizes-and-per-image-cost-4ado</link>
      <guid>https://dev.to/hopbase/midjourney-v82-api-async-calls-4-image-jobs-ar-hd-sizes-and-per-image-cost-4ado</guid>
      <description>&lt;p&gt;&lt;strong&gt;Midjourney v8.2 (model ID &lt;code&gt;midjourney-v8-2&lt;/code&gt;) is now live on HopBase&lt;/strong&gt;, submitted over the OpenAI-compatible &lt;code&gt;POST /v1/images/generations&lt;/code&gt; endpoint and polled for results with &lt;code&gt;GET /v1/video/tasks/{task_id}&lt;/code&gt;. The biggest difference from most image models is that &lt;strong&gt;every job returns a fixed set of 4 candidate images&lt;/strong&gt;, and aspect ratio and quality are written into the prompt (&lt;code&gt;--ar&lt;/code&gt; sets the ratio, &lt;code&gt;--hd&lt;/code&gt; renders at native 2K) instead of being passed as request fields. Billing follows the number of images actually returned: &lt;strong&gt;$0.0067&lt;/strong&gt; per image at 1K and &lt;strong&gt;$0.0108&lt;/strong&gt; per image at 2K. Check that your key can see it with &lt;code&gt;GET /v1/models&lt;/code&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Two-step async&lt;/strong&gt;: &lt;code&gt;POST /v1/images/generations&lt;/code&gt; returns &lt;code&gt;202&lt;/code&gt; with a task ID, then you poll &lt;code&gt;GET /v1/video/tasks/{task_id}&lt;/code&gt;. Status moves through &lt;code&gt;queued → processing → completed&lt;/code&gt;, and only &lt;code&gt;completed&lt;/code&gt; and &lt;code&gt;failed&lt;/code&gt; are terminal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use the full model ID&lt;/strong&gt;: &lt;code&gt;midjourney-v8-2&lt;/code&gt;. The authoritative ID is whatever &lt;code&gt;GET /v1/models&lt;/code&gt; returns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key access&lt;/strong&gt;: Midjourney is enabled per API key; if &lt;code&gt;midjourney-v8-2&lt;/code&gt; is not in your key's &lt;code&gt;GET /v1/models&lt;/code&gt; list, enable it in the console first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A prompt is required&lt;/strong&gt;: sending a reference image with no text description is rejected. At most 1 reference image, passed in the &lt;code&gt;images&lt;/code&gt; field.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output lifetime&lt;/strong&gt;: on completion &lt;code&gt;outputs&lt;/code&gt; carries 4 signed links, valid for 24 hours from the moment the task completes. Polling again returns the same links without extending them, and expired links return 410, so download inside that window.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeouts are free&lt;/strong&gt;: a task still unfinished 2 hours after creation is marked failed and not billed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actual charge per task&lt;/strong&gt;: once the task is terminal, the task query carries &lt;code&gt;usage.cost_usd&lt;/code&gt;, the amount actually deducted, so you can reconcile cost per job in code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pricing: the official rate converted to a per-image price
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;How to trigger&lt;/th&gt;
&lt;th&gt;Per image&lt;/th&gt;
&lt;th&gt;Per job (4 images)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.0067&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0.0267&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2K&lt;/td&gt;
&lt;td&gt;Add &lt;code&gt;--hd&lt;/code&gt; to the prompt&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.0108&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0.0433&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Midjourney prices officially by GPU time (0.8 GPU minutes for a standard job, 1.3 minutes with &lt;code&gt;--hd&lt;/code&gt;), and we convert that official rate into a per-image price. &lt;strong&gt;Billing follows the number of images actually returned&lt;/strong&gt;, so a single call costs four images' worth — put that in your budget model rather than estimating from a one-image price. To compare against single-image models, multiply their per-image price by the number of candidates you would otherwise generate — see live pricing at &lt;a href="https://hop-base.com/pricing" rel="noopener noreferrer"&gt;https://hop-base.com/pricing&lt;/a&gt;. The console itemises the actual cost of every request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aspect ratio and size
&lt;/h2&gt;

&lt;p&gt;Size is not a request field; it comes from &lt;code&gt;--ar&lt;/code&gt; in the prompt, and adding &lt;code&gt;--hd&lt;/code&gt; renders at native 2K. Measured values:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;--ar&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;Standard&lt;/th&gt;
&lt;th&gt;With &lt;code&gt;--hd&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1:1 (default)&lt;/td&gt;
&lt;td&gt;1024 × 1024&lt;/td&gt;
&lt;td&gt;2048 × 2048&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16:9&lt;/td&gt;
&lt;td&gt;1456 × 816&lt;/td&gt;
&lt;td&gt;2944 × 1648&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9:16&lt;/td&gt;
&lt;td&gt;816 × 1456&lt;/td&gt;
&lt;td&gt;1648 × 2944&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4:3&lt;/td&gt;
&lt;td&gt;1232 × 928&lt;/td&gt;
&lt;td&gt;2544 × 1904&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21:9&lt;/td&gt;
&lt;td&gt;1680 × 720&lt;/td&gt;
&lt;td&gt;3376 × 1440&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;--ar&lt;/code&gt; only accepts integer ratios, so &lt;code&gt;--ar 1.5:1&lt;/code&gt; is rejected. The ceiling is 14:1, &lt;strong&gt;tightened to 4:1 once &lt;code&gt;--hd&lt;/code&gt; is on&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parameter support
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Supported&lt;/strong&gt;: &lt;code&gt;--ar&lt;/code&gt;, &lt;code&gt;--hd&lt;/code&gt;, &lt;code&gt;--s&lt;/code&gt; (0-1000), &lt;code&gt;--c&lt;/code&gt; (0-100), &lt;code&gt;--weird&lt;/code&gt; (0-3000), &lt;code&gt;--iw&lt;/code&gt; (0-3), &lt;code&gt;--sref&lt;/code&gt; with &lt;code&gt;--sw&lt;/code&gt;, &lt;code&gt;--no&lt;/code&gt;, &lt;code&gt;--seed&lt;/code&gt;, &lt;code&gt;--tile&lt;/code&gt;, &lt;code&gt;--exp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not supported on v8.2, rejected with 400 at submit&lt;/strong&gt;: &lt;code&gt;--q&lt;/code&gt;/&lt;code&gt;--quality&lt;/code&gt;, &lt;code&gt;--niji&lt;/code&gt;, &lt;code&gt;--repeat&lt;/code&gt;, &lt;code&gt;--oref&lt;/code&gt;, &lt;code&gt;--cref&lt;/code&gt;, &lt;code&gt;--stealth&lt;/code&gt;, &lt;code&gt;--stop&lt;/code&gt;, &lt;code&gt;--draft&lt;/code&gt;, and &lt;code&gt;::&lt;/code&gt; multi-prompt weighting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We &lt;strong&gt;reject this set at submit time&lt;/strong&gt; rather than forwarding it: some of these the model silently ignores (you pay and get nothing for it), and the rest only fail after the job has run for tens of seconds. The error message names the parameter and why it is not supported.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three-minute integration
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Submit; returns 202 plus a task ID&lt;/span&gt;
curl https://api.hop-base.com/v1/images/generations &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer sk-your-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":"midjourney-v8-2","prompt":"a red apple on a wooden table, studio light --ar 16:9"}'&lt;/span&gt;

&lt;span class="c"&gt;# 2. Poll with the id from the previous step; once completed, take the 4 links from outputs (valid 24 hours)&lt;/span&gt;
curl https://api.hop-base.com/v1/video/tasks/YOUR_TASK_ID &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer sk-your-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can I generate just one image?
&lt;/h3&gt;

&lt;p&gt;No. Every Midjourney generation mode returns a fixed 2×2 grid of four candidate images. That is how the model itself works, not a restriction added on our side. Neither the image-count field in the request nor &lt;code&gt;--repeat&lt;/code&gt; changes the result, which is why we do not accept any value of &lt;code&gt;n&lt;/code&gt; other than 4 — better to say so at submit time than to silently charge you for four.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I control the size?
&lt;/h3&gt;

&lt;p&gt;In the prompt: &lt;code&gt;--ar&lt;/code&gt; sets the ratio and &lt;code&gt;--hd&lt;/code&gt; renders at native 2K. The &lt;code&gt;quality&lt;/code&gt; field in the request body has no effect on this model and is rejected if you send it. The full size table is above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does it support reference images?
&lt;/h3&gt;

&lt;p&gt;Yes — at most 1, passed in the &lt;code&gt;images&lt;/code&gt; field, with &lt;code&gt;--iw&lt;/code&gt; (0-3) to tune how strongly it is followed; for style references, use &lt;code&gt;--sref&lt;/code&gt; together with &lt;code&gt;--sw&lt;/code&gt;. Note that v8.2 does not support &lt;code&gt;--oref&lt;/code&gt; or &lt;code&gt;--cref&lt;/code&gt;; Midjourney has replaced them with its new editing models.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are failed jobs billed?
&lt;/h3&gt;

&lt;p&gt;No. Only jobs that actually produce images are billed; failed jobs cost nothing. If a prompt is stopped by content moderation the response gives an explicit failure reason, so you can rewrite it and retry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost in code: budgeting a batch
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;PER_IMAGE&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;1k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0067&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0108&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;   &lt;span class="c1"&gt;# official list price, USD per returned image
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;batch_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;PER_IMAGE&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tier&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;        &lt;span class="c1"&gt;# every job returns 4 images
&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;batch_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;        &lt;span class="c1"&gt;# 500 standard jobs -&amp;gt; ~$13.40
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;batch_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# 500 --hd jobs     -&amp;gt; ~$21.60
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Full parameter reference and error codes: &lt;a href="https://hop-base.com/en/docs/media/midjourney" rel="noopener noreferrer"&gt;Midjourney v8.2 docs&lt;/a&gt;. Live list prices for every model: &lt;a href="https://hop-base.com/pricing" rel="noopener noreferrer"&gt;hop-base.com/pricing&lt;/a&gt;. &lt;em&gt;Originally published on the &lt;a href="https://hop-base.com/blog/midjourney-v8-2-api-access" rel="noopener noreferrer"&gt;HopBase blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>midjourney</category>
      <category>ai</category>
      <category>api</category>
      <category>imagegeneration</category>
    </item>
    <item>
      <title>GPT-5.6 vs Claude Sonnet 5 for Coding: Practical Differences in Chinese-Language Codebases</title>
      <dc:creator>hopbase</dc:creator>
      <pubDate>Wed, 28 Oct 2026 18:29:25 +0000</pubDate>
      <link>https://dev.to/hopbase/gpt-56-vs-claude-sonnet-5-for-coding-practical-differences-in-chinese-language-codebases-dck</link>
      <guid>https://dev.to/hopbase/gpt-56-vs-claude-sonnet-5-for-coding-practical-differences-in-chinese-language-codebases-dck</guid>
      <description>&lt;p&gt;"Should I use GPT or Claude for coding?" We hear this question more than any other. As a gateway serving both model families to developer teams every day, we see where their behavior actually differs. This isn't a benchmark shootout — just what actually matters for your choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Different Personalities
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Claude Sonnet 5&lt;/strong&gt; excels at engineering consistency across large codebases: when you're modifying a feature in a big repo, it reads the surrounding code first, keeps changes aligned with the existing style, and rarely decides to "helpfully" refactor things. Paired with Claude Code's agent mode, multi-file tasks complete much more reliably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GPT-5.6&lt;/strong&gt; excels at single, explosive performance: algorithm problems, standalone utilities, scripts from scratch — it delivers fast and accurate. It's also better at "guessing intent" from vague specs. Paired with Codex CLI, the experience is buttery smooth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chinese Language Differences
&lt;/h2&gt;

&lt;p&gt;Both models handle Chinese comprehension fine at this point. The difference is in output habits: Claude tends to continue in the same comment style as your code; GPT is bolder about converting Chinese requirement descriptions into English identifier names. If your team requires Chinese comments and commit messages, Claude's "compliance" will save you revision cycles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Token Consumption and Real Cost
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In equivalent multi-turn coding sessions, Claude accumulates much longer context, but cache hits afterward slash input costs dramatically — &lt;strong&gt;look at actual spend after caching, not just list prices&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;GPT typically needs shorter context for similar tasks, so per-turn is cheaper, but agent-style multi-turn loops might iterate more times.&lt;/li&gt;
&lt;li&gt;For batch and offline jobs where latency doesn't matter, picking the economy tier saves more than switching models.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A worked example at list price
&lt;/h3&gt;

&lt;p&gt;One agent turn with a 50K-token context, of which 40K is a cached prefix, and 3K output tokens (official list prices per million tokens: &lt;code&gt;claude-sonnet-5&lt;/code&gt; $2 input / $0.20 cached / $10 output; &lt;code&gt;gpt-5.6-sol&lt;/code&gt; $4 / $0.40 / $20):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;claude-sonnet-5: 10K × $2/M + 40K × $0.20/M + 3K × $10/M = $0.020 + $0.008 + $0.030 = $0.058
gpt-5.6-sol:     10K × $4/M + 40K × $0.40/M + 3K × $20/M = $0.040 + $0.016 + $0.060 = $0.116
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude also bills a one-time cache write when the prefix is first stored, so short sessions benefit less. The real comparison is total spend per &lt;em&gt;finished task&lt;/em&gt;: a model that needs fewer turns can win even at a higher per-token rate. Prices change — check live pricing at &lt;a href="https://hop-base.com/pricing" rel="noopener noreferrer"&gt;https://hop-base.com/pricing&lt;/a&gt; before you budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Recommendation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; Large repo daily iteration, strong engineering discipline: &lt;strong&gt;Claude Sonnet 5 + Claude Code&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Standalone scripts, algorithms, rapid prototypes: &lt;strong&gt;GPT-5.6 + Codex&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Still unsure? Take the same task, run it against both models, and your repo is the only benchmark that matters.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Run the same task against both
&lt;/h2&gt;

&lt;p&gt;Claude speaks the Anthropic Messages protocol and GPT the OpenAI protocol, so an A/B test is two calls with the same prompt:&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="nv"&gt;PROMPT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Add input validation to parse_order() in orders.py; keep the existing Chinese comment style.'&lt;/span&gt;

&lt;span class="c"&gt;# Claude Sonnet 5 (Anthropic Messages)&lt;/span&gt;
curl https://api.hop-base.com/v1/messages &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: &lt;/span&gt;&lt;span class="nv"&gt;$HOPBASE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"anthropic-version: 2023-06-01"&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="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;model&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;claude-sonnet-5&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;max_tokens&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:2048,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;messages&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:[{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;role&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$PROMPT&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}]}"&lt;/span&gt;

&lt;span class="c"&gt;# GPT-5.6 Sol (OpenAI Chat Completions)&lt;/span&gt;
curl https://api.hop-base.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 &lt;/span&gt;&lt;span class="nv"&gt;$HOPBASE_API_KEY&lt;/span&gt;&lt;span class="s2"&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="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;model&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;gpt-5.6-sol&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;messages&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:[{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;role&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$PROMPT&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}]}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare the diffs, then compare the &lt;code&gt;usage&lt;/code&gt; blocks: token counts × list price is your real cost per answer. Newer generations (Claude Sonnet 5.5, GPT-6 Sol) have since launched at similar or lower list prices, and the same method applies to them. Run &lt;code&gt;GET /v1/models&lt;/code&gt; first to see which IDs your key can call.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Someone else's benchmark can't replace your codebase.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Setup guides: &lt;a href="https://hop-base.com/en/docs/tools/claude-code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt; · &lt;a href="https://hop-base.com/en/docs/tools/codex-cli" rel="noopener noreferrer"&gt;Codex CLI&lt;/a&gt; · &lt;a href="https://hop-base.com/pricing" rel="noopener noreferrer"&gt;live pricing&lt;/a&gt;. &lt;em&gt;Originally published on the &lt;a href="https://hop-base.com/blog/gpt-5-6-vs-claude-sonnet-5-coding" rel="noopener noreferrer"&gt;HopBase blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>openai</category>
      <category>claude</category>
      <category>coding</category>
      <category>ai</category>
    </item>
    <item>
      <title>Claude Fable 5.1 API: 1M Context, $0.25/M Cache Reads and Migrating from Fable 5</title>
      <dc:creator>hopbase</dc:creator>
      <pubDate>Wed, 28 Oct 2026 18:25:21 +0000</pubDate>
      <link>https://dev.to/hopbase/claude-fable-51-api-1m-context-025m-cache-reads-and-migrating-from-fable-5-318g</link>
      <guid>https://dev.to/hopbase/claude-fable-51-api-1m-context-025m-cache-reads-and-migrating-from-fable-5-318g</guid>
      <description>&lt;p&gt;Anthropic's newest flagship, &lt;strong&gt;Claude Fable 5.1&lt;/strong&gt; (model ID &lt;code&gt;claude-fable-5-1&lt;/code&gt;), is available through the HopBase API over the native Anthropic Messages protocol. If your key already calls Claude, switching is a one-line model-name change; confirm with &lt;code&gt;GET /v1/models&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model specs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1M context window, 128K max output&lt;/strong&gt;: whole repositories, long documents, and long multi-turn conversations fit in a single request, with no need to split long outputs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptive thinking, always on&lt;/strong&gt;: no &lt;code&gt;thinking&lt;/code&gt; parameter needed; steer reasoning depth and spend with &lt;code&gt;output_config.effort&lt;/code&gt; (low through max).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built for long-horizon agent work&lt;/strong&gt;: stronger than Fable 5 at long-running autonomous coding, document / spreadsheet / slide work, multi-step research, vision, and computer use. Same tokenizer as Fable 5, so token counts are essentially unchanged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native Anthropic Messages API&lt;/strong&gt;: standard &lt;code&gt;/v1/messages&lt;/code&gt;; the Anthropic SDK and Claude Code switch over with zero code changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pricing: official list price
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item (per million tokens)&lt;/th&gt;
&lt;th&gt;Claude Fable 5.1&lt;/th&gt;
&lt;th&gt;Claude Fable 5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Input&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$10&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$50&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache write (5 min / 1 hour)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$12.50 / $20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$12.50 / $20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache read (hit)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$0.25&lt;/strong&gt; (0.025×)&lt;/td&gt;
&lt;td&gt;$1.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cache reads cost a quarter of Fable 5's, so long sessions and agent loops that re-read the same prefix save the most.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the cache-read cut means per turn
&lt;/h3&gt;

&lt;p&gt;Take an agent loop that re-sends a 200K-token prefix (system prompt + tool definitions + repo context) every turn, adds 5K fresh input tokens and gets 2K output tokens back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fable 5.1: 200K × $0.25/M + 5K × $10/M + 2K × $50/M = $0.05 + $0.05 + $0.10 = $0.20 per turn
Fable 5:   200K × $1.00/M + 5K × $10/M + 2K × $50/M = $0.20 + $0.05 + $0.10 = $0.35 per turn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Over a 50-turn session that is about $10 versus $17.50 — a 43% saving with no prompt changes, as long as the prefix stays byte-identical so it keeps hitting the cache (the one-time cache write is extra in both cases). Live list prices for every model are on the &lt;a href="https://hop-base.com/pricing" rel="noopener noreferrer"&gt;pricing page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things to check when migrating from Fable 5 / Opus 5
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Forced tool use is gone&lt;/strong&gt;: &lt;code&gt;tool_choice&lt;/code&gt; &lt;code&gt;any&lt;/code&gt; / &lt;code&gt;tool&lt;/code&gt; returns 400. Use &lt;code&gt;auto&lt;/code&gt; plus an instruction naming the tool, and &lt;code&gt;strict: true&lt;/code&gt; or structured outputs when you need schema-valid JSON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thinking blocks are bound to the model&lt;/strong&gt;: pass them back unchanged within a conversation and keep the history append-only — editing earlier turns invalidates earlier thinking blocks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No assistant prefill&lt;/strong&gt;: as with every Claude model since 4.6, control output format with structured outputs or the system prompt.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Three-minute quickstart
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.hop-base.com/v1/messages &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: sk-your-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;"anthropic-version: 2023-06-01"&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": "claude-fable-5-1",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello, introduce yourself"}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full setup steps are in the &lt;a href="https://hop-base.com/en/docs/protocols/anthropic-sdk" rel="noopener noreferrer"&gt;Anthropic SDK guide&lt;/a&gt; and the &lt;a href="https://hop-base.com/en/docs/tools/claude-code" rel="noopener noreferrer"&gt;Claude Code guide&lt;/a&gt;. If you already have a key, just switch the model name to &lt;code&gt;claude-fable-5-1&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://hop-base.com/blog/claude-fable-5-1-api-launch" rel="noopener noreferrer"&gt;HopBase blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>anthropic</category>
      <category>llm</category>
      <category>api</category>
    </item>
    <item>
      <title>Claude Opus 5.5 vs GPT-6 Sol vs GPT-6 Luna: API List Prices and Cost per Request</title>
      <dc:creator>hopbase</dc:creator>
      <pubDate>Wed, 28 Oct 2026 18:21:19 +0000</pubDate>
      <link>https://dev.to/hopbase/claude-opus-55-vs-gpt-6-sol-vs-gpt-6-luna-api-list-prices-and-cost-per-request-77h</link>
      <guid>https://dev.to/hopbase/claude-opus-55-vs-gpt-6-sol-vs-gpt-6-luna-api-list-prices-and-cost-per-request-77h</guid>
      <description>&lt;p&gt;&lt;strong&gt;The short answer: Claude Opus 5.5, GPT-6 Sol and GPT-6 Luna are available through the HopBase API at official list price. Opus 5.5 (&lt;code&gt;claude-opus-5-5&lt;/code&gt;) is Anthropic's next-generation Opus: 1M context, 128K max output, $4 input / $20 output per million tokens — 20% below Opus 5 at $5 / $25 — with cache hits at $0.20. GPT-6 Sol (&lt;code&gt;gpt-6-sol&lt;/code&gt;) targets complex coding and agent workflows: 1.05M context, $2 / $10, cached input $0.2. GPT-6 Luna (&lt;code&gt;gpt-6-luna&lt;/code&gt;) targets high throughput and cost efficiency: 1.05M context, $0.1 / $0.5, cached input $0.01. Above 272K tokens both GPT-6 models switch to a long-context rate (Sol $4 / $15, Luna $0.2 / $0.75). In one line: Opus 5.5 for Claude Code and tool-heavy agents, Sol for Codex and coding agents, Luna for high-volume classification, extraction and routing, and GPT-6 Astra for the hardest problems. Your key's &lt;code&gt;GET /v1/models&lt;/code&gt; response is the source of truth for availability.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Published list prices for the three new models
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model ID&lt;/th&gt;
&lt;th&gt;Positioning&lt;/th&gt;
&lt;th&gt;Context&lt;/th&gt;
&lt;th&gt;Input / output (per 1M tokens)&lt;/th&gt;
&lt;th&gt;Cache read&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;claude-opus-5-5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Anthropic's next-generation Opus&lt;/td&gt;
&lt;td&gt;1M (128K max output)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$4 / $20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-sol&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Complex coding and agent workflows&lt;/td&gt;
&lt;td&gt;1.05M&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$2 / $10&lt;/strong&gt; ($4 / $15 above 272K)&lt;/td&gt;
&lt;td&gt;$0.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;High throughput, cost efficiency&lt;/td&gt;
&lt;td&gt;1.05M&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$0.1 / $0.5&lt;/strong&gt; ($0.2 / $0.75 above 272K)&lt;/td&gt;
&lt;td&gt;$0.01&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For reference, GPT-6 Astra is $10 / $50 (cached $1) and Claude Opus 5 is $5 / $25. Opus 5.5 cache writes cost $5 per million for the 5-minute TTL and $8 per million for the 1-hour TTL. These are official list prices; every request's actual charge is itemised in your usage records. Since this post first went out, newer siblings have launched (for example Claude Sonnet 5.5 and GPT-6.1 Sol) — see live pricing at &lt;a href="https://hop-base.com/pricing" rel="noopener noreferrer"&gt;https://hop-base.com/pricing&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the same request costs on each model
&lt;/h2&gt;

&lt;p&gt;Straight from the list prices above, for one request with 20K input tokens, 2K output tokens and no cache hits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPT-6 Luna: 20K × $0.1/M + 2K × $0.5/M ≈ &lt;strong&gt;$0.003&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;GPT-6 Sol: 20K × $2/M + 2K × $10/M ≈ &lt;strong&gt;$0.06&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Claude Opus 5.5: 20K × $4/M + 2K × $20/M ≈ &lt;strong&gt;$0.12&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;GPT-6 Astra: 20K × $10/M + 2K × $50/M ≈ &lt;strong&gt;$0.30&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Luna and Astra are about 100x apart. That is why model choice should follow the task: inside one product, intent detection and field extraction that run hundreds of thousands of times a day belong on Luna, and only the smaller share of requests that need long reasoning chains should go to Sol, Opus 5.5 or Astra. Giving each workload its own API key also separates cost by purpose in your usage records.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to choose
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code and tool-heavy agents&lt;/strong&gt;: Opus 5.5. It is 20% cheaper than Opus 5 and cache hits cost only $0.20, so long sessions that keep re-reading the same system prompt and tool definitions get cheaper the more they hit the cache.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codex CLI, coding agents and complex workflows&lt;/strong&gt;: GPT-6 Sol. At $2 / $10 it offers 1.05M context, enough to put a whole repository in context — just remember the long-context rate beyond 272K.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-volume batch work&lt;/strong&gt;: GPT-6 Luna. Classification, tagging, extraction, rewriting and routing decisions — many calls, each simple — cost a fraction of a cent per call on Luna.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The hardest problems you can afford&lt;/strong&gt;: GPT-6 Astra. Run Sol or Opus 5.5 first and escalate only what fails or falls short; that is far cheaper than sending everything to the flagship.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most reliable method is still to run each candidate on your own evaluation set and compare output quality with the actual charges in your usage records, rather than relying on leaderboards. While you are at it, confirm you are getting the model you pay for with our &lt;a href="https://hop-base.com/blog/verify-your-llm-api-provider" rel="noopener noreferrer"&gt;model fidelity verification method&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three-minute integration
&lt;/h2&gt;

&lt;p&gt;Claude uses the Anthropic protocol with Base URL &lt;code&gt;https://api.hop-base.com&lt;/code&gt; (no &lt;code&gt;/v1&lt;/code&gt;); GPT uses the OpenAI-compatible protocol with Base URL &lt;code&gt;https://api.hop-base.com/v1&lt;/code&gt;. One key can be enabled for both families; &lt;code&gt;GET /v1/models&lt;/code&gt; tells you which IDs it can call.&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="c"&gt;# First check which models this key can call&lt;/span&gt;
curl https://api.hop-base.com/v1/models &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$HOPBASE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Claude Opus 5.5 (Anthropic protocol)&lt;/span&gt;
curl https://api.hop-base.com/v1/messages &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: &lt;/span&gt;&lt;span class="nv"&gt;$HOPBASE_API_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;"anthropic-version: 2023-06-01"&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":"claude-opus-5-5","max_tokens":64,"messages":[{"role":"user","content":"Reply with exactly: ok"}]}'&lt;/span&gt;

&lt;span class="c"&gt;# GPT-6 Sol / Luna (OpenAI-compatible; swap the model for gpt-6-luna)&lt;/span&gt;
curl https://api.hop-base.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 &lt;/span&gt;&lt;span class="nv"&gt;$HOPBASE_API_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":"gpt-6-sol","messages":[{"role":"user","content":"Reply with exactly: ok"}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Claude Code, set &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt; to &lt;code&gt;https://api.hop-base.com&lt;/code&gt; and &lt;code&gt;ANTHROPIC_AUTH_TOKEN&lt;/code&gt; to your HopBase key, then switch the model to &lt;code&gt;claude-opus-5-5&lt;/code&gt; (&lt;a href="https://hop-base.com/en/docs/tools/claude-code" rel="noopener noreferrer"&gt;Claude Code guide&lt;/a&gt;). For Codex CLI, use the Responses API (&lt;code&gt;wire_api = "responses"&lt;/code&gt;) with &lt;code&gt;gpt-6-sol&lt;/code&gt; as the model (&lt;a href="https://hop-base.com/en/docs/tools/codex-cli" rel="noopener noreferrer"&gt;Codex CLI guide&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How much cheaper is Opus 5.5 than Opus 5?
&lt;/h3&gt;

&lt;p&gt;At list price, input drops from $5 to $4 and output from $25 to $20 — 20% on both. Cache hits cost $0.20, 0.05x the input price. Opus 5.5 has a 1M context window and 128K max output.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does 272K mean for GPT-6 Sol and Luna?
&lt;/h3&gt;

&lt;p&gt;Both models have a 1.05M context window, but beyond 272K tokens they are billed at the long-context rate: $4 / $15 for Sol and $0.2 / $0.75 for Luna. Everyday requests under 272K pay the base rates of $2 / $10 and $0.1 / $0.5.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can my key call these three models?
&lt;/h3&gt;

&lt;p&gt;Availability is scoped per API key. Call &lt;code&gt;GET /v1/models&lt;/code&gt; with the key; whatever IDs come back are the ones it can call. Do not guess model names.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are these the prices I pay?
&lt;/h3&gt;

&lt;p&gt;They are the official list prices published on our &lt;a href="https://hop-base.com/pricing" rel="noopener noreferrer"&gt;pricing page&lt;/a&gt;. For enterprise volume, contact us for a quote; every request's charge can be checked line by line in your usage records.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://hop-base.com/blog/claude-opus-5-5-gpt-6-sol-luna-api-pricing" rel="noopener noreferrer"&gt;HopBase blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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