1. Before You Build








2. Choosing the Right API Type

Use This When
Direct table query: supabase.from(...) Simple CRUD on one table with RLS
RPC / Postgres Function Multi-step logic, atomic operations, cross-table writes, or complex business logic
Edge Function Webhooks, third-party integrations, email sending, payment processing, logic requiring secrets


3. Auth & Permission Requirements








4. Input Validation

Every input must be validated at three layers:

Layer What It Does
Frontend UX feedback — required, format hints
API / RPC Business rule enforcement — length, format, uniqueness
Database Data integrity — NOT NULL, CHECK constraints, FK constraints









Validation Error Response

{
  "error": "VALIDATION_ERROR",
  "message": "Validation failed.",
  "fields": {
    "name": "Name is required.",
    "email": "Enter a valid email address."
  }
}

5. Success Response Format

{
  "data": {
    ...
  },
  "message": "Project created successfully."
}

Error Response Format

{
  "error": "ERROR_CODE",
  "message": "Human-readable description of the error."
}

Response Rules





6. Standard Error Codes

Code Meaning HTTP Status
AUTH_REQUIREDNot logged in401
FORBIDDENLogged in but no permission403
NOT_FOUNDResource does not exist404
DUPLICATEAlready exists — unique constraint409
VALIDATION_ERRORInvalid or missing input400
BUSINESS_RULE_VIOLATIONFailed a business rule422
SERVER_ERRORUnexpected internal error500

7. RPC Function Checklist

Only applies when building a Postgres RPC function.








Example RPC Pattern

CREATE OR REPLACE FUNCTION create_project(
  p_workspace_id UUID,
  p_name TEXT,
  p_description TEXT DEFAULT NULL
)
RETURNS JSON
LANGUAGE plpgsql
SECURITY INVOKER
AS $$
DECLARE
  v_project projects%ROWTYPE;
BEGIN
  IF p_name IS NULL OR trim(p_name) = '' THEN
    RAISE EXCEPTION 'VALIDATION_ERROR: name is required';
  END IF;

  IF length(trim(p_name)) > 100 THEN
    RAISE EXCEPTION 'VALIDATION_ERROR: name must be 100 characters or fewer';
  END IF;

  IF EXISTS (
    SELECT 1
    FROM projects
    WHERE workspace_id = p_workspace_id
      AND name = trim(p_name)
  ) THEN
    RAISE EXCEPTION 'DUPLICATE: a project with this name already exists';
  END IF;

  INSERT INTO projects (workspace_id, name, description, created_by)
  VALUES (p_workspace_id, trim(p_name), p_description, auth.uid())
  RETURNING * INTO v_project;

  RETURN json_build_object('data', row_to_json(v_project));
END;
$$;

8. Documentation Requirements

Every API endpoint needs documentation before it is handed off to the frontend team.








9. Testing Requirements












Before Marking Done

10. API Endpoint Checklist

API Type


Auth & Permissions



Input Validation





Response Format




Error Cases Handled






Testing & Documentation








Practice Task

Apply what you learned by building a real multi-step RPC function with atomic operations, validation, and full API documentation.

Open Task 03: Build a Create Project API