Your audience, in one place.
Store every contact with custom fields, slice them into static and dynamic segments, personalize with variables, and honor consent automatically. Unlimited contacts on every paid plan — you pay for sends, never per contact.
Every contact
Everything about a contact, on one screen.
Identity, custom fields, topic subscriptions, deliverability, and a full activity history — the whole picture without leaving the page. Add contacts by hand, over the API, or by importing a CSV.
Import in seconds
Upload a CSV and map columns to email, name, opt-out, and any custom field — existing contacts are skipped, not overwritten.
Full activity trail
Created, imported, subscribed, added to a segment, opted out of a topic — every change is logged per contact.
Deliverability at a glance
See whether a contact is mailable or suppressed, with the reason, right in the header.
Ada Lovelace
ada@example.com
Fields
Topics
Activity
- Subscribed to Product updates2d
- Added to segment “Beta”5d
- Imported from CSV3w
Custom fields
Store any attribute, your way.
Define text, number, boolean, and date fields once for your workspace. Set a default, reference them anywhere as {{ key }}, and rename a key later without breaking your contacts.
Four typed field kinds
Text, Number, Boolean, and Date — with an optional workspace default used when a contact has no value.
Safe to evolve
Rename a field key and it migrates across every contact; delete one and it's cleanly stripped everywhere.
Company
company
Text—Plan
plan
TextfreeSeats
seats
Number1Signup date
signup_date
Date—Beta access
beta_access
BooleanfalseSegmentation
Static lists and dynamic segments.
Curate a fixed list by hand, or save a filter that resolves live on every send. Match all or any of up to 25 conditions across built-in and custom fields — the count updates itself as your data changes.
Dynamic, always current
Rules like plan is “pro” or signup_date is on or after a date recalculate membership automatically — no re-tagging.
Rich operators
is / is not, contains, starts or ends with, greater/less than, and is-set checks — narrowed to each field's type.
“Everyone subscribed” built in
A managed segment of every still-subscribed contact is always ready — no setup, never stale.
Personalization
Personalize with every field.
Drop {{first_name}}, {{email}}, or any custom field into a subject line or body. Values resolve per recipient at send — and a missing required value is caught before the send, never delivered as a blank.
Built-in + custom fields
Reference name and email out of the box, plus any custom field by its key — in the subject and the body.
Caught before it sends
A referenced variable with no value returns a 422 up front, so a broken merge tag never reaches an inbox.
Fallbacks keep sends clean when a value is missing.
Subscription status
Consent, tracked at every level.
A global marketing switch, per-topic preferences, and per-list opt-outs — layered so recipients tune exactly what they hear about. Transactional mail keeps flowing regardless.
Topics recipients choose
Publish topics like Product updates or Promotions; contacts subscribe on a hosted, brandable preference page.
Opt-outs honored automatically
Global, per-topic, and per-list unsubscribes are respected on every future send — nothing to wire up.
Suppressions
A reputation backstop, on by default.
Every hard bounce and spam complaint suppresses that address automatically. Add addresses manually or over the API, and Unitpost skips them on every send — even if they were never a contact.
Automatic on bounce & complaint
Hard bounces and complaints are suppressed for you, protecting your sender reputation.
Reasons you can see
Bounce, Complaint, Unsubscribe, Manual, Import, or API — every suppression carries its reason, and you can un-suppress.
Developer-first
Manage your audience with code.
Sync contacts straight from your product. Create, update, unsubscribe, and remove over one REST API — the same audience powering your campaigns and transactional sends.
Kept in sync
Create or update contacts, push custom fields, and fetch their details; email is the unique key.
import { Unitpost } from "unitpost";
const unitpost = new Unitpost(process.env.UNITPOST_API_KEY);
// Send a contact from your product — email is the key.
await unitpost.contacts.create({
email: "ada@example.com",
firstName: "Ada",
lastName: "Lovelace",
unsubscribed: false,
properties: {
company: "Acme Corp",
plan: "pro",
seats: 12,
},
});Reach the right people
A segment for every send
From a curated newsletter list to a self-updating cohort of paid users — build the audience once and let it stay current.
Newsletter list
A static list you curate by hand or on signup — add or remove contacts one at a time or from a CSV.
Active paid users
A dynamic segment on plan is “pro” — membership recalculates itself as contacts upgrade or churn.
Recent signups
Filter signup_date is on or after a date, and it always reflects the last cohort with no manual upkeep.
Region targeting
Match a custom country or city field to send the right message to the right place.
Everyone subscribed
A built-in, always-fresh segment of every contact still opted in to marketing — ready to send to.
Topic subscribers
Let contacts opt in to “Product updates” or “Promotions” and send only to the ones who want it.
Beta cohort
Flip a beta_access boolean and build a segment around it to gate early features behind consent.
Win-back
Combine field filters to reach dormant accounts — then let opt-outs and suppressions keep it clean.
Questions
Common questions
How do I add or update a contact from my app?
POST /api/v1/contacts with an email plus optional first_name, last_name, unsubscribed, and a custom_fields map; PATCH /api/v1/contacts/{id} updates one. Email is the unique key per workspace, and the path accepts either the con_ id or the email address, so you can sync from your own database without storing our ids. Writes need the contacts:write scope, reads contacts:read.
What's the difference between a static and a dynamic segment?
A static segment is a list you curate — you add and remove contacts explicitly. A dynamic segment is a saved filter that is re-evaluated live every time it's read or sent to, so membership follows your data with no re-tagging. Because dynamic membership is computed, the add-member and remove-member endpoints return 409 for one; you change who's in it by editing the filter.
Is there a limit on how many contacts I can store?
Every paid plan has no contact cap and you're billed on emails sent, not list size — so an unengaged list costs you nothing to keep. The free plan stores up to 1,000 contacts. A segment filter is capped at 25 conditions in total, which is a query-complexity limit rather than a limit on your audience.
Can I store custom attributes on a contact?
Yes. Register a field once with POST /api/v1/contact-fields as text, number, boolean, or date with an optional workspace default, then set per-contact values in the contact's custom_fields map. Values must be scalars so they're safe to interpolate as {{ key }} in a subject or body and to use as segment-filter inputs. Renaming a field key migrates the value on every contact.
Does Unitpost handle unsubscribes and bounces for me?
Yes, at three levels. Every contact has a global marketing opt-out, per-topic preferences they manage on a hosted page, and per-list opt-out in the data model. Hard bounces and spam complaints suppress an address automatically, with the reason recorded. Suppressed addresses are skipped on every future send — even addresses that were never contacts, which you can add yourself over the API.
Are segment filters case-sensitive?
Yes — eq, contains, starts_with, and ends_with all compare exactly, so "Premium" does not match "premium". This is deliberate: custom fields live in a JSON column whose string filters can't express case-insensitive matching, and making built-in columns behave differently would mean the builder preview, the dashboard count, and the actual send could disagree. Normalize values on write if you need loose matching.
Bring your list and start sending
Free includes contacts, custom fields, segments, and topic-level opt-outs — with 3,000 emails a month and up to 1,000 contacts. Import a CSV and send. No credit card.