Changing base_url takes thirty seconds. Moving a production app takes a day, because of everything the thirty seconds hides: model names that differ, features that behave differently, usage numbers you now depend on, and no way back if it goes wrong. This post is the checklist I would use, plus a script that maps your current model IDs to a gateway's catalog.
Disclosure: AICredits links on this site are affiliate links. I had no AICredits key, so nothing here was run against its authenticated API. The model mapping uses its public catalog, fetched on 2026-10-16. Whether a gateway suits you is a trade: you get one INR wallet and one key, you add a hop and a dependency. I list the costs below.
What changes when you move to a gateway?
| Area | Direct API | Gateway | Check |
|---|---|---|---|
| Base URL and key | Provider's | Gateway's | Env vars, not code |
| Model IDs | gpt-6-luna | Often openai/gpt-6-luna | Mapping script below |
| Billing | Provider invoice, USD | Gateway wallet, INR (AICredits) | Reconcile one real charge |
| Features | Full native API | Whatever the gateway implements | supported_apis, conformance test |
| Failure modes | Provider outages | Provider outages plus gateway outages | Fallback plan |
| Data path | You to provider | You to gateway to provider | Read the gateway's data terms |
Step 1: map your model IDs
Take every model string in your code and config, and resolve it against the catalog. The script tries an exact match, then a provider prefix, then a normalised match that ignores dots and hyphens. I ran it on 2026-10-16 against the public catalog:
gpt-6-luna -> openai/gpt-6-luna prefix added
claude-sonnet-5-5 -> anthropic/claude-sonnet-5.5 normalised (dots/hyphens)
claude-opus-5-5 -> anthropic/claude-opus-5.5 normalised (dots/hyphens)
claude-haiku-5-5 -> anthropic/claude-haiku-5.5 normalised (dots/hyphens)
claude-fable-5-1 -> anthropic/claude-fable-5.1 normalised (dots/hyphens)
gemini-3-flash-preview -> google/gemini-3-flash-preview prefix added
deepseek-v4.1-flash -> deepseek/deepseek-v4.1-flash prefix added
gpt-4o-mini -> gpt-4o-mini exact
claude-3-5-sonnet-latest -> None NOT FOUND
openai/gpt-6-sol -> openai/gpt-6-sol exact
no-such-model -> None NOT FOUND
Four lessons from that output:
- Version spellings differ. The Anthropic-style
claude-sonnet-5-5becameclaude-sonnet-5.5in the catalog. A silent 404 here is the most likely first failure. - Some IDs exist both bare and prefixed. The catalog had 24 IDs without a prefix, mostly older OpenAI models such as
gpt-4o-mini, and many of them also exist asopenai/.... Pick one spelling and use it everywhere. - Aliases may not exist.
claude-3-5-sonnet-latestwas not found. Pin concrete IDs from the catalog. - The mapper can be ambiguous. It reports
AMBIGUOUSinstead of guessing when two entries normalise to the same string. Resolve those by hand.
def resolve(wanted, ids):
if wanted in ids:
return wanted, "exact"
for p in PREFIXES:
if f"{p}/{wanted}" in ids:
return f"{p}/{wanted}", "prefix added"
n = norm(wanted)
hits = [i for i in ids if norm(i.split("/", 1)[-1]) == n]
if len(hits) == 1:
return hits[0], "normalised (dots/hyphens)"
return (hits, "AMBIGUOUS") if hits else (None, "NOT FOUND")
Store the result as a map in config, for example {"summary": "anthropic/claude-sonnet-5.5"}, and load it at startup.
Step 2: check feature parity
For each model, read supported_apis, context_length and mode from the catalog. On 2026-10-16, anthropic/claude-sonnet-4.6 listed messages and chat_completions, while anthropic/claude-sonnet-5.5 listed only chat_completions. If your code uses Anthropic's native Messages API through the SDK, you cannot assume every model supports that route on the gateway. If you use chat completions, you are fine.
Then run the conformance test for each model you use. Provider-specific features, such as Anthropic's cache control or reasoning parameters, may or may not pass through. Test them, do not assume. See prompt caching for what depends on them.
Step 3: put everything behind config
import os
BASE_URL = os.environ["LLM_BASE_URL"] # gateway or direct provider
API_KEY = os.environ["LLM_API_KEY"]
MODEL_MAP = json.loads(os.environ["LLM_MODEL_MAP"]) # {"summary": "anthropic/claude-sonnet-5.5"}
With this, rollback is changing three variables and restarting. Keep a second set of values for the direct provider in your secrets manager, and test the switch in staging. Note that direct-provider model IDs differ from gateway IDs, so the map must change with the URL.
Step 4: shadow-test on real prompts
- Log 100 to 500 real production prompts (strip personal data first).
- Replay them through both routes.
- Compare: success rate, latency, token counts, and a sample of outputs for quality, using a rubric or a judge with known limits.
- Only move traffic once the failure list is explained.
Token counts matter for cost. A gateway should report the same usage as the provider, but check it. If they differ, find out why before you build budgets on them.
Step 5: move traffic gradually
Start with a low-risk feature (a classifier, an internal tool), then a percentage of traffic, then the rest. Watch error rate, latency, and cost per call. The cost-per-feature script helps with the last one, and retries and fallback covers the failure policy.
What are the costs of using a gateway?
Be honest with yourself about these:
- An extra dependency. If the gateway is down, you are down unless you have a direct fallback.
- An extra hop. It may add latency. I did not measure AICredits' latency, and the benchmark method post gives a way to measure it yourself.
- A price difference. In AICredits' catalog the INR price equals USD price times the exchange rate times 1.05 across all 413 priced models I checked; the homepage also mentions a platform fee. Reconcile with a real invoice.
- Data handling. Your prompts pass through another company. I did not read AICredits' privacy terms for this post, so read them before sending anything sensitive.
- Feature lag. New provider features may arrive later or not at all.
What you get in return, per its homepage: UPI and net banking top-ups in INR, one key across providers, per-key budgets and an automatic failover feature I could not test. For many Indian teams the payment side alone decides it. See the AICredits review and AICredits vs OpenRouter, or sign up (affiliate link) and run the steps above on a cheap model first.
What I could not verify
- Authenticated behaviour on AICredits: feature pass-through, usage accuracy, failover.
- AICredits' data handling and invoicing terms.
- Latency and reliability compared with direct APIs.



