Skip to main content

Overview

This guide covers how the two frontend projects (conformly-frontend and conformly-web) integrate with the Conformly.ai backend API.

Base Configuration

API Base URL

EnvironmentURL
Local devhttp://localhost:8000/api/v1
Productionhttps://beta-api.conformly.ai/api/v1
Set via VITE_API_BASE_URL in each frontend’s .env file.

Authentication

All API requests (except /payments/*) require a valid Supabase JWT token:
const headers = {
  'Authorization': `Bearer ${supabaseToken}`,
  'Content-Type': 'application/json'
};

Auth + Subscription Flow

The platform frontend (conformly-frontend) implements a ProtectedRoute component that:
  1. Checks session: On load, validates the Supabase session
  2. Syncs profile: Calls POST /auth/sync to activate free plan or migrate pending subscriptions
  3. Checks subscription: Calls GET /auth/me and reads subscription_status
  4. Gates access: Renders the app if subscription_status === 'active', redirects to /subscribe otherwise
const response = await fetch(`${API_BASE_URL}/auth/me`, {
  headers: { 'Authorization': `Bearer ${token}` }
});
const profile = await response.json();

if (profile.subscription_status === 'active') {
  // Allow access
} else {
  // Redirect to /subscribe
}
Never call supabase.auth.getSession() or refreshSession() inside an onAuthStateChange callback. The Supabase client holds an internal lock during event dispatch, and nested calls will deadlock. Use setTimeout(..., 0) to defer API calls from event handlers.

Common Patterns

File Upload Flow

  1. Initialize upload: POST /standards/{id}/uploads/init or POST /work-products/uploads/init
  2. Upload file to the returned presigned URL
  3. Complete upload: POST /standards/{id}/uploads/{upload_id}/complete

Analysis Tracking Flow

  1. Start analysis: POST /analysis/gaps (returns immediately with job ID)
  2. Poll analyses: GET /analysis/analyses?workspace_id=... to check status (pendingprocessingcompleted)
  3. Get results: GET /analysis/analyses/{id} for gaps and recommendations

Payment Flow

The marketing site (conformly-web) handles the pricing → payment flow:
  1. User selects a plan on the marketing site pricing section
  2. Frontend calls POST /payments/create-checkout-session with the selected plan
  3. User is redirected to Stripe Checkout
  4. On success, Stripe redirects to STRIPE_SUCCESS_URL (the platform frontend /payment-success page)
  5. The payment success page calls GET /payments/session-info/{session_id} and displays confirmation
  6. On next login, POST /auth/sync migrates the pending subscription to the user profile

Error Handling

All endpoints return consistent error responses:
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human readable error message",
    "details": {},
    "timestamp": "2026-01-15T10:30:00Z",
    "request_id": "req_123456789"
  }
}

Response Formats

Paginated Response

{
  "items": [],
  "total": 100,
  "page": 1,
  "limit": 20,
  "next_cursor": "cursor_string"
}

User Profile Response (GET /auth/me)

{
  "id": "uuid",
  "email": "user@example.com",
  "name": "John Doe",
  "organization": "Acme Corp",
  "role": "engineer",
  "created_at": "2026-01-15T10:30:00Z",
  "last_login": "2026-03-03T14:00:00Z",
  "subscription_status": "active",
  "subscription_plan": "free"
}

Cross-Project URL References

FromToVariableExample
conformly-webconformly-frontendVITE_APP_URLNavigation login/signup links
conformly-frontendconformly-webVITE_WEB_URLSubscribe page pricing link

API Reference

Browse all API endpoints

Configuration

Backend environment variables