Werkmail Docs
Contents

API

Lists and campaigns API

Broadcasts use lists + a campaign job on the broadcast route.

Lists

bash
curl -sS -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Newsletter"}' \
  "$BASE/api/practices/$PRACTICE_ID/lists"

curl -sS -H "Authorization: Bearer $TOKEN" \
  "$BASE/api/practices/$PRACTICE_ID/lists"

List payloads include subscriber_count and active_count.

Subscribers

bash
# DOI (default) — pending + confirm email
curl -sS -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email":"a@example.com"}' \
  "$BASE/api/practices/$PRACTICE_ID/lists/$LIST_ID/subscribers"

# already-consented import
curl -sS -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email":"a@example.com","status":"active"}' \
  "$BASE/api/practices/$PRACTICE_ID/lists/$LIST_ID/subscribers"

curl -sS -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"emails":["a@example.com","b@example.com"]}' \
  "$BASE/api/practices/$PRACTICE_ID/lists/$LIST_ID/subscribers/import"

curl -sS -H "Authorization: Bearer $TOKEN" \
  "$BASE/api/practices/$PRACTICE_ID/lists/$LIST_ID/subscribers"

curl -sS -X DELETE -H "Authorization: Bearer $TOKEN" \
  "$BASE/api/practices/$PRACTICE_ID/lists/$LIST_ID/subscribers/$SUB_ID"

Without status: active / skip_doi, create starts double opt-in. Public confirm: GET /api/public/confirm?token=….

Public subscribe (POST /api/public/subscribe) also starts DOI and does not return confirm_url.

Campaigns

bash
curl -sS -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": "'"$LIST_ID"'",
    "name": "April newsletter",
    "subject": "Praxis news",
    "text_body": "Hello",
    "html_body": "<p>Hello</p>",
    "route": "broadcast"
  }' \
  "$BASE/api/practices/$PRACTICE_ID/campaigns"

curl -sS -H "Authorization: Bearer $TOKEN" \
  "$BASE/api/practices/$PRACTICE_ID/campaigns"

The create response includes the campaign ledger row and a job_id. Campaigns require marketing eligibility (DKIM, warm-up, Impressum, consent).

Optional create fields: segment_id, ab_enabled, ab_metric (open or click), ab_sample_pct, ab_test_hours, variants.

A/B first wave sends only the sample. After the test window (or POST …/campaigns/{id}/ab-winner) the remainder receives the winner.

Method Path Purpose
GET /api/practices/{id}/campaigns List
GET / PATCH /api/practices/{id}/campaigns/{campaignID} Read or update a draft
POST …/start Queue now
POST …/schedule Body scheduled_at (RFC3339)
POST …/cancel Cancel
POST …/test Test send
GET …/stats Delivery stats
GET …/links Link clicks
GET / PUT …/variants A/B variants
DELETE /api/practices/{id}/lists/{listID} Delete a list
DELETE …/lists/{listID}/subscribers/{subID} Remove a subscriber

Merge tags and {{#if}} / {{#unless}} apply per recipient from the CRM contact.

Journeys: GET/POST /api/practices/{id}/journeys. See the Journeys guide.

BI CSV: GET /api/practices/{id}/exports/bi?kind=stats|campaigns|bounces|scores|audit.

View this page as Markdown · llms.txt · full corpus