API-first · open source · MIT

Scheduling and contact forms, behind one clean API.

Give every user a public booking page and an embeddable contact form — backed by typed ConnectRPC, a generated SDK, signed webhooks, and a dashboard you don't have to build.

No credit card · deploys on free tiers · self-host anywhere

halomail.app/book/grace-hopper

Intro Call · 30 min

Pick a time

Mon
Tue
Wed
Thu
09:00
09:30
10:00

Inbox

live

Jane Visitor

Saw your portfolio — can we talk?

Marc Dev

Question about the API pricing

Priya S.

Booking rescheduled to Thursday

POST /SubmitMessage · 200 OK

Plays well with

Built on the tools you already run

PostgreSQL
Redis
Google Calendar
Outlook
Resend
ConnectRPC
Docker
OpenTelemetry
PostgreSQL
Redis
Google Calendar
Outlook
Resend
ConnectRPC
Docker
OpenTelemetry
Features

Everything a booking link needs, and nothing it doesn't

Two products sharing one identity layer, one API, and one deployable binary.

Scheduling that respects timezones

Weekly availability rules, date overrides, Google and Outlook sync, reschedule and cancel flows — slots are computed server-side so two people never book the same minute.

Weekly rules

Mon – Fri09:00 – 17:00
SaturdayUnavailable

Next bookings

Intro CallTue 09:00
Design ReviewWed 14:30
PairingThu 11:00

Spam-proof by default

Honeypot fields, per-IP rate limiting, and a spam score on every submission.

jane@example.com
0.02
winner@lottery.biz
0.97
marc@studio.dev
0.05

Emails that don't look templated

Five built-in themes plus custom HTML, with live preview before you send.

Minimal
Apple
Notion
Glass
Terminal

Typed end to end

Protobuf definitions generate both the Go server and the TypeScript SDK, so a renamed field breaks the build instead of production.

const halo = new HaloMail({ apiUrl: process.env.API_URL });

await halo.contact.submitMessage({
  formSlug:    "portfolio",
  senderName:  "Jane Visitor",
  senderEmail: "jane@example.com",
  data:        { message: "Let's talk." },
});

One dashboard for meetings and messages.

Every booking, every form submission, every API key and webhook delivery in a single place — with an audit log that records who changed what.

  • Read, search, and mark submissions without leaving the app
  • Rotate scoped API keys and replay failed webhooks
  • Per-form target addresses and redirect URLs
Open the dashboard

This week

1D7D

Bookings

34

Messages

128

Show rate

92%

MonTueWedThuFriSatSun
FormMessagesSpamLast
portfolio1420.4%2m ago
hire-me381.1%1h ago
support5123.8%4m ago
newsletter960.9%22m ago
feedback270.0%3h ago

Run as many forms as you have pages.

One form per page, per campaign, per client. Each gets its own slug, target address, field schema, and redirect — and shares the same two-line embed.

See the embed guide
How it works

Live on your site in three steps

01

Create a form or event type

From the dashboard or one API call. You get a slug and a public booking handle.

02

Paste two lines into your site

A script tag and a data-halomail attribute on the form you already designed.

03

Watch messages and bookings land

Stored, forwarded to your inbox, and pushed to your endpoints as signed webhooks.

Integrate

Two lines of HTML, or the raw API

The widget is progressive enhancement over a form you already have. Prefer to own the request? It's plain JSON over POST.

index.html · drop-in widget
<script src="https://api.halomail.app/widget.js" defer></script>

<form data-halomail="portfolio">
  <input name="name" required>
  <input name="email" type="email" required>
  <textarea name="message" required></textarea>
  <input name="_hl_hp" tabindex="-1" style="display:none">
  <button type="submit">Send</button>
</form>
terminal · book a meeting
curl https://api.halomail.app/halomail.scheduling.v1.BookingService/CreateBooking \
  -H 'Content-Type: application/json' \
  -d '{
    "eventTypeId":  "evt_01a01b8f",
    "inviteeName":  "Grace Hopper",
    "inviteeEmail": "grace@example.com",
    "start":        "2026-06-15T09:00:00Z"
  }'
Signed webhooks
Scoped API keys
Resend or SMTP
Single-binary deploy

6

services, one binary

~15 MB

container image

$0

to run on free tiers

MIT

licensed, forever

Have a question? We've got answers.

Confused or curious? The docs cover the whole surface — from the first embed to self-hosting the stack on your own infrastructure.

Read the docs

What is HaloMail?

An open-source platform that gives every user a public booking page and an embeddable contact form, behind one typed API. Run it as a hosted service or self-host the whole thing as a single container.

How do I start using HaloMail?

Create an account, make a form or event type, then paste a script tag into your site. The integration guide walks through both, with copy-paste snippets for plain HTML and React.

Do I need a database?

PostgreSQL, yes — a free Neon project is plenty to start. Redis is optional: without it, rate limiting falls back to an in-memory limiter, which is correct for a single instance.

Can I use my own domain for emails?

Yes. Verify a domain with your email provider, then point EMAIL_FROM at an address on it. Without a verified domain, delivery is limited to your own account address.

Is it really free to run?

In monolith mode it fits inside the free tiers of a container host and a managed Postgres. Scale a single service out to its own deployment later without touching code.

How do I keep the API off the public internet?

Every write endpoint except form submission and booking requires a bearer token. Deploy the gateway behind your own proxy if you want the rest locked down further.

Get started

Ship scheduling and contact in an afternoon.

Self-host the whole platform as one container, or run each service on its own. Same API either way.