Skip to main content
Reference

API & Integrations

Regurai exposes three kinds of server-side surfaces. Pick the right one for the job.

SurfaceMechanismCallerAuth
Internal app logiccreateServerFnSame-origin React codeUser session (requireSupabaseAuth)
Public HTTP endpointTanStack server route under src/routes/api/public/*External services (webhooks, cron)Per-route signature verification
Isolated security primitiveSupabase Edge Function (Deno)Internal callers needing IP visibility, isolation, or service-role powerFunction-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

FunctionPathPurposeAuth model
login-rate-limitsupabase/functions/login-rate-limit/index.tsIP-keyed brute-force lockout (5/15 min)Anon; CORS open to app origin

To add an edge function:

  1. Scaffold under supabase/functions/<name>/index.ts.
  2. Use the service-role client only inside the function — never expose its key.
  3. Deploy via the Lovable Cloud edge-function tooling.
  4. Add the entry to the table above in this chapter.

Third-party integrations

IntegrationPurposeLocation
Supabase AuthIdentity, sessions, MFA@supabase/supabase-js, @/integrations/supabase/*
Supabase PostgresApplication dataRLS-scoped via server fns
Cloudflare WorkersEdge runtime / SSRBuilt-in to TanStack Start
Lovable AI GatewayLLM 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 Error or Response (401, 403, etc.).
  • Public routes return Response objects with a clear status code; never leak stack traces.
  • Client code surfaces server fn errors via TanStack Query's error state; user messaging is generic for auth failures.
  • All errors are logged to the platform's edge / SSR log stream; no PII in log messages.