API & Integrations
Regurai exposes three kinds of server-side surfaces. Pick the right one for the job.
| Surface | Mechanism | Caller | Auth |
|---|---|---|---|
| Internal app logic | createServerFn | Same-origin React code | User session (requireSupabaseAuth) |
| Public HTTP endpoint | TanStack server route under src/routes/api/public/* | External services (webhooks, cron) | Per-route signature verification |
| Isolated security primitive | Supabase Edge Function (Deno) | Internal callers needing IP visibility, isolation, or service-role power | Function-specific |
Internal APIs (server functions)
Authoring convention (see server-side-modern knowledge):
// src/lib/something.functions.ts
import { createServerFn } from "@tanstack/react-start";
import { requireSupabaseAuth } from "@/integrations/supabase/auth-middleware";
import { z } from "zod";
export const doThing = createServerFn({ method: "POST" })
.middleware([requireSupabaseAuth])
.inputValidator((input) => z.object({ id: z.string().uuid() }).parse(input))
.handler(async ({ data, context }) => {
const { supabase, userId } = context; // RLS scoped to user
// ...
});
Global middleware in src/start.ts:
errorMiddleware(request-level error envelope).attachSupabaseAuth(function-level — adds the user's bearer token to every server fn RPC).
Without attachSupabaseAuth, protected server fns return 401.
External APIs / webhooks
Server routes under src/routes/api/public/* are exempt from the auth gate on published deployments. Every public route MUST verify caller identity before doing anything — usually via HMAC signature.
Canonical webhook shape:
// src/routes/api/public/webhook.ts
import { createFileRoute } from "@tanstack/react-router";
import { createHmac, timingSafeEqual } from "crypto";
export const Route = createFileRoute("/api/public/webhook")({
server: {
handlers: {
POST: async ({ request }) => {
const sig = request.headers.get("x-webhook-signature");
const body = await request.text();
const expected = createHmac("sha256", process.env.WEBHOOK_SECRET!)
.update(body).digest("hex");
if (!sig || !timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return new Response("Invalid signature", { status: 401 });
}
// ...
return new Response("ok");
},
},
},
});
Stable URLs for external configuration:
- Production:
project--<id>.lovable.app - Preview:
project--<id>-dev.lovable.app
Edge functions catalogue
| Function | Path | Purpose | Auth model |
|---|---|---|---|
login-rate-limit | supabase/functions/login-rate-limit/index.ts | IP-keyed brute-force lockout (5/15 min) | Anon; CORS open to app origin |
To add an edge function:
- Scaffold under
supabase/functions/<name>/index.ts. - Use the service-role client only inside the function — never expose its key.
- Deploy via the Lovable Cloud edge-function tooling.
- Add the entry to the table above in this chapter.
Third-party integrations
| Integration | Purpose | Location |
|---|---|---|
| Supabase Auth | Identity, sessions, MFA | @supabase/supabase-js, @/integrations/supabase/* |
| Supabase Postgres | Application data | RLS-scoped via server fns |
| Cloudflare Workers | Edge runtime / SSR | Built-in to TanStack Start |
| Lovable AI Gateway | LLM calls (where used) | Preferred over direct provider keys |
When adding a new third-party integration, prefer existing platform connectors before adding a custom API key. Document each new integration here with: what it does, what data is shared, what credential is required, and where the secret is stored.
Error handling standards
- All server functions throw native
ErrororResponse(401,403, etc.). - Public routes return
Responseobjects with a clearstatuscode; never leak stack traces. - Client code surfaces server fn errors via TanStack Query's
errorstate; user messaging is generic for auth failures. - All errors are logged to the platform's edge / SSR log stream; no PII in log messages.