Email campaigns

Broadcast announcements and onboarding emails to your partners.

Email campaigns let you broadcast a one-off message — a welcome note, a product announcement, a monthly digest, or a reward bump — to your partner base. You write the campaign once, pick who receives it, preview it, and send. Emails go out through Resend as plain-text messages. Campaigns are managed by workspace admins from /<workspace>/campaigns.

In the dashboard

  1. ●

    Open Email Campaigns and click New campaign

    Go to /<workspace>/campaigns. Past campaigns are listed with a draft or sent badge. ClickNew campaign (top right) to open the composer sheet.

  2. ●

    Write your campaign

    On the Write your campaign step you can start from one of four templates — Welcome new partners, Product announcement, Monthly update, or New reward announcement — or write your own Subject and Message from scratch. Insert {{partner_name}} anywhere in the body to personalize each email with the recipient's name. Click Continue to save the draft and advance.

  3. ●

    Review & send

    On the Review & send step, choose an audience under Send to: Approved partners, Pending applicants, or All partners. The preview panel shows the subject and body with {{partner_name}} filled in with a sample name. Click Send now to send, or Save as draft to keep it for later. On success you'll see a toast with the recipient count.

A sent campaign records how many partners it reached (sentCount) and its send date, both shown on the campaign card.

Via the API / for agents

Campaigns are a two-call flow: first create a draft, then send it. Both calls are scoped to a workspace slug.

Create a draft:

POST /api/workspaces/<slug>/campaigns
Content-Type: application/json

{
  "programId": null,           // optional: limit to one program
  "subject": "Big news for our partners",
  "body": "Hi {{partner_name}}, ...",
  "targetStatus": "approved"   // "approved" | "pending" | null (all)
}

The response includes the new campaign's id. Use it to send:

POST /api/workspaces/<slug>/campaigns/<campaignId>/send

Send response:

{
  "sentCount": 42,
  "campaign": {
    "id": "...",
    "status": "sent",
    "sentCount": 42,
    "sentAt": "2026-07-05T12:00:00.000Z"
  }
}

The send endpoint resolves recipients from the workspace's partners: it filters by programId if set, by targetStatus if set, and — when targetStatus is null (all partners) — excludes any partner whose status is banned. Emails are sent in batches of 50 as plain text via Resend.

Gotchas

Only the first {{partner_name}} is replaced

The send route substitutes {{partner_name}} with a plain string replace, so only the first occurrence in the body is personalized. If you use the token more than once, later occurrences ship literally. Keep it to a single {{partner_name}} near the top. (The dashboard preview replaces all occurrences, so it can look fine while the actual email differs.)

Sending is one-shot and idempotent-ish

A campaign that's already sent returns 409 Already sent — you can't re-send it. If no partners match the filter you get 400 No recipients matched. Individual Resend failures are swallowed silently and simply don't count toward sentCount, so a lower-than-expected count means some deliveries failed.