All routes start with /wp-json/hivemail/v1. Sign in as described in authentication; errors and paging are on the overview. Capability letters: V hivemail_view_audience, A hivemail_manage_audience, C hivemail_manage_campaigns, F hivemail_manage_automations, S hivemail_manage_settings, X manage_hivemail. Routes that accept PUT also accept POST and PATCH.
Segments #
A segment is a saved filter: rules = { match: "all" | "any", conditions[] }, at most 30 conditions. Who is in it is worked out each time; only the count is cached.
| Method | Route | Cap | Purpose |
|---|---|---|---|
| GET | /segments |
V | search, orderby (name, cached_count, updated_at, created_at, id), order, page, per_page (max 100) |
| POST | /segments |
A | name, rules. 201, counted. 400 hivemail_invalid_segment with data.errors.rules or .name |
| GET | /segments/conditions |
V | What the rule editor can build: condition types, operators, custom fields, max_conditions |
| POST | /segments/preview |
V | rules in; { rules (cleaned), total, subscribed, sample[≤10] } out |
| GET | /segments/{id} |
V | One segment with rules, count, counted_at |
| PUT | /segments/{id} |
A | name, rules. New rules are recounted |
| DELETE | /segments/{id} |
A | Only the saved filter goes; contacts are untouched |
| POST | /segments/{id}/refresh |
V | Count it now |
Contacts in a segment: GET /contacts?segment={id}.
curl -u "admin:abcd efgh ijkl mnop qrst uvwx" -X POST -H "Content-Type: application/json" \
-d '{"name":"VIPs who clicked","rules":{"match":"all","conditions":[{"type":"tag","op":"has","value":7},{"type":"engagement","op":"clicked","days":90,"campaign":0}]}}' \
"https://example.com/wp-json/hivemail/v1/segments"
Campaigns #
All campaign routes need C. States: draft, scheduled, sending, paused, sent, cancelled, failed. Only a draft can be changed (PUT otherwise is 409 hivemail_campaign_state). Scheduling runs the checklist, compiles the email once and freezes it.
| Method | Route | Purpose |
|---|---|---|
| GET | /campaigns |
status (one or comma-separated), search, orderby, order, page, per_page (max 100). Answers counts per status too |
| POST | /campaigns |
name (required), subject, subject_b, preheader, from_name, from_email, reply_to, type (regular, ab), ab_split (10 to 90), audience, utm, and template_id or design. 201, a draft |
| POST | /campaigns/recipients |
audience in; { total, recipients, skipped{} } out, before saving |
| GET | /campaigns/{id} |
Everything, with design, stats, dates (UTC) |
| PUT | /campaigns/{id} |
Drafts only; only the keys you send change |
| DELETE | /campaigns/{id} |
409 while scheduled, sending or paused |
| GET | /campaigns/{id}/checklist |
{ ready, items[{id, level, message}], recipients, total, skipped{} } |
| GET | /campaigns/{id}/preview |
contact_id, variant (a, b). The email one person would get |
| POST | /campaigns/{id}/test |
to, contact_id, variant. Sends a test now |
| POST | /campaigns/{id}/schedule |
scheduled_at: YYYY-MM-DD HH:MM in the site time zone, or an ISO time with Z or an offset; none means now. 400 hivemail_campaign_not_ready carries data.checklist |
| POST | /campaigns/{id}/send |
Schedule for now and start |
| POST | /campaigns/{id}/unschedule |
Back to draft |
| POST | /campaigns/{id}/pause, /resume, /cancel |
409 hivemail_campaign_state from the wrong state |
| POST | /campaigns/{id}/progress |
Work on the send for up to 3 s and answer the campaign with fresh stats |
| POST | /campaigns/{id}/duplicate |
201, a copy as a draft |
| POST | /campaigns/{id}/switch |
editor: change a draft's email to another editor |
| POST | /campaigns/{id}/save-as-template |
name. 201 |
audience is { all, lists[], tags[], segments[], exclude: { lists[], tags[], segments[] } } (up to 100 ids per group). Recipients are subscribed contacts who are not in the trash and not suppressed; the worker checks again at send time.
# 1. Create a draft from template 5 for list 1
curl -u "admin:abcd efgh ijkl mnop qrst uvwx" -X POST -H "Content-Type: application/json" \
-d '{"name":"October news","subject":"News for {{first_name|you}}","template_id":5,"audience":{"lists":[1]}}' \
"https://example.com/wp-json/hivemail/v1/campaigns"
# 201 {"id":12,"name":"October news","status":"draft","template_id":5,"audience":{"all":false,"lists":[1],...},...}
# 2. Check it
curl -u "..." "https://example.com/wp-json/hivemail/v1/campaigns/12/checklist"
# 3. Schedule it (a local time in the site's time zone). Answers the campaign with
# "status":"scheduled" and "compiled":true; a campaign that fails the checklist
# answers 400 hivemail_campaign_not_ready with data.checklist
curl -u "..." -X POST -H "Content-Type: application/json" \
-d '{"scheduled_at":"2026-11-02 09:00"}' \
"https://example.com/wp-json/hivemail/v1/campaigns/12/schedule"
<?php
// Send now, from PHP.
$response = wp_remote_post(
'https://example.com/wp-json/hivemail/v1/campaigns/12/send',
array( 'headers' => array( 'Authorization' => 'Basic ' . base64_encode( 'admin:abcd efgh ijkl mnop qrst uvwx' ) ), 'timeout' => 20 )
);
Warning:
/sendstarts real mail to real people and cannot be recalled. Test against a small list first.
Templates, designs and the brand kit #
A design is JSON with a mode (blocks, classic, text or html) saying which editor made it.
| Method | Route | Cap | Purpose |
|---|---|---|---|
| GET | /templates |
C | search, editor, orderby (name, updated_at, created_at, id), order, page, per_page |
| POST | /templates |
C | name and design, starter or editor. 201 |
| GET | /templates/starters |
C | Ready-made designs; preview=1 adds each one's HTML |
| GET | /templates/{id} |
C | The full template |
| PUT | /templates/{id} |
C | name, design, version. A stale version is 409 hivemail_template_conflict |
| DELETE | /templates/{id} |
C | Campaigns keep their own copy |
| POST | /templates/{id}/duplicate |
C | 201 |
| POST | /templates/{id}/test |
C | to, subject, contact_id |
| POST | /templates/{id}/switch |
C | editor, version. The old version goes to the history |
| GET | /templates/{id}/revisions |
C | The history, newest first |
| GET | /templates/{id}/revisions/{rid} |
C | One version |
| POST | /templates/{id}/revisions/{rid}/restore |
C | Put it back |
| GET | /design/blocks |
C | Block types, fonts, settings the editors use |
| POST | /design/render |
C | design, contact_id. Answers the cleaned design, html, text, size, warnings[] |
| GET, PUT | /brand-kit |
S | Read or save the brand kit |
Reports #
| Method | Route | Cap | Purpose |
|---|---|---|---|
| GET | /campaigns/{id}/report |
C | Funnel, opens, clicks, unsubscribed, bounced, complained, A/B variants, most clicked links, timeline |
| GET | /campaigns/{id}/report/contacts |
C | kind (sent, opened, clicked, unsubscribed, bounced, failed, skipped), page, per_page (max 500): the people behind a number |
| GET | /reports/overview |
C | days (30 or 90): totals, a per-day timeline, the period's campaigns |
| GET | /flows/{id}/report |
F | A flow's report (flows and shops) |
Rates are percentages of sent. Revenue is a list per currency, never added across currencies.
curl -u "admin:abcd efgh ijkl mnop qrst uvwx" \
"https://example.com/wp-json/hivemail/v1/campaigns/12/report/contacts?kind=clicked&per_page=50"
Sending log, test email and suppressions #
| Method | Route | Cap | Purpose |
|---|---|---|---|
| GET | /sending/status |
S | The delivery method, queue counts, readiness checks, merge tags |
| POST | /sending/test |
S | to. Sends the sample email through the chosen method now |
| POST | /sending/check-domain |
S | domain (optional). Look up SPF, DKIM and DMARC |
| GET | /sending/bounce-info |
S | provider (generic, mailgun, sendgrid). The webhook address, the steps, what has arrived |
| GET | /sending/log |
C | status (queued, paused, processing, sent, failed, skipped), search, campaign, page, per_page (1 to 100) |
| POST | /sending/messages/{id}/retry |
C | Re-queue one failed message (409 if it is not failed) |
| POST | /sending/retry-failed |
C | Re-queue every failed message. Answers { requeued } |
| GET | /suppressions |
A | search, reason (bounce, complaint, manual), page, per_page |
| POST | /suppressions |
A | email, reason. 201 |
| DELETE | /suppressions/{id} |
A | Take an address off the list; the contact keeps its status |
| GET | /webhooks/info |
S | The bounce webhook addresses and secret (Webhooks) |
| POST | /webhooks/rotate |
S | A new generic-webhook secret |
| POST | /webhooks/{provider} |
secret | generic, mailgun or sendgrid |
Settings, system and tools #
Delivery through Mailgun or SendGrid is chosen and keyed through the sending settings group; secret values are never returned, only ••••••••.
| Method | Route | Cap | Purpose |
|---|---|---|---|
| GET | /settings/{group} |
S | Schema and values. Groups include general, sending, tracking, compliance, forms, notifications, woocommerce, edd |
| PUT | /settings/{group} |
S | Save values; the mask sent back means unchanged, an empty string removes a secret |
| GET | /system/scheduler, POST /system/scheduler/run |
S | Scheduler state; run one tick |
| GET | /system/setup |
X | The first-steps card |
| GET | /tools/status, /tools/logs, /tools/cleanup/preview, /tools/settings-export, /tools/wizard |
S | Health, log, clean-up preview, settings export |
| POST | /tools/repair, /tools/cleanup, /tools/settings-import, /tools/wizard, /tools/reset |
S | Repair tables, clean up, import settings, wizard, delete all data (needs HIVEMAIL_ALLOW_RESET) |
| DELETE | /tools/logs |
S | Clear the log |
| POST | /compliance/confirmations/send-pending |
A | Send the confirmation email to pending contacts |
| POST | /compliance/confirmation/preview, /compliance/confirmation/test, /compliance/footer/preview |
S | Previews and a test of the compliance emails |
| GET, POST | /compliance/pages |
S | The public unsubscribe, preferences and confirmation pages |
| POST | /notifications/sample |
S | Send a sample alert email |
# Read the Sending tab
curl -u "admin:abcd efgh ijkl mnop qrst uvwx" "https://example.com/wp-json/hivemail/v1/settings/sending"