<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/three-lines-to-switch-llm-providersand-the-twelve-things-that-break-pjoq7dpc1" -->

---
title: Three Lines to Switch LLM Providersand the Twelve Things...
description: Switching between OpenAI-compatible LLM providers looks trivial because the request shape (POST /v1/chat/completions) is widely mimicked, but underlying...
canonical: https://daily.dev/posts/three-lines-to-switch-llm-providersand-the-twelve-things-that-break-pjoq7dpc1
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Three Lines to Switch LLM Providersand the Twelve Things That Break | daily.dev
og:description: Switching between OpenAI-compatible LLM providers looks trivial because the request shape (POST /v1/chat/completions) is widely mimicked, but underlying...
og:url: https://daily.dev/posts/three-lines-to-switch-llm-providersand-the-twelve-things-that-break-pjoq7dpc1
og:image: https://api.daily.dev/og/posts/pJoQ7dpC1.png
og:image:alt: Three Lines to Switch LLM Providersand the Twelve Things That Break
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Three Lines to Switch LLM Providersand the Twelve Things That Break

**[Medium](https://daily.dev/sources/medium_js)** · 8 min read · 0 upvotes · 0 comments

## Summary

Switching between OpenAI-compatible LLM providers looks trivial because the request shape (POST /v1/chat/completions) is widely mimicked, but underlying behavior diverges sharply. Twelve specific gaps are cataloged: inconsistent max_tokens vs max_completion_tokens handling, silently dropped unknown parameters, ignored temperature settings on reasoning models, missing usage data in streams, wide variance in tool calling support, two tiers of structured output support, inconsistent finish_reason values, differing error shapes and status codes, divergent context-window truncation behavior, inconsistent multimodal input handling, non-interchangeable embeddings, and inconsistent idempotency/request-ID support. A probe script is provided to test each provider before depending on it, along with two structural habits — isolating the client and normalizing responses at the boundary — to make provider swaps safer. Aggregators like OpenRouter and LiteLLM absorb some of this inconsistency but introduce their own tradeoffs.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://medium.com/@lawwork04/three-lines-to-switch-llm-providersand-the-twelve-things-that-break-6ff114b63b0f>

## Questions this post answers

### Why does my token limit seem to get ignored when I switch LLM providers?

Some OpenAI-compatible providers use max_completion_tokens instead of the older max_tokens parameter, and if a provider accepts only one of the two, sending the wrong one can silently drop your limit entirely, letting a runaway generation continue and increasing your bill without any error being returned.

_Anyone juggling multiple LLM providers can track gotchas like this through daily.dev before they hit production._

### Why is the usage field missing when I stream chat completions from an LLM API?

Streaming responses often omit the usage block by default; you need to explicitly pass stream_options={"include_usage": True}, and even then not every provider honors it. Without server-reported usage, token counts must be estimated client-side with a tokenizer that may not match the server's, making cost tracking unreliable.

_Developers comparing LLM providers can keep tabs on API quirks like this via daily.dev._

### Is it safe to assume an OpenAI-compatible API will support the same tool calling and structured output features as OpenAI?

No. Basic tools plus tool_choice="auto" is broadly supported, but forcing a specific function, parallel tool calls, streaming partial tool-call arguments, and strict JSON Schema-constrained decoding are all inconsistently implemented across providers. Some providers emulate tool calling via prompt injection and a parser rather than native training, which fails differently and worse.

_Teams deciding between LLM providers can follow coverage of these compatibility gaps on daily.dev._

## Similar posts on daily.dev

- [Multi-Provider LLM Routing Is Not a Problem, It's Your Architecture: Inference in Production Series](https://daily.dev/posts/multi-provider-llm-routing-is-not-a-problem-it-s-your-architecture-inference-in-production-series-b8ljpdbw8) · DigitalOcean Community · 0 upvotes · 0 comments
- [LLM APIs are a Synchronization Problem](https://daily.dev/posts/llm-apis-are-a-synchronization-problem-jqudnnuyu) · Armin Ronacher · 3 upvotes · 0 comments

---

Tags: [#llm](https://daily.dev/tags/llm), [#architecture](https://daily.dev/tags/architecture), [#openai](https://daily.dev/tags/openai), [#ai-inference](https://daily.dev/tags/ai-inference)

[View this post on daily.dev](https://daily.dev/posts/three-lines-to-switch-llm-providersand-the-twelve-things-that-break-pjoq7dpc1)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Three Lines to Switch LLM Providersand the Twelve Things That Break","url":"https://daily.dev/posts/three-lines-to-switch-llm-providersand-the-twelve-things-that-break-pjoq7dpc1","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/three-lines-to-switch-llm-providersand-the-twelve-things-that-break-pjoq7dpc1"},"datePublished":"2026-08-31T02:23:03.295Z","dateModified":"2026-08-31T02:25:22.552Z","description":"Switching between OpenAI-compatible LLM providers looks trivial because the request shape (POST /v1/chat/completions) is widely mimicked, but underlying...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d6ab0a9a223ee01bc82d647f54feb2d2?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d6ab0a9a223ee01bc82d647f54feb2d2?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/three-lines-to-switch-llm-providersand-the-twelve-things-that-break-pjoq7dpc1","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"llm,architecture,openai,ai-inference","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"Three Lines to Switch LLM Providersand the Twelve Things That Break"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/three-lines-to-switch-llm-providersand-the-twelve-things-that-break-pjoq7dpc1#faq","mainEntity":[{"@type":"Question","name":"Why does my token limit seem to get ignored when I switch LLM providers?","acceptedAnswer":{"@type":"Answer","text":"Some OpenAI-compatible providers use max_completion_tokens instead of the older max_tokens parameter, and if a provider accepts only one of the two, sending the wrong one can silently drop your limit entirely, letting a runaway generation continue and increasing your bill without any error being returned. Anyone juggling multiple LLM providers can track gotchas like this through daily.dev before they hit production."}},{"@type":"Question","name":"Why is the usage field missing when I stream chat completions from an LLM API?","acceptedAnswer":{"@type":"Answer","text":"Streaming responses often omit the usage block by default; you need to explicitly pass stream_options={\"include_usage\": True}, and even then not every provider honors it. Without server-reported usage, token counts must be estimated client-side with a tokenizer that may not match the server's, making cost tracking unreliable. Developers comparing LLM providers can keep tabs on API quirks like this via daily.dev."}},{"@type":"Question","name":"Is it safe to assume an OpenAI-compatible API will support the same tool calling and structured output features as OpenAI?","acceptedAnswer":{"@type":"Answer","text":"No. Basic tools plus tool_choice=\"auto\" is broadly supported, but forcing a specific function, parallel tool calls, streaming partial tool-call arguments, and strict JSON Schema-constrained decoding are all inconsistently implemented across providers. Some providers emulate tool calling via prompt injection and a parser rather than native training, which fails differently and worse. Teams deciding between LLM providers can follow coverage of these compatibility gaps on daily.dev."}}]}
```

