Skip to main content
This guide walks you through getting an API key and making your first two API calls: sending a transactional email and tracking a contact event.

Prerequisites

You need one of the following:
  • Hosted Plunk — Sign up at useplunk.com and create a project.
  • Self-hosted Plunk — Deploy using Docker and connect to AWS SES. See the Self-Hosting guide.
You also need a verified sending domain before you can send email. See Verifying Domains. For testing, you can verify a single email address in the AWS SES console instead of a full domain.
1

Get your API key

Open the Plunk dashboard, navigate to your project, and go to Settings → API Keys.You’ll see two keys:
  • Secret key (sk_*) — Required for sending email and all other write operations. Keep this server-side and never expose it in client code.
  • Public key (pk_*) — Only works with the /v1/track endpoint. Safe to use in browser JavaScript.
Copy your secret key. You’ll use it in the next steps.
Your secret key has full access to your project — it can send emails, read contacts, and modify settings. Store it in an environment variable, not in source code.
2

Send a transactional email

Use POST /v1/send to send an email directly from the API. The from address must come from a domain you have verified in Plunk.
curl -X POST https://api.useplunk.com/v1/send \
  -H "Authorization: Bearer sk_your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "[email protected]",
    "subject": "Welcome to our app",
    "body": "<h1>Welcome, {{firstName}}!</h1><p>Thanks for signing up.</p>",
    "from": "[email protected]",
    "name": "Your App",
    "data": {
      "firstName": "Jane"
    }
  }'
A successful response looks like:
{
  "success": true,
  "data": {
    "emails": [
      {
        "contact": { "id": "cnt_abc123", "email": "[email protected]" },
        "email": "eml_xyz789"
      }
    ],
    "timestamp": "2026-03-30T10:00:00.000Z"
  }
}
Key request fields:
to
string | object | array
required
Recipient email address. Accepts a string ("[email protected]"), an object with name and email ({"name": "Jane", "email": "[email protected]"}), or an array of either for multiple recipients.
subject
string
required
Email subject line. Supports {{variable}} substitution using values from data.
body
string
required
HTML email body. Supports {{variable}} substitution. Use {{field ?? default}} for fallback values.
from
string | object
required
Sender address. Must be from a domain verified in your Plunk project. Accepts a string email or {"name": "Sender Name", "email": "[email protected]"}.
name
string
Sender display name when from is a plain string.
data
object
Key-value pairs for template variable substitution and contact data. Simple values are persisted to the contact record. To pass a value for this email only without saving it, use {"value": "ABC", "persistent": false}.
attachments
array
Up to 10 attachments (10 MB total). Each attachment requires filename (string), content (base64-encoded string), and contentType (MIME type string).
template
string
Template ID from your dashboard. When set, subject and body are optional — the template values are used unless you override them.
3

Track a contact event

Use POST /v1/track to record a named event for a contact. This creates the contact if they don’t exist yet, updates their data, and can trigger any matching workflows you’ve configured.You can use either your secret key (sk_*) or your public key (pk_*) for this endpoint.
curl -X POST https://api.useplunk.com/v1/track \
  -H "Authorization: Bearer pk_your_public_key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "event": "signed_up",
    "data": {
      "plan": "pro",
      "company": "Acme Corp"
    }
  }'
A successful response looks like:
{
  "success": true,
  "data": {
    "contact": "cnt_abc123",
    "event": "evt_xyz789",
    "timestamp": "2026-03-30T10:00:00.000Z"
  }
}
Key request fields:
email
string
required
The contact’s email address. If this contact doesn’t exist yet, Plunk creates them automatically.
event
string
required
Name of the event to record (e.g., signed_up, purchase_completed, plan_upgraded). Use this name in workflows and segments to filter by event.
data
object
Key-value pairs saved to the contact record and made available in workflow templates. To pass a value for this event only without persisting it to the contact, use {"value": "order_123", "persistent": false}.
subscribed
boolean
Explicitly set the contact’s subscription status. If omitted, new contacts default to subscribed and existing contacts keep their current status.

Next steps

Verify your sending domain

Add DNS records so you can send from your own domain with proper DKIM and SPF authentication.

Build a workflow

Set up an automated email sequence triggered by events you track with /v1/track.

Send a campaign

Broadcast an email to all contacts or a targeted segment of your audience.

API reference

Explore every endpoint: contacts, templates, campaigns, segments, workflows, and more.

Build docs developers (and LLMs) love