Skip to main content

Supabase backend API contracts

Verified from supabase/config.toml, the nine function handlers under supabase/functions/, and their browser callers on 2026-08-03. This document describes the repository state; it is not a substitute for checking the deployed function configuration before a live operation.

All public function URLs have the form <VITE_SUPABASE_URL>/functions/v1/<function-name>. Browser callers use the shared nullable Supabase client or a user access token. Secret-bearing calls remain inside Edge Functions.

Function surface

FunctionMethodsAuthentication enforced by current code/configRequest and response contract
chat-modelsGET, POST, OPTIONSExplicit verify_jwt = true; handler also requires Bearer and calls auth.getUser()GET accepts refresh=1; POST accepts {refresh?: boolean}. Returns the verified model/combo catalog, default availability, fetch time, stale flag, optional warning, image_input_version, and explicit per-model image capability metadata.
run-chatGET, POST, OPTIONSExplicit verify_jwt = true; handler validates the bearer user, rate-limits that user, and checks project ownershipGET is only the model-catalog compatibility path and requires models=1 (refresh=1 is optional). POST validates project_id, session/turn identifiers, input, bounded history, optional brain context, model, response version, and optional ephemeral image attachments. The research-v1 path returns validated JSON and persists a session, trace, and LLM span; the legacy transport remains SSE-compatible.
chat-affectPOST, OPTIONSExplicit verify_jwt = true; handler validates the bearer user, rate limit, project ownership, and referenced span/traceAccepts bounded identifiers, phase, text hash, a bounded affect analysis, optional text/model, and optional router refinement. Persists a sanitized annotation; raw text is not stored in annotation metadata.
chat-feedbackPOST, OPTIONSExplicit verify_jwt = true; handler validates the bearer user, rate limit, project ownership, and referenced span/traceAccepts project/span/trace/session/turn identifiers, positive or negative, score 1 or 0, and an optional bounded explanation. Writes a user_feedback span annotation.
ingest-arcade-trajectoryPOST, OPTIONSExplicit verify_jwt = true; handler validates the bearer user and owner-scoped projectAccepts the validated episode and chunk envelope produced by src/data/arcade-research.ts. Calls the service-role-only ingest_arcade_trajectory_internal function and returns acknowledged episode/chunk state.
delete-arcade-trajectoriesPOST, OPTIONSExplicit verify_jwt = true; handler validates the bearer userCalls the service-role-only delete_arcade_trajectories_internal function for the authenticated owner and returns deleted episode/chunk counts. This is separate from clearing a local consent queue.
run-playgroundPOST, OPTIONSNo explicit function entry in supabase/config.toml; the handler requires Bearer, calls auth.getUser(), and rate-limits the userAccepts a CHAT or STR template, format, provider/model routing values, invocation parameters, variables, and optional tools/response format/input. Streams token, done, or error SSE events.
run-evalPOST, OPTIONSNo explicit function entry in supabase/config.toml; handler requires x-exepert-ingest-key matching EXEPERT_INGEST_KEYAccepts {spanId?, traceId?, evaluatorName?} and requires a span or trace identifier. Runs a configured heuristic/code/LLM evaluator and writes annotations with the service role.
otlp-receiverPOST, OPTIONSNo explicit function entry in supabase/config.toml; handler requires the constant-time-checked x-exepert-ingest-key, applies a per-isolate rate limit, and caps the bodyAccepts OTLP/HTTP JSON resourceSpans, maps OpenInference attributes, and writes traces/spans with the service role. The Playwright live-verification spec only probes unauthenticated rejection; it does not perform successful ingestion.

Unsupported methods return 405. JSON endpoints use structured error bodies; streaming endpoints report terminal errors as SSE events where the handler has already opened a stream.

Native image-input compatibility

chat-models advertises native image support only when the catalog includes image_input_version: "image-input-v1". Each model also carries supports_images and image_capability_source. Capability comes only from explicit provider metadata, the server-side ROUTER_VISION_MODELS allowlist, or a combo whose known members all support images; route names are never used as evidence. A client connected to an older catalog remains safely text-only.

run-chat accepts additive attachments arrays on the current turn and on user messages. PNG, JPEG, and WebP data is validated for count, strict base64, MIME and magic-byte agreement, dimensions, per-image size, and the total request budget before 9Router is called. Image-only current turns are valid; blank text without a validated current attachment is not. The browser Chat UI remains text-only, while the native desktop may use this optional contract.

Images are session-memory context, not durable records. Persisted transcript and observability payloads contain only bounded count, MIME, dimensions, and byte-size metadata—never filenames, base64, data URLs, or raw bytes. This feature adds no Storage bucket or database migration.

Browser-to-function callers

  • src/chat/client.ts calls chat-models, run-chat, and chat-feedback.
  • src/affect/client.ts calls chat-affect.
  • src/data/arcade-research.ts invokes the two Arcade functions.
  • src/data/dal.ts invokes run-eval.
  • src/ui/prompt-playground.ts calls run-playground.
  • OTLP ingestion is a trusted exporter/server integration, not a normal browser DAL write path.

Security invariants

  • Treat the six explicit verify_jwt entries and handler checks as separate, cumulative controls. A directory without a config entry is not proof that a deployed function is public or private.
  • Validate the exact hosted project and deployed configuration before invoking live endpoints. Repository inspection alone does not prove deployment state.
  • Browser bundles may contain only client-safe VITE_* values. Service-role, ingest, router, provider, and administrative keys remain Edge secrets or server-only values.
  • Preserve owner checks before privileged writes. Do not add service-role use to browser code or broaden RLS to make a request pass.
  • Do not assume a standalone deno executable exists. Use the Supabase CLI-managed Edge Function workflow unless Deno is explicitly installed and validated for a task.

Source of truth

  • Function deployment/auth configuration: supabase/config.toml plus the deployed project configuration.
  • Request validation and response behavior: each supabase/functions/<name>/index.ts handler and its shared modules.
  • Browser request construction: the callers listed above.
  • Database authorization and callable SQL: cumulative files in supabase/migrations/, deployed state, and current advisor results.