Skip to content

Send activation and onboarding emails with your agent

How do I send activation emails for my SaaS? Connect Sendocado to your agent, add signups from your app, and set live a welcome email and follow-ups that stop when users finish onboarding. An agent can follow this page from start to end.

View as Markdown

Activation emails here are the emails that get a new user to use your product: a welcome, then follow-ups. They are not the email that verifies an address.

What you build

  • New users get a welcome email right away, a follow-up on day 3 and a check-in on day 7.
  • A user who finishes onboarding gets no more of these emails.
  • A user who replies leaves the campaign, and the reply lands in your Replies inbox.

What you need

  • A Sendocado account. Sign in once at https://sendocado.com/login with Google or an email link.
  • An email provider account: Resend, Amazon SES, Postmark, SendGrid, Mailgun, an SMTP server or Gmail.
  • Access to your DNS host, to add the records for your sending domain.
  • Access to your product’s code, to add two API calls.

1. Connect your agent

In Claude Code, run this command, then type /mcp and sign in:

Add the server
claude mcp add --transport http sendocado https://sendocado.com/api/mcp

Cursor, Claude and other clients: Sendocado for agents.

2. Decide what “finished onboarding” means

Pick the one action after which a new user gets value, for example “connected their first project”. Your app tags the contact activated at that moment. Agent: ask the user for this action. Do not guess it.

3. Create the project and set the postal address

Call create_project with a name and a time zone, or list_projects if the user already has one. Then set the postal address with update_project, sending every field back. Marketing email cannot go out without the address: the law asks for it in every footer.

4. Connect the sender

Ask the user for the provider credentials. Test them with check_sender, which saves nothing, then save them with update_sender, with the From name and address people will see. Never invent credentials. Gmail connects in the app only, in the browser.

5. Verify the sending domain

create_sending_domain returns the DNS records for the domain of the From address. Show them to the user, who adds them at the DNS host. After that, check_sending_domain asks the provider again; Sendocado also checks every 10 minutes. DNS changes can take hours to show.

6. Add signups from your app

Your app makes one REST call when someone signs up, and one when they finish onboarding. Both use an API key from Settings → API keys, sent as a Bearer token.

At signup, create the contact with the tag trial:

Create a contact at signup
curl -X POST "https://sendocado.com/api/v1/projects/$PROJECT_ID/contacts" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "maya@example.com",
  "first_name": "Maya",
  "last_name": "Patel",
  "timezone": "Europe/London",
  "tags": ["trial"],
  "attributes": {
    "plan": "trial",
    "company": "Northwind"
  }
}'

At finished onboarding, send the same email to the batch route with the tag activated. The batch route creates or updates by email, adds tags and never removes them, so the contact keeps trial and gains activated. It takes up to 1,000 contacts. The sample below sends two; your app sends one, with its email and "tags": ["activated"], null for the names and time zone, and {} for attributes:

Add or update contacts
curl -X PUT "https://sendocado.com/api/v1/projects/$PROJECT_ID/contacts/batch" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "contacts": [
    {
      "email": "maya@example.com",
      "first_name": "Maya",
      "last_name": null,
      "timezone": null,
      "tags": ["customer"],
      "attributes": {
        "plan": "pro"
      }
    },
    {
      "email": "leo@example.com",
      "first_name": "Leo",
      "last_name": "Martin",
      "timezone": "Europe/Paris",
      "tags": ["trial"],
      "attributes": {}
    }
  ]
}'

7. Create the campaign

Get the emails from the user first; do not invent the copy. Then call create_campaign with is_stopped_on_reply set to true, this audience and three steps:

Audience: tag has trial, tag has not activated
[
  {
    "filters": [
      { "type": "tag", "op": "has", "tag": "trial" },
      { "type": "tag", "op": "has_not", "tag": "activated" }
    ]
  }
]
  • The welcome, with delay_days 0: it goes out when the contact joins.
  • The follow-up, with delay_days 3: day 3.
  • The check-in, with delay_days 4: day 7, because each delay counts from the step before.

create_campaign makes a draft. Nothing sends while it is a draft. A contact who gets the tag activated stops matching the audience and leaves the campaign.

8. Check it with the user

  • preview_audience counts who matches now, with a few of them.
  • send_test_email sends each email to the user’s own inbox.
  • get_campaign_readiness lists what stands between the campaign and going live. An empty list means it can go live.

Show the user the emails and the count.

9. Set it live after the user says yes

Call set_campaign_status with live. Going live emails real people: every contact who matches joins at once, and new signups join within seconds.

10. Read the results

  • get_campaign_stats, after a week: sends, opens, clicks and replies for each step.
  • list_replies: what people wrote back.
  • get_send: what happened to one email, and why it did not arrive.

11. Change an email later

Read the campaign with get_campaign, then call update_campaign_step on that one step. Never re-create a step to change it: its results stay with its id.

What the agent cannot do here

  • The first sign-in.
  • Adding DNS records at the DNS host.
  • Connecting Gmail.
  • Paying for a plan.