---
title: "REST API: campaigns, segments, templates and reports"
description: Every REST route for segments, campaigns, templates, reports, the sending log, suppressions, sending services, settings and tools, with examples.
url: "https://hiveplugins.com/docs/hive-mail-rest-api-campaigns-segments-reports/"
updated: "2026-10-28"
category: Hive Mail
---

# REST API: campaigns, segments, templates and reports

All routes start with `/wp-json/hivemail/v1`. Sign in as described in [authentication](/docs/hive-mail-rest-api-authentication/); errors and paging are on [the overview](/docs/hive-mail-rest-api-reference/). 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:** `/send` starts 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](/docs/hive-mail-rest-api-automation-and-commerce/)) |

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](/docs/hive-mail-webhooks-and-api-keys/)) |
| 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"
```

Next: [Flows, recipes, forms and shops](/docs/hive-mail-rest-api-automation-and-commerce/), [Extending Hive Mail](/docs/hive-mail-extending-hive-mail/).
