Send your first campaign
Make a template, choose an audience, run the pre-send checks, test it and send or schedule.
What you need first
A healthy connection and a verified sender (see Connect a sending provider).
A postal address on the workspace (set in the Quickstart). Marketing email needs one in its footer.
People with marketing consent, on a list or in a segment.
A key with
templates:write,campaigns:writeandcampaigns:send.
1. Make a template
curl -s -X POST "$BASE/v1/templates" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: tpl-update-nov" \
-d '{"name":"Product update: November","kind":"blocks",
"version":{"subject":"{{ profile.first_name | default: \"Hi\" }}, what is new in November","preheader":"Three things.",
"body":{"kind":"blocks","doc":{"blocks":[
{"type":"text","html":"<h1>What is new</h1><p>...</p>"},
{"type":"button","label":"Read more","href":"https://example.com/changelog"},
{"type":"text","html":"<p><a href=\"{{ unsubscribe_url }}\">Unsubscribe</a></p>"}]}}}}'Check how it renders for one person:
curl -s -X POST "$BASE/v1/templates/<templateId>/render" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-d '{"profile":{"first_name":"Dana"}}'2. Create the campaign
curl -s -X POST "$BASE/v1/campaigns" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: camp-update-nov" \
-d '{"name":"Product update: November","channel":"email","purpose":"marketing",
"audience":{"includeListIds":["<listId>"]},"templateId":"<templateId>",
"route":{"connectionId":"<connectionId>"},"tracking":{"opens":true,"clicks":true},
"utm":{"source":"acme","medium":"email","campaign":"update-2026-11"}}'Use includeSegmentIds to send to a segment. Always give a route.
3. Run the checks
curl -s "$BASE/v1/campaigns/<campaignId>/checklist" -H "Authorization: Bearer $HERMETICA_API_KEY"
curl -s "$BASE/v1/campaigns/<campaignId>/content-check" -H "Authorization: Bearer $HERMETICA_API_KEY"
curl -s -X POST "$BASE/v1/campaigns/<campaignId>/recipient-estimations" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" -d '{}'
curl -s "$BASE/v1/campaigns/<campaignId>/recipient-estimations/latest" -H "Authorization: Bearer $HERMETICA_API_KEY"The estimate shows how many people will get it, and how many are left out as suppressed, without consent or blocklisted.
4. Send a test
curl -s -X POST "$BASE/v1/seed-lists" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"Internal seeds","emails":["you@example.com"]}'
curl -s -X POST "$BASE/v1/campaigns/<campaignId>/test-send" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-d '{"seedListId":"<seedListId>"}'Test sends skip quiet hours, so they arrive at once, even at night.
5. Get it approved (optional)
A teammate can review the campaign before it goes out. Submit it, and someone else approves or rejects it with a comment. The person who submitted cannot approve their own campaign, and approving needs the campaigns:approve scope.
curl -s -X POST "$BASE/v1/campaigns/<campaignId>/approval/submit" -H "Authorization: Bearer $HERMETICA_API_KEY"
curl -s -X POST "$BASE/v1/campaigns/<campaignId>/approval/approve" \
-H "Authorization: Bearer $REVIEWER_API_KEY" -H "Content-Type: application/json" -d '{"comment":"Looks good"}'A pending or rejected campaign cannot be scheduled. Editing an approved campaign sends it back to unapproved, so the reviewer always signed off on what is sent. To require approval for every campaign, set {"campaignApprovalRequired":true} with PATCH /v1/content-settings.
6. Send or schedule
curl -s -X POST "$BASE/v1/campaigns/<campaignId>/schedule" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-d '{"schedule":{"at":"2026-11-04T15:00:00Z","tz":"America/New_York"}}'Or send now with POST /v1/campaigns/<campaignId>/send-now. POST .../unschedule stops it before it starts.
7. Read the results
GET /v1/campaigns/<campaignId>/report gives deliveries, opens, clicks and unsubscribes. /recipients lists each person and status.
For an A/B subject test, set variants with PUT /v1/campaigns/<id>/variants/a and /b, then PATCH the campaign with {"abTest":{"testPercent":50,"metric":"clicks","waitHours":4,"auto":true}}.
Next: Build a welcome journey.