Works with · Lovable
Lovable + Cerver: see what your users' AI actually costs.
Lovable turns prompts into full React + Supabase apps — 100k+ new projects a day. What it doesn't give you: any idea what your users' AI usage costs, who your expensive users are, or a key you can safely ship. That's a backend problem — and it's one prompt away from solved.
The gap in every vibe-coded AI app
Lovable will happily wire an AI feature — usually by putting a provider API key somewhere it shouldn't be and calling it a day. Then reality arrives on schedule: the key leaks (a June study caught 282 apps exposing theirs), one enthusiastic user quietly becomes most of your bill, and you can't answer the only business question that matters: what does each user's AI usage cost me?
Cerver is the piece Lovable doesn't build: a session gateway between your app and every model. Your app talks to two endpoints with a publishable key (scoped, $5/day budget, 60 req/min — designed to ship in clients). Every user gets a session; every session carries app_user_id; every dollar lands in a dashboard you can query.
The integration is a prompt
You built the app by prompting — integrate the backend the same way. Paste this into Lovable:
Add an AI assistant to my app, powered by cerver.ai (an AI-backend gateway).
Requirements:
1. All AI calls go through Cerver's gateway — two endpoints only:
- POST https://gateway.cerver.ai/v2/sessions
body: { "compute": {"provider": "online"}, "metadata": {"app_user_id": "<current user id>"} }
→ returns { "session_id": ... }. Create ONE session per user, cache the id.
- POST https://gateway.cerver.ai/v2/sessions/<id>/run-llm
body: { "input": "<user message>", "model": "claude-haiku-4-5-20251001", "harness": "claude" }
→ Server-Sent Events stream; "event: text_delta" lines carry data JSON with a "content" chunk.
2. Auth header on both calls: Authorization: Bearer <CERVER_PUBLISHABLE_KEY>
(React client (publishable key) or Supabase Edge Function (secret key)). NEVER put an OpenAI/Anthropic key anywhere in this app.
3. Always send metadata.app_user_id on session create — per-user cost attribution depends on it.
4. Stream the reply into the UI as chunks arrive; show a small "thinking" state until the first chunk.
5. Keep the model id in ONE constant so it can be swapped later.
6. Add a friendly retry state for failed/refused runs.
The publishable key is scoped server-side to these two endpoints and carries a $5/day budget
and 60 req/min rate limit — it is designed to ship in the client.
Before pasting, mint the key (once, from your terminal — your secret key never enters Lovable):
curl -X POST https://gateway.cerver.ai/v2/auth/keys \
-H "Authorization: Bearer $CERVER_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{ "label": "lovable-app", "project_slug": "my-app", "kind": "publishable" }'
# → { "key": "pk_XXXX…" } — that's the one that goes in the app
What the generated code looks like
If you'd rather read it than prompt it — the whole client is two functions (React client (publishable key) or Supabase Edge Function (secret key)):
const GW = "https://gateway.cerver.ai";
const PK = "pk_XXXX…"; // publishable key — scoped + capped, safe for clients
// one session per user — the transcript is their AI history
export async function cerverSession(userId) {
const cached = localStorage.getItem("cerver.session");
if (cached) return cached;
const r = await fetch(`${GW}/v2/sessions`, {
method: "POST",
headers: { Authorization: `Bearer ${PK}`, "Content-Type": "application/json" },
body: JSON.stringify({
compute: { provider: "online" },
metadata: { app_user_id: userId } // ← this is what makes usage queryable per user
})
});
const j = await r.json();
const sid = j.session_id || j.sessionId;
localStorage.setItem("cerver.session", sid);
return sid;
}
// streamed reply (SSE)
export async function ask(sessionId, input, onDelta) {
const r = await fetch(`${GW}/v2/sessions/${sessionId}/run-llm`, {
method: "POST",
headers: { Authorization: `Bearer ${PK}`, "Content-Type": "application/json" },
body: JSON.stringify({ input, model: "claude-haiku-4-5-20251001", harness: "claude" })
});
const reader = r.body.getReader(), dec = new TextDecoder();
let buf = "", event = "";
for (;;) {
const { done, value } = await reader.read();
if (done) break;
buf += dec.decode(value, { stream: true });
const lines = buf.split("\n"); buf = lines.pop();
for (const line of lines) {
if (line.startsWith("event: ")) event = line.slice(7).trim();
else if (line.startsWith("data: ") && event === "text_delta") {
try { onDelta(JSON.parse(line.slice(6)).content || ""); } catch {}
}
}
}
}
Then: query your users' AI usage
This is the part that changes how you run the product. Open your Cerver dashboard → Sessions, and every user is there: their transcript history, their session count, their exact spend. The user costing you $2/day isn't a leak — it's your Pro tier waiting to be priced. The feature nobody uses isn't a mystery — the transcripts say what people actually ask. And when a better model ships, check the benchmark, change one string in your Lovable project, done.
Two endpoints. One prompt. Every answer about your AI costs.
Open a project, mint a publishable key, paste the prompt into Lovable. No card, $5 free tier.