DEV Community

Cover image for OpenRouter solved one problem. I still had four more
Lolo
Lolo

Posted on

OpenRouter solved one problem. I still had four more

Unpredictable pricing hurts app builders

I signed up for OpenRouter like everyone else: one key, tons of models, no separate OpenAI/Anthropic accounts. Worked great, honestly. But a few weeks into actually building stuff, I noticed I kept hitting the same wall over and over.

Text was never the whole thing. I'd be building something that needed a script generated, then a thumbnail for it, then maybe read it out loud. OpenRouter gave me one key for the text part. Then I was back to three more provider docs, three more auth headers, three more bills, for the parts that weren't text.

And the pricing thing bugged me more than I expected it to. OpenRouter passes through whatever the provider charges plus a fee, which is fair, but it meant I could never just... know what a feature cost. I'd want to tell myself "this thing costs about X per use" before I shipped it, not find out after the fact from an invoice.

The "switch providers with one line" thing is real for text, but that's where it stopped for me. The second I needed an image or a voice, I was reading new docs again like it was day one.

And the free models on OpenRouter are genuinely nice for messing around, but the rate limits are tight enough that I never wanted to actually build a real feature on top of one and then have to migrate off it later.

So at some point I just got annoyed enough to fix it for myself. That's Apiarium: one key, same request shape, across text (GPT, Claude, Gemini), images, text-to-speech, and transcription. Credits instead of pass-through pricing so I can actually look at a number before shipping something instead of after. Video generation is coming soon too.

To be clear, I don't think OpenRouter is bad at what it does. If you just want the biggest catalog of text models to poke at, it's still probably the better call. It just wasn't enough for what I kept building.

fetch('https://api.apiarium.dev/llm', {
  method: 'POST',
  headers: { Authorization: 'Bearer KEY' },
  body: JSON.stringify({
    model: 'claude-sonnet', // or gpt-4o, gemini
    messages: [{ role: 'user', content: 'Hi' }]
  })
})
Enter fullscreen mode Exit fullscreen mode

If you've run into the same thing, needed more than just text, or wanted to know what something would cost before you shipped it, I'm curious how you dealt with it. Did you keep everything on separate providers, build your own abstraction, or just decide the extra complexity wasn't worth solving?

If you're curious what I ended up building, it's at apiarium.dev.

Top comments (5)

Collapse
 
max_quimby profile image
Max Quimby

The cost-predictability complaint resonates more than the multi-modal one for me. Pass-through pricing means your unit economics are only knowable after the invoice, which is a terrible position to ship a feature from. The way we dealt with it wasn't a new provider — it was a thin gateway layer of our own that tags every call with an estimated cost before dispatch (token count × the provider's published rate for that model), logs it per feature, and can hard-cap a feature if its running cost crosses a threshold. That turned "find out from the invoice" into a number we could see in a dashboard the same day.

On the multi-modal side, we kept text/image/voice on separate providers but hid them behind one internal interface, so the app code doesn't know or care which vendor served a request. More plumbing up front, but it meant swapping an image provider later was a one-file change. How are you thinking about credits vs. pass-through when a provider changes its own pricing mid-quarter — does the credit model absorb that for the user, or does it re-price?

Collapse
 
manolito99 profile image
Lolo

That's a really interesting perspective, and I actually agree.

Our goal isn't just to be another unified API. We want to become the infrastructure layer around AI providers.

Predictable pricing is one part of that. Since we use credits, users always know what they'll pay before making a request, regardless of temporary provider price changes.

But I think you're right that there's another layer missing: cost visibility, per-feature analytics, budgets and usage controls. That's definitely on our roadmap.

I'd genuinely love to keep you in the loop as we build this. Your workflow is exactly the kind of production use case we want Apiarium to support.

If we can save you from maintaining part of that gateway yourself, then we've done our job.

Thanks for taking the time to write all that, it was genuinely valuable.

Collapse
 
mudassirworks profile image
Mudassir Khan

the cost predictability complaint is the right one. the Max Quimby approach in the comments (tagging calls with estimated cost before dispatch, token count × published rate per feature) is what we landed on too. recorded before the call fires so the first time you know a feature's real cost isn't on the invoice.

the multimodal gap is also real but the less annoying problem. we kept image and voice on separate providers wrapped behind one internal interface. swapping a provider later is one file, not a refactor. plumbing cost is high upfront then invisible.

curious how you're handling credits running out halfway through a session — does the user see a hard error, or is there a free model fallback?

Collapse
 
manolito99 profile image
Lolo

Good to hear you and Max landed on basically the same pattern independently, that's a stronger signal than either of you building it in isolation would be.

To answer directly: no mid-session issue right now since /llm doesn't stream, each request checks credits before dispatch and returns a hard error (no charge) if you're short, rather than silently falling back to a cheaper model. Honestly hadn't thought hard about a free-model fallback as an option, that's a fair thing to consider, especially for something mid-feature that would rather degrade than fail outright.

Curious how you handled it on your side, hard error too, or something softer?

Collapse
 
tokenlat profile image
TokenLat

Agree completely - aggregation solves "which model," not "how to land it." The four remaining problems (routing, cache warmth, cost observability, failover) are exactly what a landing layer adds on top of raw aggregation. We frame it as access != landing: OpenRouter gets you access, but keeping the cache warm and the trace visible across a 40-step loop is the part nobody sells you. Great post.