Use the AI SaaS Starter Kit with Backblaze B2
    • Dark
      Light

    Use the AI SaaS Starter Kit with Backblaze B2

    • Dark
      Light

    Article summary

    The AI SaaS Starter Kit is an open-source template for building AI-powered software-as-a-service applications. It provides a Next.js frontend, a FastAPI backend, user authentication, subscription billing, AI image generation, an administrative console, and file management backed by Backblaze B2 Cloud Storage.

    Use the starter kit to begin with a working application foundation and adapt its interface, dashboard, plans, and AI workflow for your own product. The repository is also structured so that AI coding agents can understand its architecture, follow its development rules, and help extend the application.

    The starter kit is available from the AI SaaS Starter Kit GitHub repository.

    This guide describes AI SaaS Starter Kit version 0.1.0.

    Starter Kit Components

    The starter kit includes the following components:

    • Application interface
      Next.js 16, React 19, TypeScript, Tailwind CSS, and shadcn/ui.

    • Application API
      FastAPI, Python, boto3, and Pydantic.

    • Authentication and database
      Supabase authentication and PostgreSQL.

    • Subscription billing
      Stripe Checkout, the Stripe Billing Portal, subscription synchronization, and Free, Pro, and Team plan gating.

    • AI image generation
      NVIDIA NIM with the flux.1-dev model, orchestrated through the Genblaze SDK.

    • Object storage
      Backblaze B2 storage for uploaded files, generated images, and generation provenance manifests.

    • Administration
      An admin console for reviewing users, subscriptions, generation jobs, files, provider runs, and audit events.

    • Development guidance
      Repository instructions, architecture documentation, structural tests, and feature documentation for developers and AI coding agents.

    Stripe billing and AI image generation are optional. You can run the authentication, upload, and file-management features with Backblaze B2 and a local Supabase environment before configuring the optional services.

    How the Starter Kit Uses Backblaze B2

    The starter kit connects to Backblaze B2 through the S3-Compatible API by using boto3. It uses your bucket for the following data:

    • Files uploaded through the application

    • Images created through the AI generation workflow

    • SHA-256 provenance manifests associated with generated images

    • File metadata displayed by the dashboard and file manager

    For uploads, the FastAPI backend creates a presigned URL and the browser uploads the file directly to Backblaze B2. The file does not pass through the application server. This design supports larger uploads and avoids serverless request-body limits.

    By default, the application creates short-lived presigned URLs for private file previews and downloads. You can optionally configure a stable public URL base if you use a public bucket and want durable public links.

    Prerequisites

    Before you begin, ensure that you have the following items:

    To enable optional features, you also need the following items:

    Create a Project from the Template

    You can create a new GitHub repository from the template or clone the starter kit directly. Creating a repository from the template is recommended because it gives your project its own Git history.

    1. Open the AI SaaS Starter Kit repository.

    2. Click Use this template, and select Create a new repository.

    3. Enter a repository name, configure its visibility, and create the repository.

    4. Clone your new repository and enter its directory.

      git clone https://github.com/<your-organization>/<your-repository>.git
      cd <your-repository>

      Replace <your-organization> and <your-repository> with the values for your GitHub repository.

    Install the Dependencies

    1. From the project root, install the frontend dependencies.

      pnpm install
    2. Create a Python virtual environment and install the backend dependencies.

      cd services/api
      python3 -m venv .venv
      source .venv/bin/activate
      pip install -r requirements.txt
      cd ../..

    Add the Backblaze B2 Environment Variables

    1. From the project root, create a local environment file.

      cp .env.example .env
    2. Open .env, and replace the Backblaze B2 placeholders with your values.

      B2_APPLICATION_KEY_ID=<your-application-key-id>
      B2_APPLICATION_KEY=<your-application-key>
      B2_BUCKET_NAME=<your-bucket-name>
      B2_REGION=<your-bucket-region>
      B2_PUBLIC_URL_BASE=

      For example, a bucket in the US West region might use us-west-004 for B2_REGION. The application derives the S3-Compatible API endpoint from the region, so you do not need to enter a separate endpoint.

      B2_PUBLIC_URL_BASE is optional. Leave its value empty to use short-lived presigned URLs with a private bucket. For a public bucket, you can set it to a value with the following format: B2_PUBLIC_URL_BASE=https://<bucket-name>.s3.<region>.backblazeb2.com.

    Configure Backblaze B2 CORS for Local Development

    The browser uploads files directly to Backblaze B2. Your bucket must allow cross-origin requests from the local application before you can test uploads.

    From the project root, load the Backblaze B2 environment variables and run the included configuration script. The second origin allows uploads if Next.js uses port 3001 because port 3000 is unavailable.

    set -a
    . ./.env
    set +a
    services/api/.venv/bin/python scripts/configure_b2_cors.py \
      --origin http://localhost:3000 \
      --origin http://localhost:3001

    Applying this configuration replaces the bucket's entire CORS configuration. If another application uses the same bucket, include every origin that it requires.

    Configure Supabase Locally

    Supabase provides authentication and the PostgreSQL database used for profiles, roles, plans, subscriptions, generation jobs, and administrative data. For local development, the included configuration uses a local Supabase stack.

    1. Start Docker or your Docker-compatible runtime.

    2. From the project root, start Supabase.

      supabase start
    3. Copy the local Supabase configuration into .env.

      node scripts/sync-supabase-env.mjs

    The script sets the following variables:

    • NEXT_PUBLIC_SUPABASE_URL

    • NEXT_PUBLIC_SUPABASE_ANON_KEY

    • SUPABASE_SERVICE_ROLE_KEY

    The service-role key is a server-side secret. Do not expose it in browser code or commit the .env file to source control.

    The local Supabase environment includes the following services:

    Mailpit captures local account-confirmation and email-code messages. The local environment does not send these messages to an external email address.

    Run the Starter Kit

    From the project root, start the frontend and backend.

    pnpm dev

    This command first runs pnpm doctor, which checks the Node.js, pnpm, and Python versions; the Python virtual environment; required environment variables; and local ports. If the check finds a problem, follow the displayed instructions and run the command again.

    The application uses the following default addresses:

    Component

    Address

    Application

    http://localhost:3000

    API

    http://localhost:8000

    Backblaze B2 connectivity check

    http://localhost:8000/health

    If port 8000 is unavailable, the development script selects another API port and displays it in the terminal.

    Verify the Starter Kit

    1. Open http://localhost:3000.

    2. Create an account.

    3. Open Mailpit at http://127.0.0.1:54324.

    4. Open the confirmation message, and confirm the account.

    5. Sign in to the application.

    6. Open the upload page, and upload a supported file.

    7. Open the file manager, and verify that the file appears.

    8. Open your Backblaze B2 bucket, and verify that the object was uploaded.

    9. Open http://localhost:8000/health, and verify that the API reports a successful Backblaze B2 connection.

    Grant Administrative Access

    New accounts receive the user role by default. To test the administrative console, grant your account the admin role.

    1. Open Supabase Studio at http://127.0.0.1:54323.

    2. Open the SQL editor.

    3. Run the following statement, replacing the email address with your account email address.

      update public.profiles
      set role = 'admin'
      where email = 'you@example.com';
    4. Open /admin in the application, and verify that the administrative console appears.

    Enable Stripe Billing

    Stripe billing is optional. Without a Stripe configuration, the application continues to run, but billing endpoints return an HTTP 503 response.

    The following steps use Stripe test mode and do not create real charges.

    1. Sign in to the Stripe CLI.

      stripe login
    2. In the Stripe Dashboard, enable test mode and copy your test secret key.

    3. Add the secret key to .env.

      STRIPE_SECRET_KEY=<your-stripe-test-secret-key>
    4. Create the Pro and Team recurring prices and add their identifiers to .env.
      The command is idempotent. If the products and prices already exist, it reuses them instead of creating duplicates.

      pnpm stripe:seed
    5. Start the Stripe webhook listener in a separate terminal.

      pnpm stripe:listen
    6. Copy the displayed whsec_ signing secret into .env as STRIPE_WEBHOOK_SECRET.

    7. Restart pnpm dev because the API reads .env during startup.

    8. Open /billing, and select the Pro plan.

    9. Complete the test checkout by using Stripe test card number 4242 4242 4242 4242, any future expiration date, and any valid CVC and postal code.

    10. If the API uses a port other than 8000, forward Stripe events to the displayed port instead.

      stripe listen --forward-to localhost:<api-port>/billing/webhook

    For complete instructions, see Set Up Stripe Billing.

    Enable AI Image Generation

    AI image generation is optional. Without an NVIDIA API key, the generation endpoint returns an HTTP 503 response and the other application features remain available.

    The generation feature requires a Pro or Team plan. Configure Stripe test mode and upgrade your test account before you test generation.

    1. Get an API key from NVIDIA NIM.

    2. Add the key to .env.

      NVIDIA_API_KEY=<your-nvidia-api-key>
    3. Restart pnpm dev.

    4. Open /generate.

    5. Enter a prompt, and generate an image.

    6. Verify that the image appears on the generation page and in the file manager.

    7. Open the Backblaze B2 bucket, and verify that the generated image and its provenance manifest appear under the generated/ prefix.

    The default model is black-forest-labs/flux.1-dev. You can configure the model, image dimensions, generation steps, timeouts, concurrency, and daily limit in services/api/app/config/settings.py.

    For details about the workflow, see AI Media Generation.

    Configure CORS for a Deployed Application

    The browser uploads files directly to Backblaze B2 through presigned PUT requests. Before you deploy the application, the bucket must have a CORS rule that permits requests from the deployed frontend origin.

    1. From the project root, load the Backblaze B2 environment variables and run the included configuration script.

      set -a
      . ./.env
      set +a
      services/api/.venv/bin/python scripts/configure_b2_cors.py \
        --origin https://<your-web-domain>
    2. Repeat the --origin option to permit more than one frontend origin.

      services/api/.venv/bin/python scripts/configure_b2_cors.py \
        --origin https://<your-production-domain> \
        --origin https://<your-preview-domain>

    The script configures GET, PUT, and HEAD requests and permits the Content-Type header. Applying the configuration replaces the bucket's entire CORS configuration. If other applications use the bucket, include every origin that they require. A dedicated bucket for each deployment environment prevents different applications or environments from overwriting one another's CORS configuration. If you use the same bucket for local development, include your local origins (for example, http://localhost:3000) in this command too: it replaces the local CORS rules that you configured earlier in Configure Backblaze B2 CORS for Local Development rather than adding to them.

    The API also has its own CORS setting. In production, set API_CORS_ORIGINS on the backend to the exact frontend origin.

    API_CORS_ORIGINS=https://<your-web-domain>

    For full production instructions, see Deploy the AI SaaS Starter Kit.

    Deploy the Starter Kit

    The recommended production topology separates the application into the following services:

    • A Next.js frontend deployed to Vercel

    • A FastAPI backend deployed to Railway, Render, or Fly.io

    • A hosted Supabase project for authentication and PostgreSQL

    • Stripe for billing, if enabled

    • Backblaze B2 for uploaded and generated files

    Deploy the backend first so that you can add its address to the frontend as NEXT_PUBLIC_API_URL. When you import the frontend into Vercel, set its root directory to apps/web.

    You can also deploy the frontend and backend as separate Vercel projects. Review the serverless limitations in the repository deployment guide before selecting this topology.

    See the deployment guide for required environment variables, hosted Supabase configuration, production Stripe webhooks, Backblaze B2 CORS configuration, and post-deployment verification.

    Customize the Starter Kit

    The repository separates reusable SaaS infrastructure from the example application behavior. When you build your application:

    • Retain the authentication, billing, file manager, upload workflow, UI components, and navigation structure.

    • Adapt the dashboard cards, charts, and tables to represent your application's activity.

    • Change the application name and description in apps/web/src/lib/app-config.ts.

    • Use the existing FastAPI layer structure and TanStack Query data-access patterns when you add features.

    • Update the repository documentation in the same pull request as the related code.

    Start with AGENTS.md before you give the repository to an AI coding agent. It defines the repository layout, development commands, architectural constraints, and links to the detailed documentation.

    Troubleshoot the Starter Kit

    Use the following solutions to resolve common setup and configuration issues.

    Resolve Environment Check Failures

    Run the environment check separately to see each detected problem and its corrective action.

    pnpm doctor

    Install any missing dependency, replace placeholder values in .env, or recreate the Python virtual environment as directed. Then run pnpm doctor again.

    Resolve a Missing Python Virtual Environment

    Recreate the environment from the project root.

    cd services/api
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
    cd ../..

    Resolve Supabase Startup Failures

    Confirm that Docker is running before you run supabase start. If the Supabase variables are missing from .env, run the synchronization script again.

    node scripts/sync-supabase-env.mjs

    Resolve a Failed Backblaze B2 Health Check

    Confirm that the values for B2_APPLICATION_KEY_ID, B2_APPLICATION_KEY, B2_BUCKET_NAME, and B2_REGION in .env match the bucket and application key. Also confirm that the key has Read and Write access to the selected bucket.

    Resolve Upload Failures After Deployment

    If the application loads but file uploads fail, confirm that the Backblaze B2 bucket CORS configuration permits the deployed frontend origin. Also confirm that the backend's API_CORS_ORIGINS value includes the same frontend origin.

    Resolve Billing Service Unavailable Errors

    An HTTP 503 response from a billing endpoint means that Stripe is not fully configured. Confirm that .env contains STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, STRIPE_PRICE_PRO, and STRIPE_PRICE_TEAM. Restart the application after you change .env.

    Resolve Stripe Webhook Signature Errors

    If a webhook returns 400 Invalid signature, confirm that STRIPE_WEBHOOK_SECRET matches the signing secret displayed by the active Stripe listener. Restart the API after you update the value.

    Resolve AI Generation Service Unavailable Errors

    An HTTP 503 response from the generation endpoint means that NVIDIA_API_KEY is not configured. Add the key to .env and restart the application.

    If the generation page remains locked, confirm that the signed-in account has an active Pro or Team plan.

    Resolve Administrative Access Errors

    New users are not administrators. If /admin returns an HTTP 403 response, grant the account the admin role in Supabase and sign in again.

    Next Steps

    After you verify the starter kit, use these resources to customize and deploy your application:

    • Review the architecture
      To understand the frontend, backend layers, data flows, and integration boundaries, see Architecture.

    • Work with an AI coding agent
      To learn the repository structure, rules, commands, and required documentation updates, see Agent Instructions.

    • Explore the application workflows
      To review the sign-in, upload, billing, generation, and administrative workflows, see Application Workflows.

    • Review the feature documentation
      To understand authentication, billing, image generation, file uploads, file management, the dashboard, and administration, browse the feature documentation.

    • Deploy the application
      To configure Vercel, a backend host, hosted Supabase, Stripe, and Backblaze B2, see Deployment.

    • Review the security guidance
      To understand authentication boundaries, credential handling, upload validation, rate limiting, and production hardening, see Security.

    • Learn about the S3-Compatible API
      To understand how the application uses boto3 and presigned URLs with Backblaze B2, see the S3-Compatible API documentation.

    • Configure CORS rules
      To learn more about permitting direct browser uploads to Backblaze B2, see Cross-Origin Resource Sharing Rules.

    • Explore more integrations
      To learn about other Backblaze integrations and developer examples, visit Backblaze Labs.

    Help us improve this guide. If you find an error, notice outdated information, or have suggestions for improvement, email techpubs@backblaze.com.


    Was this article helpful?