Skip to main content
Spec: PF-89 — API Versioning & Edge Function Lifecycle
Last Updated: 2026-03-25

Overview

Edge Functions support application-level API versioning via the X-API-Version header. Callers request a specific version (e.g. v1, v2); the withVersioning middleware routes to the correct handler. If no header is sent, the latest stable version (highest major key) is used. Versioning is opt-in per function and gated by ENABLE_API_VERSIONING.

Quick Start — Adding Versioning to a Function

1. Define a contract

Create supabase/functions/_shared/contracts/my-function.contract.ts:
Re-export from _shared/contracts/index.ts.

2. Wrap with withVersioning

3. (Optional) Add a v2


How It Works

  1. Caller sends X-API-Version: v1 header.
  2. withVersioning looks up handlers['v1'].
  3. If found → executes handler; if deprecated → merges Deprecation / Sunset / Link headers.
  4. If not found → returns 400 with migration guidance (PF-07 error envelope).
  5. If no header → defaults to highest version key.

Feature Flag

Set ENABLE_API_VERSIONING=true in Supabase Edge Function secrets. When unset/false, all requests pass through to the default (latest) handler with no version negotiation.

Contract Conventions

  • File: _shared/contracts/{function-name}.contract.ts
  • Naming: {FunctionName}V{N}Request, {FunctionName}V{N}Response
  • Major-only semver surface: v1, v2 — minor/patch changes stay backward-compatible
  • Re-export all contracts from _shared/contracts/index.ts

Deprecation Headers

When a version is marked deprecated, responses include: Callers should monitor for Deprecation headers and plan migration before Sunset.

CI Contract Validation

Run npx tsx scripts/edge-contracts/diff-contracts.ts to detect breaking changes (removed exports) in contract files. This runs automatically on PRs touching *.contract.ts.
  • Additions (new exports): non-breaking ✅
  • Removals (deleted exports): breaking ❌ — bump major version

Consumer Obligations

  1. Send X-API-Version header or accept the default (latest stable).
  2. Handle 400 responses with migration guidance when a version is unsupported.
  3. Respect Sunset dates by migrating before the removal deadline.
  4. Monitor Deprecation headers in responses.