# Handsent > Handsent sends personal, one-to-one email to a list from your own Gmail: one email per person, merged with their details, at a human pace, with follow-ups in the same thread that stop when someone replies. It reads Google Sheets and CSVs, writes status back to the sheet, tracks replies, bounces and unsubscribes without tracking pixels, and exposes everything through a REST API, signed webhooks and an MCP server. Made by Buildnode. Free during early access. Handsent is not a newsletter platform (it does not send from its own servers to subscribers) and not transactional email (it is not for receipts or password resets). It is for people who would have written each email themselves if they had the afternoon: customers, leads who asked to hear from you, partners, candidates, investors, and local businesses with a published contact. Base URLs: app and API at https://handsent.buildnode.io. REST API at https://handsent.buildnode.io/api/v1 (bearer API key). MCP at https://handsent.buildnode.io/api/mcp (Streamable HTTP, same bearer key). ## Guide - [Full guide](https://handsent.buildnode.io/llms-full.txt): setup, what it can do, adding it to your project, the API with curl examples, the MCP server with tool list and client config, and **§6 "Wiring an app into Handsent"**: the integration recipe (push on the event, skip on conversion, merge-field discipline, and the traps in the seams). Read §6 first if you are connecting an app. Everything below is a summary. - [OpenAPI 3.1](https://handsent.buildnode.io/api/v1/openapi.json): the machine-readable API description, served by the app. ## How to set up - Sign in with Google at https://handsent.buildnode.io. Three scopes: gmail.send (sending your campaigns and tests), gmail.readonly (reading only threads Handsent started, plus a draft you choose as a template) and spreadsheets (the sheet you connect, read rows and write status back). - Add a list: paste a Google Sheet URL, upload a CSV, paste rows, or create an API list and push contacts. - Set the postal address on the Team page (Mailing address tab). Every campaign body must contain a mailing address and an unsubscribe instruction before it can start. - Create a campaign: pick an inbox and a list, write the subject and body with {{merge_fields}}, add follow-ups, send yourself a test, start. ## What it can do - Campaigns with follow-ups threaded under the first email; the sequence ends when the person replies. - Pacing: per-campaign daily and hourly caps, a random gap between sends, a send window and weekdays in a timezone; a daily cap per inbox. Defaults: 90 a day, 30 an hour, 45 to 150 seconds apart, 09:00 to 17:00, Monday to Friday. - Scheduling: a start time, and waves (release N contacts every H hours). - Suppressions for the whole workspace: replies of STOP or unsubscribe, bounces, and addresses you add. A cooldown (default 90 days) between campaigns to the same address. - Reply tracking by reading only the threads Handsent started. No open or click tracking. - Sheet write-back of each row's status; typing "skip" in a row holds it. - Templates with rich text and resizable images (drag a corner, or Small / Best fit / Original), or a Gmail draft as the source. Subject and body variants for the first email. - Teams: one workspace, owner, admin and member roles, shared inboxes, lists, templates, suppressions, API keys and webhooks, and an audit log. ## How to add it to your project - The shape: your app owns who and when (identity, the triggering event, the conversion); Handsent owns the email (copy, pacing, follow-ups, replies, suppression, footer). Keep copy in Handsent so it can be edited without deploying your app. - Two calls carry a whole integration: `POST /lists/{id}/contacts` when someone becomes worth emailing, `POST /lists/{id}/contacts/skip` when they convert. Push the full field set with `"mode":"merge"`, lowercase the address, and keep a `pushed_at` watermark on your side stamped after a successful push. - Create an API key on the Team page (API keys tab). Scopes: read (GET only), write (create and change lists, contacts, templates, campaigns, test sends, pause), admin (start campaigns, remove suppressions, manage webhooks). - Send it as `Authorization: Bearer hs_...` (or `x-api-key`). All bodies and responses are JSON. Errors are `{ "error": { "code", "message", "issues?" } }`. - Webhooks: POST /api/v1/webhooks with a URL and event types; the signing secret is returned once. Each delivery carries `Handsent-Signature: t=,v1=.">` and `Handsent-Event: `, with retries and backoff. ## How to use the API - Lists: GET/POST /lists, GET/DELETE /lists/{id}, GET/POST /lists/{id}/contacts, POST /lists/{id}/contacts/skip (bulk skip/unskip by email), GET/PATCH/DELETE /lists/{id}/contacts/{email}. Inboxes: GET /inboxes (the `inboxId` a campaign needs). - Templates: GET/POST /templates, GET/PATCH/DELETE /templates/{id}. - Campaigns: GET/POST /campaigns, GET/PATCH /campaigns/{id}, POST /campaigns/{id}/test, /start, /pause, /dry-run, /sync, GET /campaigns/{id}/contacts, POST /campaigns/{id}/contacts/{email}/reset. - Feeds: GET /events (ascending by seq, `since` cursor), GET /sends, GET /audit. - Suppressions: GET/POST/DELETE /suppressions. Webhooks: GET/POST /webhooks, DELETE /webhooks/{id}, POST /webhooks/{id}/test. Account: GET /me. - Pagination: list and campaign collections use `cursor` and return `nextCursor`; contact, send and suppression collections use `limit` and `offset` and return `nextOffset`; events and audit use `since` and return `nextCursor` (a seq to pass back as `since`). ## How to use the MCP - Endpoint https://handsent.buildnode.io/api/mcp, Streamable HTTP (POST only, stateless, JSON responses), `Authorization: Bearer hs_...`. - Claude Code: `claude mcp add --transport http handsent https://handsent.buildnode.io/api/mcp --header "Authorization: Bearer hs_..."`. - Tools: list_lists, get_list, create_list, add_contacts, skip_contact, skip_contacts, unskip_contact, list_inboxes, list_campaigns, campaign_report, campaign_contacts, pause_campaign, resume_campaign, send_test, dry_run, recent_events, add_suppressions, remove_suppressions, list_templates, save_template, create_batch, audit_log. ## Policies - [Privacy policy](https://handsent.buildnode.io/privacy): what is stored, Google Limited Use, deletion. - [Terms](https://handsent.buildnode.io/terms). - Contact: hello@buildnode.io. Buildnode Inc., 2015 Main St, Vancouver, BC, Canada.