Skip to main content

Ready to Publish?

Important: The preview environment is not HIPAA-compliant. Do not use real patient data during testing or previews. Only test with synthetic or sample data.
Publishing requires a Pro plan ($1,000/month) or higher. You can take your app live on your own at any time by pressing Publish in the top right corner of the Specode UI. The guided publish flow walks you through every step - no need to wait for the Specode team. Before you can publish, you’ll need:
  • A HIPAA audit with no blocking findings
  • A production Convex deployment connected via deploy key
  • Signed BAAs with all services that handle PHI
  • Production environment variables configured (email provider keys, etc.)
Backend hosting BAA is self-serve: You sign Convex’s BAA directly in your Convex dashboard - no negotiation needed.
Optional penetration test: We offer an optional in-house penetration test for $3,000. Teams typically request this when they need a pen test report for procurement, security review, or enterprise onboarding. You can also arrange this after publishing from the live app panel.
If your app integrates with third-party services (telehealth video, messaging, eRx, analytics, etc.), those vendors may have their own fees and agreements, including BAAs where applicable. Important: Stripe does not sign a BAA and classifies certain healthcare categories (telemedicine, pharmacy) as restricted. The Specode team can help navigate Stripe approvals for restricted categories. See our Payment Processing Guide for details.

Before You Publish: Connect Your Services

Before starting the publish flow, connect your GitHub repository and Convex production deployment from Project Settings > Connections.
Connections page showing GitHub and Convex setup

Project Settings > Connections - connect GitHub and Convex before publishing.

GitHub (Optional)

Connecting a GitHub repository is optional but recommended. Each publish pushes your code to the repo and tags it with a version number, giving you a full history of every deployed version.
  1. Create an empty repository on GitHub. Specode suggests a name based on your project (e.g., specode-mindlink-secure-723). Don’t add a README, .gitignore, or license. Create it on GitHub
  2. Connect it. Click Connect GitHub and pick that repository.
  3. Specode pushes your code. Your current code is pushed immediately, and every publish after that pushes and tags a new version. Commits made directly on GitHub come into Specode with Pull from GitHub; a publish waits until they’re pulled.

Convex (Required)

Your production app runs in your own Convex account. Specode publishes to it using a restricted deploy key.
1

Open your Production deployment in the Convex dashboard

Go to the Convex dashboard and open your project. Make sure you select the Production deployment (not Development).
Convex dashboard showing Production deployment link

In the Convex dashboard, click Production next to your project to open the production deployment.

2

Go to Settings > Deploy Keys

In your production deployment, go to Settings in the left sidebar, then find the Deploy Keys section. Click + Create Deploy Key.
Convex Deployment Settings with Deploy Keys section

Deployment Settings - click + Create Deploy Key.

3

Create a deploy key with exactly two permissions

Name the key (e.g., “Specode”), set expiration to No expiration, and select exactly two permissions:
  • deployment:deploy
  • deployment:env:write
Do not select any other permissions. Click Create.
Create Deploy Key dialog with two permissions selected

Create Deploy Key - select only deployment:deploy and deployment:env:write.

4

Copy the deploy key

Copy the key immediately - you won’t be able to see it again. It starts with prod:your-deployment|....
Deploy Key Created dialog showing the key to copy

Copy your new deploy key. You won't be able to see it again.

5

Paste it into Specode

Back in Specode’s Project Settings > Connections, paste the key into the Production deploy key field and click Connect. Specode checks that the key can’t read data or logs, then stores it encrypted.
Once both services are connected, your Connections page will show the connected state:
Connections page with GitHub and Convex both connected

Both GitHub and Convex connected and ready for publishing.


The Publish Flow

Press Publish in the top right corner to start. The flow has five steps, and you can go back to any previous step at any time.

Step 1: HIPAA Audit

Specode runs a HIPAA compliance audit on the code you’re about to publish. All blocking findings must be resolved before you can continue.
HIPAA audit step showing Ready to publish

Step 1 - HIPAA audit passed with no blocking findings.

If you’ve already published and then made changes to your project, the audit step will flag that your code has changed and require a new audit before you can publish again.
HIPAA audit warning - code changed since last audit

If code changed since the last audit, you'll need to run it again.

Step 2: Production Convex

Connect your production Convex deployment if you haven’t already done so from Project Settings. If you’ve already connected it, this step shows the connected deployment.
Production Convex connected with deploy key

Step 2 - Production Convex connected.

Step 3: BAA Confirmation

Confirm that you have Business Associate Agreements (BAAs) in place with all services that handle patient data. The publish flow lists the services that may receive patient data (e.g., Convex). A BAA with Convex is required - it’s included on the Convex Professional plan (request it from support@convex.dev). For other services, follow your own policies. Some services only handle data like sign-in codes and may not need one.
BAA confirmation step listing services that may receive patient data

Step 3 - Confirm your BAAs are in place.

Step 4: Environment Variables

Configure production environment variables. These go straight to your production Convex deployment - Specode can’t read them back and only tracks which are set. Variables are detected from your app’s code. Required variables must be set before you can continue. Common variables include:
  • AUTH_EMAIL - The From address for sign-in emails (required)
  • MAILGUN_API_KEY - For sending sign-in and password-reset emails from your own Mailgun account (required)
  • MAILGUN_DOMAIN - Your Mailgun sending domain (required)
  • AUTH_EMAIL_NAME - The From name for sign-in emails (optional)
  • BETTER_AUTH_TRUSTED_ORIGINS - Extra origins allowed to sign in, comma-separated (optional)
  • OPENAI_API_KEY - If your app uses OpenAI (optional)
You can also add custom variables for anything else your app reads. Specode sets SITE_URL (from your domain), BETTER_AUTH_SECRET, and VITE_PROJECT_NAME automatically.
Environment variables step with empty required fields

Step 4 - Configure your production environment variables.

Environment variables step with all values configured

All required variables filled in and ready to save.

Step 5: Review and Publish

Review your production setup, then publish. The summary shows each step’s status, the destination Convex deployment, the release number and version, and which GitHub repo will receive the code.
Review and publish step showing all checks passed

Step 5 - Everything is green. Click Publish to production.

Click Publish to production. Specode will:
  1. Cut a release from the current code
  2. Push the backend to Convex
  3. Publish the frontend
  4. Check that the live app responds
  5. Tag the release in your GitHub repo
Publishing steps in progress

Publishing in progress - you can close this window and return to check progress.

Once complete, you’ll see a success banner. Your app is live.
Published success banner with production URL

Published! Your app is now live at your production URL.


After Publishing

Your Production URL

After publishing, your app is live at a Convex-hosted URL (e.g., https://valiant-mink-841.convex.site). Specode automatically sets the SITE_URL environment variable to this address.

Custom Domain

You can serve your app from your own domain, such as www.yourclinic.com or app.yourclinic.com. A root domain like yourclinic.com can’t point at the app directly - add www.yourclinic.com and forward yourclinic.com to it at your domain provider.
Domain setup with input field for custom domain

Add your custom domain from the live app panel.

After adding a domain, you’ll get DNS records to configure:
  1. In the Convex dashboard, open your Production deployment > Settings > Custom Domains, enter your domain, keep HTTP Actions selected, and click Add Domain. Leave “Override Environment Variables” as is.
  2. At your domain provider, add these records. On Cloudflare, set both to DNS only:
It may take up to 30 minutes to verify your domain and start serving traffic.
Domain added with CNAME and TXT records to configure

DNS records to configure at your domain provider.

Publish History

Every publish is versioned. You can see your full publish history with the release number, version, timestamp, and status. From the history, you can:
  • Roll back to a previous version
  • Rebuild from the same code version (useful after changing a domain or environment variable)
Publish history table with three releases

Publish history showing versioned releases with rollback and rebuild options.

Pushing Updates

Once published, you keep full access to your Specode project. New changes in your project do not automatically sync to the live app. When you’re ready to push changes to production:
  1. Make and test your changes in the Specode development environment
  2. Press Publish - the flow will require a fresh HIPAA audit if your code changed since the last one
  3. The new version is deployed and tagged in your GitHub repo
Each publish increments the version number, so you always know which code version your live app runs on.

GitHub Integration

If you connected a GitHub repository, every publish pushes your code and tags it with the release version. You can also:
  • Push code manually from Project Settings > Connections at any time
  • Pull from GitHub to bring commits made directly on GitHub into Specode (a publish will wait until external changes are pulled)

BAAs and Third-Party Services

For HIPAA compliance, you’ll need signed BAAs with each service that handles protected health information (PHI). This includes:
  • Convex - self-serve BAA signed in your Convex dashboard (included on the Convex Professional plan)
  • Mailgun (or your chosen email provider) - for transactional emails like password resets and notifications. Set up your account, get your API key, configure your sending domain, and sign their BAA.
  • Any other third-party services whose APIs touch PHI in your app (telehealth, messaging, eRx, analytics, etc.)
Your Specode team will help identify which BAAs are needed based on your app’s integrations.
If your email provider won’t sign a BAA: If your transactional email provider (e.g., Mailgun) refuses to sign a BAA, you have two options:
  1. Switch providers - Look for a HIPAA-compliant alternative that offers BAAs.
  2. Eliminate PHI from emails - Ask the Specode AI to audit your app’s email notification flow and confirm that no PHI is included in any outgoing emails (to patients, clinicians, or other roles). If emails contain only non-PHI information (appointment reminders without details, generic notifications, etc.), a BAA may not be required. Prompt example: “Analyze the code and ensure the email notification flow does not expose any PHI. Any email should contain the minimum information that does not qualify as PHI.”
Either way, all email-based communications that could touch PHI require a signed BAA with the provider.
Authentication method and HIPAA considerations: If your app uses Google sign-in alongside regular email registration, be aware of a compliance nuance:
  • With Google sign-in enabled, users may not enter their email separately in the app, which means email notifications (handled by your transactional email provider) need extra configuration to capture the right address.
  • Google sign-in must be separated from email notification functionality - it should only be used for authentication, while all email notifications must route through your HIPAA-compliant email provider (e.g., Mailgun with a signed BAA).
  • If this adds complexity, consider using email-only registration/sign-in to keep the compliance surface area smaller.
What about BetterAuth? Better Auth is an open-source authentication library that runs directly on your Convex backend. It is not a separate hosted service or third-party data processor - your authentication data is stored and processed entirely within your Convex environment. Since Convex is the data custodian (and you sign a BAA with Convex), no separate BAA is needed for Better Auth.
Important: Stripe does not sign a BAA and classifies certain healthcare categories (telemedicine, pharmacy) as restricted. The Specode team can help navigate Stripe approvals for restricted categories. See our Payment Processing Guide for details.
Not sure where to start? Just press Publish in the top right corner - the guided flow walks you through everything. Or reach out to support.