npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

posthorn

v0.2.11

Published

Domain setup, mailbox creation, and email warmup from the command line

Readme

Posthorn

Posthorn spins up cold-email infrastructure: sending domains, mailboxes, SPF/DKIM/DMARC, and inbox warmup. It runs on accounts you own and is drivable entirely by an AI agent.

It's a pure orchestration layer: you own your Cloudflare account, your Google Workspace, your domains, and your mailboxes. Posthorn automates the setup and warmup on top of accounts you control. It never owns or bills for any of it.

Quick start with an AI agent (recommended)

Posthorn is built to be driven by an agent (Claude Code, Codex, Cursor, etc.). Paste this into your agent:

I want to set up cold-email infrastructure: sending domains, mailboxes, and inbox warmup. Use the Posthorn CLI to do it. First run npm install -g posthorn then posthorn guide, read the guide, and walk me through the whole setup step by step. Run the commands for me and tell me whenever I need to do something in my browser.

The agent reads posthorn guide (which prints this document) and orchestrates the rest.

Install

npm install -g posthorn

Or run any command without installing via npx posthorn <command>.


Agent playbook

If you're an AI agent driving the posthorn CLI for a user, this is the knowledge you need that --help alone doesn't give you. Read it fully before starting. Run posthorn guide any time to reprint it.

The platform is a pure orchestration layer: the USER owns their Cloudflare account, their Google Workspace, their domains, and their mailboxes. Posthorn never owns or bills for any of it.

The flow: walk it like a setup wizard

Go step by step. Ask one question at a time, only when the step needs it, and do as much as possible yourself. Don't front-load questions.

Step 1. posthorn auth register. Instant API key; no email or signup info needed, and there are no account tiers. Nothing to ask.

Step 2. Domain. Ask: "Do you need a new domain for your emails, or will you use an existing one for sending?"

  • NEW domain (the purchase always happens on the user's own Cloudflare account and card; Posthorn never owns or bills for domains): a. They need a Cloudflare account with a payment method (they pay Cloudflare directly for the domain, ~$10/yr). Browser step: create the API token (below), then posthorn accounts cloudflare <token>. b. posthorn domains check name1.com name2.io --cloudflare <id> (availability
    • price) → posthorn domains reputation <pick> (vets Spamhaus blocklist, reputation score, and prior use; verdicts: clean / caution / avoid. Run it before buying; you can't tell a tainted domain from its name.) → posthorn domains buy <pick> --cloudflare <id> --contact '{...}'
  • EXISTING domain. If it runs their live website or real email, recommend a dedicated sending domain instead. Two ways to connect it; either way the domain stays registered where they bought it, only nameservers change: a. Their own Cloudflare: they manage the domain's DNS in their own Cloudflare account. Needs the API token (below); and if the domain isn't on their Cloudflare yet, they add it at dash.cloudflare.com and point nameservers there first. Then posthorn domains connect <domain> --cloudflare <id>. b. Posthorn-managed DNS: no Cloudflare account to create or manage; Posthorn hosts the domain's DNS for them (free). posthorn domains managed <domain> → they set the 2 printed nameservers at their registrar → posthorn domains activate <id>. Note: Posthorn then hosts ALL of the domain's DNS records (website records included), so it fits domains dedicated to email.

Step 3. Google Workspace. Ask: "Do you have a Google Workspace you can add new domains and mailboxes to, or do you want to set up a new one?"

  • Existing Workspace: delegation browser step (below), then posthorn accounts workspace <admin-email>.
  • New Workspace: walk them through the signup (browser step below: "Creating a new Google Workspace org"), then delegation. Tell the user the org signup is also one-time; it gets reused for every future domain and mailbox. (Delegation is per org, not per domain, so with an existing org this step can happen any time, even before the domain exists. The domain pipeline auto-adds and verifies the new domain inside their org.)

Step 4. Wait for the domain: poll posthorn domains get <id> until status ready (minutes to 24h; poll every 30-60s, don't hammer). MX/SPF/DMARC are configured automatically. Statuses progress: pending_* → purchased → dns_configuring → dns_configured → dns_verified → workspace_verifying → workspace_verified → ready.

Step 5. DKIM. Browser step below; once per domain, needs the domain ready.

Step 6. posthorn mailboxes create <domain-id> --email ... --first ... --last ...

Step 7. posthorn warmup start <mailbox-id>

Dependencies: you CANNOT create a mailbox until the domain status is ready.

Run posthorn auth status --json any time to see where things stand. State is stored locally, so you can stop and continue any time.

The external/manual steps (things that happen OUTSIDE the CLI)

These are the steps you must GUIDE THE USER through in their browser. Give exact click-by-click instructions. Before each browser step, share with the user that this is a one-time setup, e.g. "This is a one-time setup step; you won't need to do this again." The repetition model, so you can answer follow-ups:

  • Cloudflare API token: once ever
  • Workspace signup (only when creating a new org): once ever
  • Workspace delegation: once per Workspace org
  • DKIM: once per domain
  • Everything else (domains, mailboxes, warmup): fully automated, no browser

Cloudflare API token (one-time, for "buy new" or "own Cloudflare" domains)

  • Tell the user: "This is a one-time setup; you won't need to do this again."
  • dash.cloudflare.com/profile/api-tokens → Create Token → Custom Token
  • Permissions: Account>Account Settings>Read, Account>Registrar: Domains>Admin, Zone>Zone>Edit, Zone>DNS>Edit.
  • Account Resources: Include > All accounts
  • Zone Resources: Include > All zones
  • Do NOT add Billing permissions; they are not needed. Domain purchases charge the payment method already on the Cloudflare account, which is a dashboard setting, not a token permission.
  • Then: posthorn accounts cloudflare <token>
  • This token is only for Cloudflare (domains and DNS). Google Workspace is NOT connected with this token; it has its own separate one-time step below (domain-wide delegation, no token involved).
  • For domain PURCHASES, the user also needs a payment method on their Cloudflare account (they pay Cloudflare directly; Posthorn never bills for domains).

Creating a new Google Workspace org (only when the user has none)

Tell the user: one-time, about 5 minutes, needs a credit card (Business Starter is ~$7/user/month with a free trial). Walk them through workspace.google.com → Get started:

  1. Business name, employee count, region. Any values are fine.
  2. Current email: any email they already read (personal Gmail is fine; it's just the contact for signup).
  3. When asked about a domain, choose the option saying they ALREADY HAVE a domain, and enter the sending domain from step 2 of the flow. Do NOT buy a domain from Google here, even if offered: the domain must stay at their registrar/Cloudflare so Posthorn can manage its DNS.
  4. Create the admin user, e.g. admin@. This account is the org's SUPER-ADMIN: they should save the password, and this is the email for posthorn accounts workspace <admin-email> later.
  5. Pick Business Starter, add payment, finish signup.
  6. If Google prompts to VERIFY the domain or set up MX records, skip it ("I'll do this later" / close the wizard). Posthorn does domain verification and MX automatically once delegation is set up.
  7. Continue to domain-wide delegation (next section), signed in as that new super-admin.

Google Workspace domain-wide delegation (one-time per Workspace org)

  • Tell the user: "This is a one-time setup for your Workspace; you won't need to do this again."
  • admin.google.com → Security → Access and data control → API controls → Domain-wide delegation → Add new
  • Client ID: 110137377718772968374
  • OAuth scopes (paste all, comma-separated): https://mail.google.com/,https://www.googleapis.com/auth/admin.directory.user,https://www.googleapis.com/auth/admin.directory.domain,https://www.googleapis.com/auth/siteverification
  • Must be done signed in as a SUPER-ADMIN of that Workspace org, and the email passed to the CLI must be that super-admin's. Then run: posthorn accounts workspace <admin-email>
  • This replaces OAuth entirely: no consent screen, no app verification, no test users.

Nameservers (only for "managed DNS" or moving a domain to Cloudflare)

  • The CLI prints 2 nameservers. The user sets them at their domain REGISTRAR (where they bought the domain), replacing the existing nameservers.
  • Propagation takes minutes to 24h. Check with posthorn domains activate <id> (managed) or by polling posthorn domains get <id>.

DKIM (per domain, Google has no DKIM API)

Tell the user: "This is a once-per-domain step; new mailboxes on this domain won't need it." If you have browser-automation tools, do it for the user:

  • Navigate to https://admin.google.com/ac/apps/gmail/authenticateemail (the URL may need /u/N/ for the right account slot, verify the "Selected domain" on the page matches).
  • If status is "Authenticating email with DKIM" → already done, skip.
  • Otherwise click GENERATE NEW RECORD → GENERATE (defaults: 2048-bit, "google" prefix). Read the TXT record value (starts with v=DKIM1; k=rsa; p=...).
  • Add it to DNS as a TXT record named google._domainkey..
  • Click START AUTHENTICATION on the admin page. If no browser tools: have the user do the above and paste you the TXT value, then add it to their DNS.

Mailboxes & sending

  • Create: posthorn mailboxes create <domain-id> --email [email protected] --first John --last Smith Returns a one-time password (Google Workspace login). Save it (not shown again).
  • Credentials for IMAP/SMTP are auto-provisioned via the service account (domain-wide delegation). Google mailboxes need no per-mailbox setup.
  • Send: posthorn send <mailbox-id> --to [email protected] --subject "Hi" --body "..."

There is no email-verification step anywhere: connecting your own Cloudflare and Workspace IS the identity. Once a mailbox exists, sending and warmup work.

Warmup

  • posthorn warmup start <mailbox-id> → joins the shared warmup pool and runs continuously until paused
    • Volume and reply behavior are platform-managed (ramps from 2/day up to 5/day, then holds; peers reply to ~30% of warmup mail). Not configurable: the pool is shared, so settings are tuned for everyone's deliverability.
  • posthorn warmup stats <campaign-id> → placement rate, reputation, daily breakdown
  • posthorn warmup list → all campaigns
  • Warmup never fully stops on its own, pause with posthorn warmup pause <id>.

Feedback (bugs, feature requests)

posthorn feedback --type bug|feature|question|other "<message>"

If you hit a bug, missing capability, or rough edge while driving this CLI, report it; it goes straight to the Posthorn team. Agents: you are encouraged to file feedback yourself when something doesn't work the way you expected (include the command you ran and what you expected).

Whenever you or the user get stuck, file the issue with posthorn feedback.

Tips for agents

  • Read commands auto-detect output: when stdout isn't a TTY (i.e. you're an agent capturing output), they emit JSON automatically, no flag needed. Humans in a terminal get formatted text. Force either way with --json / --pretty.
  • Every command stores state locally (~/.config), so the user doesn't re-enter keys.
  • Translate everything into plain English for the user. Never show them raw JSON or ask them to run curl, you run the CLI on their behalf.