Questions, answered honestly
Skip to your people: Developers · CTOs · CFOs
For developers
The part where you try to find the catch.
Is it really a one-line change?+
Point your base URL at https://api.slashspend.ai/v1 and keep your existing client. SlashSpend implements the OpenAI-compatible Chat Completions API — the format almost every client and framework already targets (the OpenAI SDK, LangChain, LiteLLM, the Vercel AI SDK, your own fetch). You keep calling whatever models you already use: gpt-*, claude-*, gemini-*, or openrouter/* with your own keys. One-line diff, not a migration — your reviewer will be disappointed by how boring the PR is.
Will it break streaming, tools, or function calling?+
No. stream: true works for every provider — SSE, unbuffered, in the OpenAI chat.completion.chunk shape regardless of which provider answers. For Anthropic requests with cache_control, we stream via the native Messages API and translate events on the fly (Anthropic's message_start/content_block_delta → OpenAI chunks), so your prompt-cache discount survives streaming too. Need token counts off a stream? On OpenAI, OpenRouter, Gemini and Anthropic's compat endpoint we auto-request a final usage chunk (unless you've already set your own stream_options), and the native Anthropic cache_control path synthesizes one too — so streamed token counts are the provider's own, not estimates. If a provider ever omits usage despite the request, we fall back to estimating output tokens from the streamed text. Tools, function calling, and structured output work on every path — on the Anthropic cache_control path we translate them to Anthropic's native tool schema and translate the tool calls (streamed and non-streamed) back, so nothing's lost.
How does the semantic cache not hand back the wrong answer?+
Cosine similarity on the prompt embedding with a strict default cutoff (0.95), namespaced per user so you never collide with anyone else. Dial it per request with X-SlashSpend-Semantic-Threshold, or globally in settings. Every hit is auditable, not a black box: the response carries X-SlashSpend-Semantic-Score (how close the match was) and -Semantic-Match-Id (which stored entry answered). And if one ever looks off, one click excludes that match-id so it can never serve again. Cache invalidation is famously one of the two hard problems in computer science — so it's a threshold you control plus a receipt for every hit, not vibes.
What's 'caveman' mode, and should I turn it on?+
It's an opt-in way to cut output-token spend. Add X-TrimTokens-Output: caveman to a request and we prepend one system instruction telling the model to answer tersely — short sentences, no filler, no pleasantries. Output tokens are usually the pricey half of an LLM bill, so for agents, coding assistants, and batch jobs it trims cost noticeably. It's a prompt nudge, not surgery: we ask for a shorter answer, we never truncate or rewrite the response, and we never touch your conversation history. Who should skip it: user-facing chat where tone and full prose matter. And it can't corrupt structured output — if your request uses response_format JSON, tools, or functions we auto-disable caveman (terse nudging makes models drop fields) and tell you via X-SlashSpend-Caveman-Suppressed: structured_output. The response header X-SlashSpend-Output-Mode reports caveman or standard so you always know which applied. It's per-request by design (off by default) — output style should be an explicit per-call choice, not a silent account default; want a per-API-key default instead? Tell us.
Does compression mangle my prompts?+
It only trims filler from your newest message (deterministic, no model in the loop) and leaves the conversation history byte-for-byte identical — which also protects the provider's native prefix-cache discount. Flip compression off in settings if you want raw passthrough. (Different knob from caveman mode above: compression shortens what you send, caveman asks for a shorter answer back.)
What's the latency tax?+
~20ms at the door. But semantic-cache hits skip generation entirely and return in <50ms, so on cache-heavy traffic your p50 goes down. Your on-call rotation also stops getting paged every time a provider sneezes — that's the failover talking.
Which providers and models work — Anthropic, OpenRouter, Grok…?+
Native providers today are OpenAI, Anthropic, and Google — pass gpt-*, claude-*, or gemini-* with the matching key header. Everything else rides in through OpenRouter: pass your OpenRouter key and call any openrouter/ model — GLM 5.2, Qwen 3.7, DeepSeek, Grok, your own fine-tunes. SlashSpend layers tier-routing, caching, and compression on top of all of them. You're not locked to any one lab.
What happens when the provider I'm using goes down?+
On a transient fault — 429, 5xx, or a time-to-first-byte timeout — we fail over across providers, not just within one: an OpenAI model degrades to Anthropic then Gemini, an Anthropic model to OpenAI then Gemini, and so on, using whichever provider keys you've made available. Terminal errors (400/401/404 and friends) are relayed straight back, never retried, so you're not double-billed for a bad request. If you store an OpenRouter key, every chain ends with one more attempt on a strong open model (DeepSeek by default) — so even all three frontier labs wobbling at once degrades to a served answer instead of a 503. That last hop only fires when an OpenRouter key is present; without one, a total outage returns an honest 503 rather than pretending. The failover reason is on every response (X-SlashSpend-Failover-Reason) and in /v1/trace.
How do I see what actually happened?+
Every response carries X-SlashSpend-Request-Id. Fetch the decision trace — cache type, routing decision + confidence, failover reason, latency — at GET /v1/trace?id=<request_id>. No prompt or response content, ever. Need the actual content for one request? Send X-SlashSpend-Debug: true and we hold that one request + response for 1 hour — owner-scoped, and encrypted at rest with your account key when an encryption secret is set — readable from the same trace endpoint. Off by default: no debug header, no content stored. Semantic cache hits also return X-SlashSpend-Semantic-Score and -Semantic-Match-Id so a match is never a black box. grep your standard response headers; no dashboard required to triage a single call.
A new model just dropped — do I have to wait for you to ship an update?+
No. Unknown models are forwarded untouched (X-SlashSpend-Passthrough: true), so you can call a brand-new model the day it launches — no waiting on us. The model registry also auto-syncs from the OpenRouter catalog every six hours, so full context-window and pricing awareness arrives within 24 hours of a model's launch, automatically, with no deploy on your side.
Embeddings, images, audio?+
Chat completions only for now. /v1/embeddings, images, and audio are on the list, not in the build. We'd rather ship the thing that's real than the thing that's roadmap.
For CTOs
Architecture, security, and the blast radius.
Where do my provider keys live?+
In Local Key Mode (the default and recommendation): nowhere. They arrive as request headers, are used in memory for the upstream call, and discarded. Never written to a DB, a log, or a third party. The optional Key Vault encrypts them with AES-256-GCM, and the encryption secret lives only in an env var.
Do you store prompts or responses?+
By default, nothing prompt- or response-related is written to our database or logs — the request-log row literally has no column for content, so it can't be. Cache hits are served from a short-lived response cache (Upstash, 1-hour TTL), and the semantic index stores a math vector of your prompt — not its text. The one exception is opt-in and yours to trigger: send X-SlashSpend-Debug: true and we hold that single request + response for 1 hour (owner-scoped, encrypted at rest when an encryption secret is set) so you can inspect it, then it auto-expires. The only durable data is metadata: tokens, model, latency, cost — kept 90 days behind Postgres row-level security, then automatically deleted.
We already use OpenRouter's provider routing. Why add you?+
Different layer. OpenRouter's provider selection picks the cheapest/fastest host for a model you already chose. We decide whether that pricey model should run at all: cross-tier downgrade by task difficulty, semantic cache (skip the call), and prompt/output compression — none of which provider-selection does. Stack us on top of your OpenRouter key and you get both.
What stops the router from sending a hard question to a dumb model?+
Six checks, all of which must pass — and the whole feature is off until you enable it. Routing only considers requests under your token threshold, only follows a substitution row you can edit or pin ("never downgrade"), refuses to touch requests carrying prompt-cache breakpoints, and — the important one — requires the difficulty scorer to judge the prompt CLEARLY simple with a confidence margin before any downgrade. Short-but-hard prompts stay on the model you asked for, and if difficulty can't be scored properly (real embeddings unavailable) we decline to downgrade at all rather than guess. Default substitutions step down one tier within the same family (Opus → Sonnet, never Opus → Haiku); anything more aggressive — like open-weight DeepSeek or Qwen via your OpenRouter key — only happens if you explicitly add the row. Every response tells you exactly what happened in X-SlashSpend-Routing-Decision, so a declined downgrade is never invisible. And you don't have to take any of this on faith: shadow mode re-runs a sample of your real traffic against the cheaper model in the background (callers always get the primary answer, only a similarity score is ever stored) and builds a per-route agreement report — so you enable auto-routing on evidence, not vibes.
Will you throttle us during a launch?+
Not if you tell us the ceiling you need — and probably not even if you don't. Rate limiting is per account (all your keys share one sliding-window bucket) and self-serve configurable in Settings → Account up to 5,000 requests/minute, effective on your next request with no support ticket or redeploy; email us before a bigger launch and we'll raise it further. You'll never be surprised by the ceiling: every response carries X-RateLimit-Limit and -Remaining, a 429 includes an honest Retry-After computed from the window (seconds, not a blanket minute), and when traffic enters the top 20% of your limit we set X-SlashSpend-RateLimit-Warning and email you — before you hit it. One more launch-day guarantee: if our rate-limiter infrastructure itself has a fault, we fail open and serve your traffic rather than 500 it.
What's the failure mode if SlashSpend is down?+
It's a base URL — point it back at the provider and you're exactly where you started, instantly, with nothing to uninstall. We're honest that a proxy is a hop in your path; that's precisely why rollback is one line and failover is built in.
Are we going to get locked in?+
No — and we test it in CI so we can't quietly drift into it. Because it's BYOK, your provider accounts, keys, rate-limit tier, and model previews stay entirely yours; we never intermediate that relationship. Leaving is a one-line base-URL revert (we speak the OpenAI-compatible format you already use, and Anthropic cache_control users get the native Messages API so reverting is clean too). Export your config and full usage logs anytime via GET /v1/export. Every release runs an "exit-equivalence" test: the same unmodified client must work against SlashSpend and the provider directly, or the build fails. See the five-minute leaving guide at /leaving.
Do you break our Anthropic prompt-cache discount?+
No — it survives the proxy. Requests with cache_control route to Anthropic's native Messages API (not the OpenAI-compat shim that silently strips those fields), and we translate the response back to the OpenAI shape your client already parses. Streaming works the same way — the discount carries through. And you don't have to choose between caching and features: on that native path we translate your tools, tool calls/results, images, and structured output to Anthropic's native schema and back, so tool-calling keeps working while the discount holds (the X-SlashSpend-Translated header shows what we translated). Two optional knobs if you want more control: X-SlashSpend-Cache-Tier: 1h upgrades breakpoints to the one-hour TTL tier (pays the write premium once instead of every five-minute eviction); X-SlashSpend-Stabilize: dates normalizes rotating timestamps so they stop silently busting the provider's cached prefix.
SOC 2? Compliance?+
Not yet — and we won't pretend otherwise. That's the whole reason Local Key Mode is the default: you should not have to trust our storage with your credentials to get the savings. Vault Mode is opt-in for teams who want the convenience and accept the trade-off. Full data-handling breakdown — what's stored, encrypted, and never stored — is at slashspend.ai/security.
Who are your subprocessors?+
Supabase (auth + metadata), Upstash (cache + vectors), Stripe (billing), Resend (email). Your provider keys and prompt text are not sent to any of them in Local Key Mode.
For CFOs
The ROI, without the fairy dust.
How do you charge — and what's the catch on pricing?+
$99/month, flat. No per-request markup, no percentage of spend, no cut of savings. A percentage-of-savings model means the vendor earns more when your bill is bigger — a backwards incentive for a company hired to shrink it. We took a salary instead of a tip jar.
What savings should we actually expect?+
Up to ~40%, driven by your traffic mix: lots of repeated or simple calls save more; a stream of unique hard prompts saves less. The dashboard shows real numbers — what you would have paid vs. what you actually paid — so you can verify, not trust.
What's the payback period?+
If your monthly AI spend is over ~$250, routing and caching typically clear the $99 in the first month. Below that, you're mostly buying the failover and the dashboard.
Any usage overages or surprise invoices?+
No metered markup, ever. There's a soft cap of 5,000,000 requests/month purely to deter abuse — we email at 80% and lift it on request for legitimate high-volume use. The bill is $99 whether you send 100 requests or 5 million. Well past that and want an SLA, a security review, SSO, or invoice billing instead of a card? Email sales@slashspend.ai — that's a conversation, not a plan tier.
What happens to our data and spend if we cancel?+
Cancel anytime in the Stripe portal. The proxy stops authorizing (returns 402), you flip your base URL back, and nothing is held hostage — your keys were never ours and your prompts were never stored.
Still skeptical? That's the correct posture.
The migration is one line and the exit is the same line. Try it.
Get on the list — $99/mo