Skip to content

Quickstart

In this quickstart you create a simulated person, send them an email, and wait for their reply. It takes about five minutes.

The examples use the server c1.simmail.dev. Your organization may live on a different server. Your account page shows the exact addresses for each universe, so use those.

  1. Sign up.

    Create an account at www.simmail.dev. You get an organization and a first universe. Open your account page and find the universe under Universes. It shows:

    • API, for example https://c1.simmail.dev/api
    • Universe, the universe’s id
    • SMTP, SMTPS, IMAP and IMAPS host and ports
    • MCP, for AI agents
  2. Create an API key.

    Go to API keys and choose New key. Pick the universe and the Member role. Copy the key now; it is shown only once. It starts with smk_.

    Save the key and the server address in your shell:

    Terminal window
    export SIMMAIL_URL=https://c1.simmail.dev
    export SIMMAIL_API_KEY=smk_your_key

    Check that it works:

    Terminal window
    curl -s "$SIMMAIL_URL/api/me" -H "Authorization: Bearer $SIMMAIL_API_KEY"

    The answer names your key, its universe and its role.

  3. Create a login for your app.

    Your app needs a login to send over SMTP. On the account page choose Open next to the universe. In the universe’s dashboard go to Settings → Mail logins and add a login with an address and a password, for example app@yourcompany.test.

    Each login name can be used once in your organization: if another of your universes already has it, you get “login name already in use”. Use an address that is yours, such as one at your own company’s domain.

  4. Create a person to write to.

    Make Dana, a homeowner who always answers:

    Terminal window
    curl -s -X POST "$SIMMAIL_URL/api/personas" \
    -H "Authorization: Bearer $SIMMAIL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "name": "Dana Reyes",
    "addresses": ["dana@harbor.test"],
    "role": "homeowner",
    "wants": "to sell her house this spring for a fair price",
    "temperament": "responsive",
    "timing": { "reply_rate": 1 }
    }'

    reply_rate: 1 makes sure she answers cold mail. Without it, a responsive person answers 95% of first emails.

  5. Send an email over SMTP.

    Any SMTP client works. This one uses curl, which speaks SMTP too. Write the message to a file, with a Message-ID you choose so you can find the reply later:

    Terminal window
    cat > hello.eml <<'EOF'
    From: Sam at Acme <app@yourcompany.test>
    To: Dana Reyes <dana@harbor.test>
    Subject: Your house on Clark Street
    Message-ID: <hello-1@yourcompany.test>
    Hi Dana,
    Would you consider an offer of 165,000 for your house?
    Sam
    EOF
    curl --ssl-reqd --url smtp://c1.simmail.dev:2525 \
    --user 'app@yourcompany.test:your-password' \
    --mail-from app@yourcompany.test \
    --mail-rcpt dana@harbor.test \
    --upload-file hello.eml

    --ssl-reqd upgrades the connection with STARTTLS. If the universe’s connection details say its certificate is self-signed, add --insecure.

  6. Or send it with the API.

    The API sends exactly as SMTP would. It answers with the new message’s id:

    Terminal window
    curl -s -X POST "$SIMMAIL_URL/api/send" \
    -H "Authorization: Bearer $SIMMAIL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "from": "app@yourcompany.test",
    "to": ["dana@harbor.test"],
    "subject": "Your house on Clark Street",
    "text": "Hi Dana,\n\nWould you consider an offer of 165,000?\n\nSam"
    }'
    {
    "message_id": "<3f9c1e0a7b2d4c5e6f708192@simmail.test>",
    "status": "sent"
    }
  7. Wait for the reply.

    People reply on a simulated clock, often hours later. fast=true has Dana write her due reply now:

    Terminal window
    curl -s -G "$SIMMAIL_URL/api/wait/reply" \
    -H "Authorization: Bearer $SIMMAIL_API_KEY" \
    --data-urlencode "from=dana@harbor.test" \
    --data-urlencode "in_reply_to=<hello-1@yourcompany.test>" \
    --data-urlencode "fast=true" \
    --data-urlencode "timeout=60s"

    You get her reply as JSON, with its text, subject, links and more. If you sent with the API, use the message_id it returned as in_reply_to.

AnswerWhat it means
401The key is missing or wrong. Send Authorization: Bearer smk_….
403 “your role (viewer) cannot do this”The key’s role is too low. Use a Member key.
404 “no persona at ?from=…”Nobody plays that address. Check the spelling, or create the persona.
408Nothing arrived before the timeout. The person may have chosen not to answer; the dashboard’s Activity says why.
409 “decided not to reply”The person chose not to answer. People do that.