Custom Email Sending

By default, invoices, estimates, proformas, and payment reminders send from BillCraft's shared sender address. If you'd rather your clients see emails coming from your own business address, you can connect a Google Workspace or Microsoft 365 mailbox under Settings → Email sending.

This only affects client-facing documents. Team invitations and client portal login codes always send from BillCraft's sender, regardless of this setting.

Why do I need to create my own app?

Rather than asking you to trust a shared, BillCraft-owned app with access to your mailbox, you register your own small OAuth application with Google or Microsoft — free, takes about five minutes — and BillCraft uses it only to request permission to send mail as you. You can revoke that permission at any time from your own Google Cloud or Azure account, without contacting BillCraft.

Google Workspace setup

You'll need access to Google Cloud Console with the Google account (or Workspace admin account) whose mailbox you want to connect.

1

Create a Google Cloud project

In Google Cloud Console, click the project dropdown at the top → New Project. Any name works — e.g. "BillCraft Email".

[SCREENSHOT: Google Cloud Console — New Project dialog]
2

Enable the Gmail API

Go to APIs & Services → Library, search for Gmail API, and click Enable.

3

Configure the OAuth consent screen

Go to APIs & Services → OAuth consent screen. Choose Internal if you're on Google Workspace and only need your own organization to connect, or External for a personal Gmail account (in that case add your own email under Test users so Google doesn't require app review for this single-user connection).

4

Create OAuth credentials

Go to APIs & Services → Credentials → Create Credentials → OAuth client ID. Choose Web application as the type, and add this exact URL under Authorized redirect URIs:

https://billcraft.aakasa.dev/api/settings/email/google/callback

Click Create. Google shows you a Client ID and Client Secret — copy both.

[SCREENSHOT: Google Cloud Console — OAuth client created, showing Client ID and Client Secret]
5

Connect in BillCraft

In BillCraft, go to Settings → Email sending, paste the Client ID and Client Secret into the Google Workspace card, and click Save & Connect. You'll be sent to Google to sign in and grant permission, then redirected back — BillCraft will show the connected mailbox address once it succeeds.

Microsoft 365 / Azure setup

You'll need access to the Microsoft Entra admin center (formerly Azure Active Directory) for the tenant whose mailbox you want to connect.

1

Register a new application

In the Entra admin center, go to Identity → Applications → App registrations → New registration. Give it any name — e.g. "BillCraft Email". Under Supported account types, choose the option matching who should be able to connect (typically "Accounts in this organizational directory only" for a single Workspace/tenant).

2

Add the redirect URI

Under Redirect URI, select platform type Web and enter:

https://billcraft.aakasa.dev/api/settings/email/microsoft/callback

Click Register.

[SCREENSHOT: Azure App registration — Redirect URI configuration]
3

Grant Mail.Send permission

Open the app you just registered → API permissions → Add a permission → Microsoft Graph → Delegated permissions. Search for and add Mail.Send and offline_access. If your organization requires admin consent, click Grant admin consent (only a tenant admin can do this step).

4

Create a client secret

Go to Certificates & secrets → Client secrets → New client secret. Add a description and expiry, then click Add. Copy the secret Value immediately — Microsoft only shows it once.

5

Copy your IDs

From the app's Overview page, copy the Application (client) ID and Directory (tenant) ID.

[SCREENSHOT: Azure App Overview — Application (client) ID and Directory (tenant) ID]
6

Connect in BillCraft

In BillCraft, go to Settings → Email sending, paste the Application (client) ID, Client Secret, and Tenant ID into the Microsoft 365 card, and click Save & Connect. You'll be sent to Microsoft to sign in and grant permission, then redirected back to BillCraft.

Sending from a different address

By default, client-facing emails send as whichever mailbox completed the OAuth connection above. If you'd rather they show a different address — e.g. a shared billing@yourcompany.com instead of a personal mailbox — set it under Settings → Email sending → From address for that provider. This only works if the connected mailbox is actually allowed to send as that address:

Google Workspace: add the address as a verified "Send mail as" alias under the connected account's Gmail settings (Settings → Accounts → Send mail as). Google requires confirming ownership of that address (or an admin-configured domain-wide alias) before it will accept sends from it.

Microsoft 365 / Azure: grant the connected account "Send As" (or "Send on Behalf") delegate permission on that mailbox — typically a shared mailbox — from the Exchange admin center. Without that permission, Graph rejects the send with ErrorSendAsDenied.

Leave the From address field blank to always use the connected mailbox's own address.

Troubleshooting

"redirect_uri_mismatch" error: the redirect URI registered in Google Cloud / Azure must match the one shown above exactly, including the https:// and no trailing slash.

Connection shows an error after redirecting back: check that the Gmail API (Google) or Mail.Send permission with admin consent (Microsoft) was actually granted in step 3 of the relevant setup above, then disconnect and reconnect from Settings → Email sending.

Emails fail after setting a custom From address: the connected mailbox isn't allowed to send as that address yet — see "Sending from a different address" above. Clear the field to fall back to the connected mailbox's own address while you fix the alias/delegation setup.

Disconnecting: you can remove the connection from Settings → Email sending at any time, or revoke access directly from your Google Account permissions page or the Entra admin center — either way, BillCraft falls back to its shared sender immediately.