docs: Improve docs with core-concept and guides
This commit is contained in:
@@ -1,46 +0,0 @@
|
||||
---
|
||||
title: Conditional Branching
|
||||
description: If/then logic in workflows
|
||||
icon: GitBranch
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Conditions split workflows into two paths based on contact data.
|
||||
|
||||
```
|
||||
[Condition: plan = "premium"?]
|
||||
├─ True → [Premium email]
|
||||
└─ False → [Upgrade offer]
|
||||
```
|
||||
|
||||
## Operators
|
||||
|
||||
| Operator | Example |
|
||||
|----------|---------|
|
||||
| `equals` | `plan equals "pro"` |
|
||||
| `notEquals` | `plan notEquals "free"` |
|
||||
| `contains` | `email contains "@company.com"` |
|
||||
| `greaterThan` | `mrr greaterThan 100` |
|
||||
| `lessThan` | `loginCount lessThan 5` |
|
||||
| `exists` | `company exists` |
|
||||
| `notExists` | `lastName notExists` |
|
||||
|
||||
## Nested conditions
|
||||
|
||||
Chain for multi-tier logic:
|
||||
|
||||
```
|
||||
[Condition: enterprise?]
|
||||
├─ True → [Enterprise email]
|
||||
└─ False → [Condition: pro?]
|
||||
├─ True → [Pro email]
|
||||
└─ False → [Free email]
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Store numbers as numbers, not strings
|
||||
- Check field exists before comparing
|
||||
- Limit to 3 levels of nesting
|
||||
- Test both paths
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"title": "Automation",
|
||||
"pages": ["visual-builder-guide", "workflow-patterns", "conditional-branching"]
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
title: Visual Builder
|
||||
description: Build workflows with drag-and-drop
|
||||
icon: Workflow
|
||||
---
|
||||
|
||||
## Canvas controls
|
||||
|
||||
- **+/-** — Zoom in/out
|
||||
- **Fit** — Center workflow
|
||||
- **Auto-Layout** — Arrange nodes
|
||||
|
||||
## Step types
|
||||
|
||||
| Step | Description |
|
||||
|------|-------------|
|
||||
| **Trigger** | Starting point (event, segment, schedule) |
|
||||
| **Send Email** | Send a template |
|
||||
| **Delay** | Wait minutes, hours, or days |
|
||||
| **Wait for Event** | Pause until event or timeout |
|
||||
| **Condition** | Branch based on contact data |
|
||||
| **Webhook** | Send HTTP request |
|
||||
| **Update Contact** | Modify contact fields |
|
||||
| **Exit** | End workflow |
|
||||
|
||||
## Building
|
||||
|
||||
1. Click step to configure
|
||||
2. Connect steps by dragging
|
||||
3. Conditions require both true/false paths
|
||||
|
||||
## Tips
|
||||
|
||||
- Keep workflows to 5-10 steps
|
||||
- Use descriptive step names
|
||||
- Test with a test contact before enabling
|
||||
- Space emails 12-24 hours apart
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
title: Workflow Patterns
|
||||
description: Common workflow templates
|
||||
icon: Layers
|
||||
---
|
||||
|
||||
## Linear sequence
|
||||
|
||||
```
|
||||
[Trigger] → [Email] → [Delay] → [Email] → [Exit]
|
||||
```
|
||||
|
||||
Use for: onboarding, drip campaigns
|
||||
|
||||
## Wait and branch
|
||||
|
||||
```
|
||||
[Trigger] → [Wait for Event]
|
||||
├─ Event → [Success email] → [Exit]
|
||||
└─ Timeout → [Reminder] → [Exit]
|
||||
```
|
||||
|
||||
Use for: trial conversion, activation
|
||||
|
||||
## Conditional branch
|
||||
|
||||
```
|
||||
[Trigger] → [Condition: plan = premium?]
|
||||
├─ True → [Premium email] → [Exit]
|
||||
└─ False → [Upgrade offer] → [Exit]
|
||||
```
|
||||
|
||||
Use for: personalization by tier
|
||||
|
||||
## Multi-step recovery
|
||||
|
||||
```
|
||||
[Trigger: cart_abandoned]
|
||||
↓
|
||||
[Delay: 1 hour]
|
||||
↓
|
||||
[Send: Reminder]
|
||||
↓
|
||||
[Wait for: purchase, timeout: 24h]
|
||||
├─ Purchased → [Exit]
|
||||
└─ Timeout → [Send: Discount] → [Exit]
|
||||
```
|
||||
|
||||
Use for: cart abandonment, re-engagement
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
title: Email Attachments
|
||||
description: Send files with emails
|
||||
icon: Paperclip
|
||||
---
|
||||
|
||||
## Limits
|
||||
|
||||
- Max 10 attachments per email
|
||||
- Max 10MB total size
|
||||
- Any file type supported
|
||||
|
||||
## API usage
|
||||
|
||||
```json
|
||||
{
|
||||
"to": "user@example.com",
|
||||
"subject": "Your Invoice",
|
||||
"body": "<p>Invoice attached.</p>",
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "invoice.pdf",
|
||||
"content": "JVBERi0xLjQK...",
|
||||
"contentType": "application/pdf"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Attachment fields
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `filename` | Display name (max 255 chars) |
|
||||
| `content` | Base64-encoded file content |
|
||||
| `contentType` | MIME type (e.g., `application/pdf`) |
|
||||
|
||||
## Base64 encoding
|
||||
|
||||
```javascript
|
||||
import fs from 'fs';
|
||||
|
||||
const fileBuffer = fs.readFileSync('invoice.pdf');
|
||||
const base64Content = fileBuffer.toString('base64');
|
||||
```
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Billing
|
||||
description: Understand Plunk's billing model
|
||||
icon: CreditCard
|
||||
---
|
||||
|
||||
Plunk's pricing is based on the number of emails sent each month. You can send both marketing and transactional emails under the same plan.
|
||||
|
||||
## Free Tier
|
||||
Free tier projects can send up to 1,000 emails per month at no cost. Projects on this tier will include a Plunk-branded footer in all emails.
|
||||
|
||||
## Pay-as-you-go
|
||||
After upgrading from the free tier, you will be charged per email sent at $0.001 per email. There are no monthly fees or commitments, you only pay for what you use.
|
||||
|
||||
You are able to monitor your email usage and set billing limits per category in the billing tab of the project settings.
|
||||
|
||||
## Special considerations
|
||||
- Emails that contain an attachment will incur double the cost (e.g. 1 email with attachment = 2 emails for billing purposes)
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
title: Campaigns vs Workflows
|
||||
description: Choose the right sending method
|
||||
icon: GitCompare
|
||||
---
|
||||
|
||||
## Quick comparison
|
||||
|
||||
| Need | Use |
|
||||
|------|-----|
|
||||
| Password reset now | **API** `/v1/send` |
|
||||
| Monthly newsletter | **Campaign** |
|
||||
| Welcome series over 3 days | **Workflow** |
|
||||
| Order confirmation | **API** `/v1/send` |
|
||||
| Abandoned cart recovery | **Workflow** |
|
||||
|
||||
## Transactional API
|
||||
|
||||
Immediate one-off emails from your code.
|
||||
|
||||
```javascript
|
||||
await fetch('/v1/send', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
to: user.email,
|
||||
subject: 'Reset your password',
|
||||
body: `Click here: ${resetLink}`
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
## Campaigns
|
||||
|
||||
One-time broadcasts to many contacts. Created in dashboard.
|
||||
|
||||
- Send now or schedule
|
||||
- Target all contacts, segments, or filters
|
||||
- No code required
|
||||
|
||||
## Workflows
|
||||
|
||||
Automated multi-email sequences.
|
||||
|
||||
- Triggered by events or segment changes
|
||||
- Delays between emails
|
||||
- Conditional logic (if/then)
|
||||
- Re-entry control
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: Campaigns
|
||||
description: Broadcast to your contacts
|
||||
icon: Megaphone
|
||||
---
|
||||
|
||||
Campaigns are a one-time email sent to a group of contacts. They are typically used for newsletters, announcements, or promotions.
|
||||
|
||||
## Targeting contacts
|
||||
When you create a campaign, you can send it to all subscribed contacts, or target a specific segment you have created in the [Segments](/concepts/segments) section.
|
||||
|
||||
## Sending a campaign
|
||||
Once you have designed your campaign and selected the target audience, you can schedule it to be sent immediately or at a later time. You can also choose to send a test email to yourself or any other team member before sending it to your contacts.
|
||||
|
||||
Campaigns will be queued and sent in the background. You can monitor the sending progress and view detailed analytics on opens, clicks, and bounces in the campaign detail page. Depending on the size of your audience, it may take some time for all emails to be sent.
|
||||
@@ -1,107 +0,0 @@
|
||||
---
|
||||
title: Contacts
|
||||
description: Store and manage your audience
|
||||
icon: Users
|
||||
---
|
||||
|
||||
## Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "contact_abc123",
|
||||
"email": "user@example.com",
|
||||
"subscribed": true,
|
||||
"data": {
|
||||
"firstName": "Sarah",
|
||||
"plan": "pro",
|
||||
"mrr": 99
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Adding contacts
|
||||
|
||||
- **Dashboard:** Contacts → Add Contact
|
||||
- **CSV import:** Contacts → Import
|
||||
- **API:** `POST /contacts`
|
||||
- **Events:** Auto-created when tracking events
|
||||
|
||||
## Contact data
|
||||
|
||||
The `data` field stores custom key-value pairs.
|
||||
|
||||
**Best practices:**
|
||||
- Use consistent naming (camelCase or snake_case)
|
||||
- Store dates as ISO strings: `"2024-03-15T10:30:00Z"`
|
||||
- Use numbers for numeric values (enables comparisons)
|
||||
|
||||
## Localization
|
||||
|
||||
The `locale` field in contact data overrides the project-wide language setting for that specific contact.
|
||||
|
||||
**Where it's used:**
|
||||
- Unsubscribe and preference center pages
|
||||
- Email footer translations
|
||||
- All contact-facing content
|
||||
|
||||
**Example:**
|
||||
|
||||
```javascript
|
||||
// Set a contact's preferred language
|
||||
POST /contacts
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"data": {
|
||||
"locale": "de" // German
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Via tracking:**
|
||||
|
||||
```javascript
|
||||
POST /v1/track
|
||||
{
|
||||
"event": "signup",
|
||||
"email": "user@example.com",
|
||||
"data": {
|
||||
"locale": "fr" // French
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
- If `locale` is set: uses contact's language
|
||||
- If not set: uses project's default language
|
||||
- Falls back to English if neither is set
|
||||
|
||||
## Template variables
|
||||
|
||||
Use `{{fieldName}}` in emails:
|
||||
|
||||
```html
|
||||
<p>Hello {{firstName}}!</p>
|
||||
```
|
||||
|
||||
**Fallback:** `{{firstName ?? 'there'}}`
|
||||
|
||||
**System-generated fields (always available):**
|
||||
- `{{email}}` - Contact's email address
|
||||
- `{{unsubscribeUrl}}` - Link to unsubscribe page
|
||||
- `{{subscribeUrl}}` - Link to subscribe page
|
||||
- `{{manageUrl}}` - Link to preference center
|
||||
|
||||
**Special fields:**
|
||||
- `{{locale}}` - Contact's language preference (user-settable, overrides project default)
|
||||
|
||||
## Temporary data
|
||||
|
||||
Data that won't save to contact:
|
||||
|
||||
```javascript
|
||||
data: {
|
||||
resetCode: { value: 'ABC123', persistent: false }
|
||||
}
|
||||
```
|
||||
|
||||
Use for: one-time codes, tokens, session data.
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: Contacts
|
||||
description: Manage and organize your contacts effectively
|
||||
icon: Users
|
||||
---
|
||||
|
||||
Contacts in Plunk represent an individual email recipient. Each contact has an identifier and is linked to an email address.
|
||||
|
||||
## Adding contacts
|
||||
Contacts can be added to your Plunk project in several ways:
|
||||
- Using [/v1/track](/api-reference/public-api/trackEvent), when tracking an event for a contact that does not yet exist, Plunk will automatically create it.
|
||||
- Using [/contacts](/api-reference/contacts/createContact), to create a single contact.
|
||||
- Import through CSV
|
||||
- Manually through the dashboard
|
||||
|
||||
## Contact Data
|
||||
You can associate custom data with each contact using key-value pairs. This data can be used for segmentation and personalization.
|
||||
|
||||
### Data types
|
||||
Contact data types are inferred based on the value provided:
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| String | Any text value |
|
||||
| Number | Numeric values, including integers and floats |
|
||||
| Boolean | True or false values |
|
||||
| Date | Date values in ISO 8601 format |
|
||||
|
||||
<Callout
|
||||
title="Default data type"
|
||||
variant="idea">
|
||||
If you accidentally mix data types for a specific key, Plunk will default to treating the value as a string.
|
||||
</Callout>
|
||||
|
||||
### Reserved keys
|
||||
Certain keys are reserved by the system and automatically set by Plunk:
|
||||
| Key | Description |
|
||||
|-----|-------------|
|
||||
| email | The contact's email address |
|
||||
| createdAt | Timestamp of when the contact was created |
|
||||
| updatedAt | Timestamp of the last update to the contact |
|
||||
| subscribed | Boolean indicating if the contact is globally subscribed or not |
|
||||
|
||||
### Special keys
|
||||
| Key | Description |
|
||||
|-----|-------------|
|
||||
| locale | The contact's preferred locale in ISO 639 (e.g. 'en', 'fr', 'es'). Specifying the locale field on a contact will override the project-wide locale for contact-facing pages and email footers |
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
title: Custom Domains
|
||||
description: Send from your own domain
|
||||
icon: Globe
|
||||
---
|
||||
|
||||
## Why use custom domains
|
||||
|
||||
- Better deliverability
|
||||
- Brand consistency
|
||||
- Builds sender reputation
|
||||
|
||||
## Setup
|
||||
|
||||
1. Go to **Settings → Domains**
|
||||
2. Click **Add Domain**
|
||||
3. Enter your domain
|
||||
4. Add the provided DNS records (DKIM, MX, TXT)
|
||||
5. Wait for verification (usually 10-30 minutes, up to 48 hours)
|
||||
|
||||
## Using your domain
|
||||
|
||||
Specify in the `from` field when sending:
|
||||
|
||||
```json
|
||||
{
|
||||
"to": "customer@example.com",
|
||||
"from": "orders@yourdomain.com",
|
||||
"subject": "Order confirmed",
|
||||
"body": "<p>Your order has been confirmed.</p>"
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Domain won't verify:**
|
||||
- Check DNS records are correct
|
||||
- Wait for DNS propagation (up to 48 hours)
|
||||
- Remove conflicting DKIM records from other services
|
||||
|
||||
**Emails going to spam:**
|
||||
- Warm up new domains with small volumes first
|
||||
- Monitor bounce and complaint rates
|
||||
@@ -1,53 +0,0 @@
|
||||
---
|
||||
title: Events
|
||||
description: Track actions and trigger workflows
|
||||
icon: Activity
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Events track user actions. Use them to trigger workflows and update contact data.
|
||||
|
||||
## Tracking
|
||||
|
||||
```javascript
|
||||
await fetch('/v1/track', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer pk_your_public_key'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
event: 'signed_up',
|
||||
email: user.email,
|
||||
data: { plan: 'pro' }
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
Creates/updates contact and records the event.
|
||||
|
||||
## Keys
|
||||
|
||||
- **Public key (pk_*):** Safe for client-side, only works with `/v1/track`
|
||||
- **Secret key (sk_*):** Server-side only, full API access
|
||||
|
||||
## Event data
|
||||
|
||||
**Persistent (default):** Saved to contact
|
||||
```javascript
|
||||
data: { plan: 'premium' }
|
||||
```
|
||||
|
||||
**Non-persistent:** Available only to workflow
|
||||
```javascript
|
||||
data: {
|
||||
orderId: { value: 'order-123', persistent: false }
|
||||
}
|
||||
```
|
||||
|
||||
## Automatic events
|
||||
|
||||
Plunk tracks these automatically:
|
||||
- `email.sent`, `email.opened`, `email.clicked`
|
||||
- `email.bounced`, `email.complained`
|
||||
- `segment.entered`, `segment.exited`
|
||||
@@ -1,14 +1,3 @@
|
||||
{
|
||||
"title": "Core Concepts",
|
||||
"pages": [
|
||||
"contacts-and-data",
|
||||
"templates-types",
|
||||
"campaigns-vs-workflows",
|
||||
"segments-and-filters",
|
||||
"events-and-triggers",
|
||||
"webhooks",
|
||||
"custom-domains",
|
||||
"attachments",
|
||||
"troubleshooting"
|
||||
]
|
||||
"pages": ["contacts", "segments", "workflows", "campaigns", "transactional-emails", "templates", "billing"]
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
title: Segments
|
||||
description: Dynamic audience groups
|
||||
icon: Funnel
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Segments are dynamic groups based on filters. They update automatically when contact data changes.
|
||||
|
||||
## Creating
|
||||
|
||||
1. Go to **Segments** → **Create Segment**
|
||||
2. Name your segment
|
||||
3. Add filter conditions
|
||||
4. Save
|
||||
|
||||
## Operators
|
||||
|
||||
| Operator | Example |
|
||||
|----------|---------|
|
||||
| `equals` | `plan equals "pro"` |
|
||||
| `not equals` | `plan not equals "free"` |
|
||||
| `contains` | `email contains "@gmail"` |
|
||||
| `greater than` | `mrr greater than 100` |
|
||||
| `less than` | `loginCount less than 5` |
|
||||
| `exists` | `company exists` |
|
||||
|
||||
## Combining filters
|
||||
|
||||
- **AND:** All conditions must match
|
||||
- **OR:** Any condition can match
|
||||
|
||||
## Membership tracking
|
||||
|
||||
Enable **Track membership changes** to:
|
||||
- Trigger workflows on segment entry/exit
|
||||
- Generate `segment.entered` and `segment.exited` events
|
||||
|
||||
Only enable for segments used as workflow triggers.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: Segments
|
||||
description: Group and target your contacts with dynamic segments
|
||||
icon: Layers
|
||||
---
|
||||
|
||||
Segments in Plunk allow you to create dynamic groups of contacts based on [contact data](/concepts/contacts#contact-data) and events.
|
||||
|
||||
## Creating segments
|
||||
Segments can be created through the Plunk dashboard. When creating a segment, you can define multiple conditions that contacts must meet to be included in the segment. Plunk will automatically update the segment membership as contact data and events change.
|
||||
|
||||
### Track Membership Changes
|
||||
Plunk will automatically add and remove contacts from segments as their data and events change. When toggling on `Track membership changes`, Plunk will send an event to your webhook each time a contact is added or removed from the segment.
|
||||
|
||||
These events will have the following name `segment.trial-users.entry` or `segment.trial-users.exit`, where `trial-users` is the segment's name.
|
||||
|
||||
## Using segments
|
||||
Segment can be used in various parts of Plunk, including:
|
||||
- Targeting contacts in [email campaigns](/concepts/campaigns)
|
||||
- Triggering workflows in [marketing automation](/concepts/workflows)
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
title: Template Types
|
||||
description: Marketing vs Transactional
|
||||
icon: Mail
|
||||
---
|
||||
|
||||
## Two types
|
||||
|
||||
| Type | Sends to Unsubscribed? | Use For |
|
||||
|------|------------------------|---------|
|
||||
| **Marketing** | No | Newsletters, promotions |
|
||||
| **Transactional** | Yes | Receipts, password resets |
|
||||
|
||||
## Marketing
|
||||
|
||||
Only sends to subscribed contacts. Automatically includes unsubscribe link.
|
||||
|
||||
## Transactional
|
||||
|
||||
Sends regardless of subscription status. Use only for essential emails.
|
||||
|
||||
## Choosing
|
||||
|
||||
Ask: "Would user be frustrated if they didn't receive this after unsubscribing?"
|
||||
|
||||
- **Yes → Transactional** (password resets, order confirmations)
|
||||
- **No → Marketing** (newsletters, promotions)
|
||||
|
||||
## Variables
|
||||
|
||||
```html
|
||||
<h1>Hello {{firstName}}!</h1>
|
||||
<p>Your {{plan}} plan renews on {{renewalDate}}.</p>
|
||||
```
|
||||
|
||||
**Fallback:** `{{firstName ?? 'there'}}`
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: Templates
|
||||
description: Create reusable email templates for your campaigns, workflows and transactional emails
|
||||
icon: SwatchBook
|
||||
---
|
||||
|
||||
Templates are stored in the Plunk dashboard and can be used in campaigns, workflows and transactional emails.
|
||||
|
||||
## Designing templates
|
||||
Templates can be created using the built-in editor or by uploading your own HTML.
|
||||
|
||||
### Personalization
|
||||
You can use contact data to personalize your templates by using the handlebars syntax `{{ key }}`, where `key` is the contact data key.
|
||||
|
||||
### Previewing templates
|
||||
You can preview your templates by selecting a contact in the preview window. This will allow you to see how the template will look for that specific contact, with their data populated.
|
||||
|
||||
## Templates types
|
||||
There are two types of templates in Plunk. Each type is treated at the same priority when sending emails, you should not pick one type over the other based on deliverability or performance.
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| Marketing | Automatically includes a Plunk-hosted unsubscribe page and footer. Will not be sent to contacts who are unsubscribed |
|
||||
| Transactional | Does not include any way to unsubscribe. Will be sent to any contact, regardless of subscription state |
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: Transactional Emails
|
||||
description: Send emails via API
|
||||
icon: Send
|
||||
---
|
||||
|
||||
Transactional emails are emails sent directly through the API. They are typically used for one-to-one communication, such as password resets, order confirmations, and notifications.
|
||||
|
||||
## Sending with attachments
|
||||
Plunk supports sending attachments with transactional emails. You can include up to 10 attachments per email, with a maximum total size of 10MB. Attachments should be base64 encoded and included in the `attachments` array when sending the email via the [/v1/email/send](/api-reference/public-api/sendEmail) endpoint.
|
||||
|
||||
## Sending from a template
|
||||
You can also send transactional emails using a [template](/concepts/templates) you have created in the dashboard. This allows you to reuse the same design and content for multiple emails, while still personalizing them with contact data.
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
title: Troubleshooting
|
||||
description: Common issues and solutions
|
||||
icon: Bug
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
**Invalid API key:**
|
||||
- Secret keys start with `sk_`, public keys with `pk_`
|
||||
- Use `Authorization: Bearer sk_your_secret_key`
|
||||
|
||||
**Wrong key type:**
|
||||
- Public keys (`pk_`) only work with `/v1/track`
|
||||
- All other endpoints require secret keys (`sk_`)
|
||||
|
||||
## Emails not sending
|
||||
|
||||
1. **Billing limit reached** — Check Settings → Billing
|
||||
2. **Template not found** — Verify template ID exists
|
||||
3. **Contact unsubscribed** — Marketing templates skip unsubscribed contacts
|
||||
|
||||
## Emails going to spam
|
||||
|
||||
1. Set up a custom domain
|
||||
2. Clean your list (remove bounces)
|
||||
3. Warm up new domains gradually
|
||||
|
||||
## Workflows not triggering
|
||||
|
||||
1. **Workflow not enabled** — Check toggle is ON
|
||||
2. **Wrong event name** — Names are case-sensitive
|
||||
3. **Already entered** — If re-entry disabled, contact can only enter once
|
||||
|
||||
## Rate limiting (429)
|
||||
|
||||
- Wait and retry
|
||||
- Batch multiple recipients in one request
|
||||
- Spread requests over time
|
||||
|
||||
## Request IDs
|
||||
|
||||
Every API response includes `X-Request-ID` header. Include this when contacting support.
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
title: Webhooks
|
||||
description: Send HTTP requests from workflows
|
||||
icon: Webhook
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Webhooks send HTTP requests to external services from within workflows.
|
||||
|
||||
## Adding a webhook step
|
||||
|
||||
1. Edit a workflow
|
||||
2. Add a **Webhook** step
|
||||
3. Configure URL, method, headers, and body
|
||||
|
||||
## Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"url": "https://your-api.com/webhook",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Authorization": "Bearer your_api_token"
|
||||
},
|
||||
"body": {
|
||||
"email": "{{email}}",
|
||||
"firstName": "{{data.firstName}}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Methods:** POST, PUT, PATCH, GET, DELETE
|
||||
|
||||
## Variables
|
||||
|
||||
- `{{email}}`, `{{id}}` — Contact fields
|
||||
- `{{data.fieldName}}` — Custom data
|
||||
- `{{workflowName}}`, `{{now}}` — Workflow context
|
||||
|
||||
## Error handling
|
||||
|
||||
- Failed webhooks don't block the workflow
|
||||
- Errors logged in execution details
|
||||
- 30 second timeout
|
||||
- No automatic retries
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: Workflows
|
||||
description: Set up automated email sequences and trigger them from your apps
|
||||
icon: Workflow
|
||||
---
|
||||
|
||||
Workflows in Plunk allow you to create automated email sequences that can be triggered based on events you send using the API.
|
||||
|
||||
## Prerequisites for workflows
|
||||
### Sending an event
|
||||
Workflows are triggered by sending events to Plunk using the [/v1/track](/api-reference/public-api/trackEvent) endpoint. When sending an event, you can specify the contact it is associated with and include any relevant data.
|
||||
|
||||
### Creating a template
|
||||
Before setting up the workflow, ensure you have created a template that will be used for the emails sent by the workflow. You can create templates in the [Templates](/concepts/templates) section of the dashboard.
|
||||
|
||||
## Creating a workflow
|
||||
To create a workflow, navigate to the [Workflows](/concepts/workflows) section of the dashboard and create a workflow.
|
||||
|
||||
<Callout
|
||||
title="Trigger"
|
||||
variant="idea">
|
||||
When creating a workflow, you can not change the trigger event after the workflow has been created. Make sure to choose the correct event name that will trigger the workflow.
|
||||
</Callout>
|
||||
|
||||
### Defining workflow steps
|
||||
Workflows consists of multiple steps that define the sequence of actions to be taken.
|
||||
|
||||
| Step Type | Description |
|
||||
|-----------|-------------|
|
||||
| Send Email | Sends an email to the contact using a specified template. You can customize the email content using variables from the event data. |
|
||||
| Delay | Pauses the workflow for a specified duration before proceeding to the next step. |
|
||||
| Wait for Event | Pauses the workflow until a specified event is received for the contact. You can also set a timeout duration to proceed if the event is not received within that time. |
|
||||
| Condition | Evaluates a condition based on the event data or contact data and branches the workflow accordingly. |
|
||||
| Webhook | Sends a webhook to a specified URL with the event and contact data. |
|
||||
| Update Contact | Updates the contact's data with specified key-value pairs. |
|
||||
| Exit | Terminates the workflow for the contact. |
|
||||
|
||||
## Managing workflow executions
|
||||
You can monitor and manage contacts going through workflows in the executions tab of the workflow detail page. Here you can see the status of each execution, cancel a specific execution or all executions.
|
||||
|
||||
A workflow will be locked while there are active executions. If you want to make changes to a running workflow you will either need to pause it and wait for all executions to complete, or cancel all active executions.
|
||||
@@ -1,163 +0,0 @@
|
||||
---
|
||||
title: Authentication
|
||||
description: Understanding API keys and authentication
|
||||
---
|
||||
|
||||
## Two types of API keys
|
||||
|
||||
Each project has two API keys for different purposes:
|
||||
|
||||
### Secret Key (sk_*)
|
||||
|
||||
**Use for:** All server-side API calls
|
||||
|
||||
- Required for `/v1/send` (sending emails)
|
||||
- Required for all dashboard API endpoints (contacts, campaigns, templates, etc.)
|
||||
- Can access and modify all project data
|
||||
- **Never expose in client-side code**
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
// Server-side only
|
||||
fetch('{{API_URL}}/v1/send', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer sk_your_secret_key',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
to: 'user@example.com',
|
||||
subject: 'Hello',
|
||||
body: '<p>Your order is ready!</p>'
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
### Public Key (pk_*)
|
||||
|
||||
**Use for:** Client-side event tracking only
|
||||
|
||||
- Works **only** with `/v1/track` endpoint
|
||||
- Cannot send emails or access any other endpoints
|
||||
- Safe to include in frontend JavaScript
|
||||
- Use for tracking user behavior from web browsers or mobile apps
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
// Client-side safe
|
||||
fetch('{{API_URL}}/v1/track', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer pk_your_public_key',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: 'user@example.com',
|
||||
event: 'button_clicked',
|
||||
data: { button: 'signup' }
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
## Finding your API keys
|
||||
|
||||
1. Log into [Plunk dashboard]({{DASHBOARD_URL}})
|
||||
2. Select your project
|
||||
3. Go to **Settings > API Keys**
|
||||
4. Copy the key you need
|
||||
|
||||
## Using API keys
|
||||
|
||||
All authenticated requests use the `Authorization` header with Bearer token format:
|
||||
|
||||
```bash
|
||||
Authorization: Bearer sk_your_secret_key
|
||||
```
|
||||
|
||||
### cURL example
|
||||
|
||||
```bash
|
||||
curl -X POST {{API_URL}}/v1/send \
|
||||
-H "Authorization: Bearer sk_your_secret_key" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"to": "user@example.com", "subject": "Test", "body": "Hello"}'
|
||||
```
|
||||
|
||||
### Node.js example
|
||||
|
||||
```javascript
|
||||
const PLUNK_SECRET_KEY = process.env.PLUNK_SECRET_KEY;
|
||||
|
||||
const response = await fetch('{{API_URL}}/v1/send', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${PLUNK_SECRET_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
to: 'user@example.com',
|
||||
subject: 'Test',
|
||||
body: 'Hello'
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
### Python example
|
||||
|
||||
```python
|
||||
import os
|
||||
import requests
|
||||
|
||||
PLUNK_SECRET_KEY = os.environ.get('PLUNK_SECRET_KEY')
|
||||
|
||||
response = requests.post(
|
||||
'{{API_URL}}/v1/send',
|
||||
headers={
|
||||
'Authorization': f'Bearer {PLUNK_SECRET_KEY}',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
json={
|
||||
'to': 'user@example.com',
|
||||
'subject': 'Test',
|
||||
'body': 'Hello'
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Security best practices
|
||||
|
||||
### Store secret keys securely
|
||||
|
||||
Never commit secret keys to version control. Use environment variables:
|
||||
|
||||
```bash
|
||||
# .env file (add to .gitignore)
|
||||
PLUNK_SECRET_KEY=sk_your_secret_key
|
||||
```
|
||||
|
||||
### Rotate compromised keys
|
||||
|
||||
If a secret key is exposed:
|
||||
|
||||
1. Go to **Settings > API Keys**
|
||||
2. Click **Regenerate Secret Key**
|
||||
3. Update your application with the new key
|
||||
4. The old key stops working immediately
|
||||
|
||||
### Use the right key for the job
|
||||
|
||||
- **Sending emails from your backend?** → Use secret key
|
||||
- **Tracking events from frontend?** → Use public key
|
||||
- **Managing contacts via API?** → Use secret key
|
||||
- **Building a workflow dashboard?** → Use secret key
|
||||
|
||||
When in doubt, if it's not `/v1/track`, you need the secret key.
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you're authenticated, you can:
|
||||
|
||||
- [Send your first email](/getting-started/quick-start)
|
||||
- [Explore the API](/api-reference/overview)
|
||||
- [Manage contacts](/guides/contacts)
|
||||
- [Create campaigns](/guides/campaigns)
|
||||
@@ -1,64 +0,0 @@
|
||||
---
|
||||
title: Introduction
|
||||
description: Get started with Plunk
|
||||
---
|
||||
|
||||
## What is Plunk?
|
||||
|
||||
Plunk is an open-source email platform built on AWS SES. It provides a complete solution for transactional emails, marketing campaigns, and automated workflows—everything you need to manage email communications at scale.
|
||||
|
||||
## What you can build
|
||||
|
||||
### Send transactional emails
|
||||
Send password resets, order confirmations, and notifications via API with template support and variable substitution.
|
||||
|
||||
```javascript
|
||||
await fetch('{{API_URL}}/v1/send', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer sk_your_secret_key',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
to: 'user@example.com',
|
||||
subject: 'Welcome {{name}}!',
|
||||
body: '<h1>Hello {{name}}</h1><p>Thanks for signing up.</p>',
|
||||
data: { name: 'John' }
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
### Run marketing campaigns
|
||||
Send newsletters and product updates to segments of your audience. Schedule sends or deliver immediately.
|
||||
|
||||
### Automate email sequences
|
||||
Build drip campaigns, onboarding flows, and behavior-triggered emails with the visual workflow builder.
|
||||
|
||||
## Core concepts
|
||||
|
||||
**Contacts** — People in your audience. Each has an email, subscription status, and custom data fields.
|
||||
|
||||
**Templates** — Reusable email designs. Marketing templates respect subscription status; transactional templates always send.
|
||||
|
||||
**Segments** — Dynamic groups based on contact data. Update automatically as data changes.
|
||||
|
||||
**Campaigns** — One-time email broadcasts to all contacts, a segment, or filtered audience.
|
||||
|
||||
**Workflows** — Automated sequences with delays, conditions, and event triggers.
|
||||
|
||||
**Events** — Track user actions (signups, purchases) to trigger workflows and build segments.
|
||||
|
||||
## Authentication
|
||||
|
||||
Each project has two API keys:
|
||||
|
||||
- **Secret Key (sk_*)** — Server-side only. Required for all endpoints except event tracking.
|
||||
- **Public Key (pk_*)** — Client-side safe. Only works with `/v1/track` for event tracking.
|
||||
|
||||
Never expose secret keys in frontend code.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Quick Start](/getting-started/quick-start) — Send your first email in 5 minutes
|
||||
- [Authentication](/getting-started/authentication) — Understand API keys
|
||||
- [API Reference](/api-reference/overview) — Explore all endpoints
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"title": "Getting Started",
|
||||
"pages": ["introduction", "authentication", "quick-start"]
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
---
|
||||
title: Quick Start
|
||||
description: Send your first email in 5 minutes
|
||||
---
|
||||
|
||||
## Send your first email
|
||||
|
||||
### 1. Get your API key
|
||||
|
||||
1. Sign up at [Plunk dashboard]({{DASHBOARD_URL}})
|
||||
2. Create or select a project
|
||||
3. Go to **Settings > API Keys**
|
||||
4. Copy your **Secret Key** (starts with `sk_`)
|
||||
|
||||
### 2. Send an email
|
||||
|
||||
```bash
|
||||
curl -X POST {{API_URL}}/v1/send \
|
||||
-H "Authorization: Bearer sk_your_secret_key" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"to": "recipient@example.com",
|
||||
"subject": "Hello from Plunk",
|
||||
"body": "<h1>It works!</h1><p>Your first email via Plunk.</p>"
|
||||
}'
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"emails": [{
|
||||
"contact": {
|
||||
"id": "contact_abc123",
|
||||
"email": "recipient@example.com"
|
||||
},
|
||||
"email": "email_xyz789"
|
||||
}],
|
||||
"timestamp": "2024-03-15T10:30:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
The email is queued and delivers within seconds.
|
||||
|
||||
## Use variables
|
||||
|
||||
Make emails dynamic with template variables:
|
||||
|
||||
```bash
|
||||
curl -X POST {{API_URL}}/v1/send \
|
||||
-H "Authorization: Bearer sk_your_secret_key" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"to": "user@example.com",
|
||||
"subject": "Welcome {{firstName}}!",
|
||||
"body": "<h1>Hello {{firstName}}</h1><p>Welcome to {{companyName}}.</p>",
|
||||
"data": {
|
||||
"firstName": "Sarah",
|
||||
"companyName": "Acme Inc"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
Variables use `{{variableName}}` syntax and pull from the `data` object.
|
||||
|
||||
## Send to multiple recipients
|
||||
|
||||
Pass an array to send the same email to multiple people:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"to": ["user1@example.com", "user2@example.com", "user3@example.com"],
|
||||
"subject": "Team update",
|
||||
"body": "<p>Check out our new features!</p>"
|
||||
}
|
||||
```
|
||||
|
||||
Each recipient gets their own email with personalized data if provided.
|
||||
|
||||
## Use saved templates
|
||||
|
||||
Create reusable templates in the dashboard, then reference them by ID:
|
||||
|
||||
```bash
|
||||
curl -X POST {{API_URL}}/v1/send \
|
||||
-H "Authorization: Bearer sk_your_secret_key" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"to": "user@example.com",
|
||||
"template": "welcome-email-template-id",
|
||||
"data": {
|
||||
"firstName": "Sarah",
|
||||
"verificationUrl": "https://example.com/verify/abc123"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
The template's subject, body, and sender settings are used automatically. Your `data` fills in the template variables.
|
||||
|
||||
## Track events
|
||||
|
||||
Track user actions to trigger workflows and build segments:
|
||||
|
||||
```bash
|
||||
curl -X POST {{API_URL}}/v1/track \
|
||||
-H "Authorization: Bearer pk_your_public_key" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"email": "user@example.com",
|
||||
"event": "signed_up",
|
||||
"data": {
|
||||
"plan": "pro",
|
||||
"source": "landing_page"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
This creates or updates the contact and tracks the event. Use events to trigger automated workflows.
|
||||
|
||||
## What's next
|
||||
|
||||
**Set up workflows** — Build automated email sequences with [workflows](/guides/workflows)
|
||||
|
||||
**Manage contacts** — Import and segment your audience with [contacts](/guides/contacts)
|
||||
|
||||
**Send campaigns** — Broadcast to your entire list with [campaigns](/guides/campaigns)
|
||||
|
||||
**Track engagement** — Monitor opens and clicks with [analytics](/guides/analytics)
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: API Keys
|
||||
description: Manage your API keys and understand their usage
|
||||
icon: Key
|
||||
---
|
||||
|
||||
Each project has two unique API keys. A public key and a secret key. These keys are used to authenticate requests made to Plunk's API.
|
||||
|
||||
## Public Key
|
||||
The public API key can only be used with the [/v1/track](/api-reference/public-api/trackEvent) endpoint to track events. This key can be safely exposed in client-side applications.
|
||||
|
||||
## Secret Key
|
||||
The secret API key can be used with all other endpoints in Plunk's API. This key should be kept confidential and not exposed in client-side applications.
|
||||
|
||||
If this key is compromised, a malicious actor could read and modify your project data, send emails, and perform other actions on your behalf.
|
||||
|
||||
## Regenerating API Keys
|
||||
If you believe your API keys have been compromised, you can regenerate them in the project settings.
|
||||
Keep in mind that regenerating an API key will invalidate both keys, so make sure to update your applications with the new key.
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: List Hygiene
|
||||
description: Understand and maintain a healthy email list
|
||||
icon: ShieldCheck
|
||||
---
|
||||
|
||||
Plunk automatically monitors the bounce and complaint rates of your emails to help maintain a health sender reputation. High bounce or complaint rates can negatively impact your deliverability and may lead to your account being suspended.
|
||||
|
||||
## Bounce Management
|
||||
|
||||
A bounce occurs when an email cannot be delivered to the recipient's inbox. When an email bounces, Plunk will automatically unsubscribe the contact and also send an event on the contact for `email.bounced`.
|
||||
|
||||
### Types of Bounces
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| Hard Bounce | Permanent delivery failure (e.g., invalid email address) |
|
||||
| Soft Bounce | Temporary delivery failure (e.g., mailbox full) |
|
||||
|
||||
### Preventing bounces
|
||||
- [Verify email addresses](/api-reference/public-api/verifyEmail)
|
||||
- Regularly clean your email list
|
||||
- Use double opt-in for subscriptions
|
||||
|
||||
## Complaint Management
|
||||
|
||||
A complaint occurs when a recipient marks your email as spam. When a complaint is received, Plunk will automatically unsubscribe the contact and send an event on the contact for `email.complaint`.
|
||||
|
||||
### Preventing complaints
|
||||
- Ensure your emails are relevant and valuable to your audience
|
||||
- Include a clear unsubscribe link in every email
|
||||
- Monitor your email frequency to avoid overwhelming your contacts
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: Localization
|
||||
description: Support for multiple languages and regions
|
||||
icon: Globe
|
||||
---
|
||||
|
||||
Localization in Plunk allows you to configure the language of the unsubscribe footer and contact-facing pages (subscribe, unsubscribe, manage) to better suit your audience.
|
||||
|
||||
## Configuring Localization
|
||||
You can set the default language for your project in the project settings.
|
||||
|
||||
## Overriding language per contact
|
||||
You can override the default language for individual contacts by setting the `locale` field in the contact data. This field should contain a valid [ISO 639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code (e.g., 'en' for English, 'fr' for French, 'es' for Spanish).
|
||||
|
||||
When sending emails, Plunk will use the contact's specified language if available; otherwise, it will fall back to the project's default language.
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"pages": ["list-hygiene", "verifying-domains", "tracking", "api-keys", "localization"]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Tracking
|
||||
description: Tracking for opens and clicks in your emails
|
||||
icon: HatGlasses
|
||||
---
|
||||
|
||||
Plunk provides built-in tracking for email opens and link clicks. This allows you to monitor the engagement of your emails and gain insights into how your contacts interact with your content.
|
||||
|
||||
## Open tracking
|
||||
|
||||
When open tracking is enabled, Plunk includes a small, invisible tracking pixel in your emails. When a contact opens the email, the pixel is loaded, and Plunk records the open event.
|
||||
|
||||
### Considerations
|
||||
- Open tracking relies on the loading of images in the email client. If a contact has images disabled, the open event may not be recorded.
|
||||
- Some email clients may pre-load images, which can result in false open events.
|
||||
|
||||
## Click tracking
|
||||
|
||||
Click tracking is enabled by default for all emails sent through Plunk. When a contact clicks on a link in the email, Plunk records the click event and tracks which link was clicked.
|
||||
|
||||
### Considerations
|
||||
- Click tracking works by rewriting the URLs in your email to point to Plunk's tracking servers
|
||||
- Some email clients or security software may block tracking links, which can result in missed click events
|
||||
|
||||
## Configuration
|
||||
There are three levels of configuration for tracking:
|
||||
|
||||
| Level | Description |
|
||||
|-------|-------------|
|
||||
| Enabled | Tracking is enabled for all emails |
|
||||
| Disabled | Tracking is disabled for all emails |
|
||||
| Marketing only | Tracking is enabled only for marketing emails (templates and campaigns) |
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: Verifying domains
|
||||
description: Ensure your emails reach the inbox by verifying your sending domains
|
||||
icon: Globe
|
||||
---
|
||||
|
||||
Verifying your domain is a requirement to send emails through Plunk. Domain verification helps improve email deliverability and ensures that your emails are less likely to be marked as spam.
|
||||
|
||||
## Verifying a domain
|
||||
|
||||
You can verify a domain by adding it in the domain tab of the project settings. Once added, Plunk will provide you with the necessary DNS records to add to your domain's DNS settings.
|
||||
Once you have added the DNS records, it may take some time for the changes to propagate. You can check the verification status in the domain tab of the project settings.
|
||||
|
||||
### DNS Records
|
||||
- 3 CNAME records for DKIM (DomainKeys Identified Mail) to authenticate your emails.
|
||||
- 1 TXT record for SPF (Sender Policy Framework) to specify which mail servers are authorized
|
||||
- 1 MX record to handle bounces and feedback loops
|
||||
@@ -6,51 +6,51 @@ icon: House
|
||||
|
||||
## What is Plunk?
|
||||
|
||||
Plunk is an open-source email platform designed for developers who need a powerful, scalable solution for transactional and marketing emails. Built with modern technologies and designed to handle millions of contacts, Plunk provides everything you need to manage your email communications.
|
||||
Plunk is an open-source email platform built on top of AWS SES. It is designed for developers who need a powerful, scalable solution for transactional and marketing emails. Built with modern technologies and designed to handle millions of contacts, Plunk provides everything you need to manage your email communications.
|
||||
|
||||
## Key Features
|
||||
|
||||
<Cards>
|
||||
<Card title="Transactional Emails" href="/api-reference/public-api">
|
||||
<Card title="Transactional Emails" href="/concepts/transactional-emails">
|
||||
Send transactional emails via API with template support and variable substitution
|
||||
</Card>
|
||||
<Card title="Email Campaigns" href="/guides/campaigns">
|
||||
<Card title="Email Campaigns" href="/concepts/campaigns">
|
||||
Create and send one-time email broadcasts to your contacts with advanced scheduling
|
||||
</Card>
|
||||
<Card title="Marketing Automation" href="/guides/workflows">
|
||||
<Card title="Marketing Automation" href="/concepts/workflows">
|
||||
Build automated email sequences with visual workflow builder and conditional logic
|
||||
</Card>
|
||||
<Card title="Contact Management" href="/guides/contacts">
|
||||
<Card title="Contact Management" href="/concepts/contacts">
|
||||
Manage millions of contacts with custom fields and CSV import capabilities
|
||||
</Card>
|
||||
<Card title="Dynamic Segmentation" href="/guides/segments">
|
||||
<Card title="Dynamic Segmentation" href="/concepts/segments">
|
||||
Create dynamic audience segments based on contact data and behavior
|
||||
</Card>
|
||||
<Card title="Event Tracking" href="/guides/events">
|
||||
Track events and use them to trigger workflows and segment audiences
|
||||
</Card>
|
||||
<Card title="Email Templates" href="/guides/templates">
|
||||
<Card title="Email Templates" href="/concepts/templates">
|
||||
Create reusable email templates for transactional and marketing emails
|
||||
</Card>
|
||||
<Card title="Analytics" href="/guides/analytics">
|
||||
Track email performance with detailed analytics on opens, clicks, and more
|
||||
<Card title="Event Tracking" href="/guides/tracking">
|
||||
Track events and use them to trigger workflows and segment audiences
|
||||
</Card>
|
||||
<Card title="Billing" href="/concepts/billing">
|
||||
Understand Plunk's billing model and pricing
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
## Quick Links
|
||||
|
||||
<Cards>
|
||||
<Card title="Get Started" href="/getting-started/introduction">
|
||||
Learn how to set up Plunk and send your first email
|
||||
</Card>
|
||||
<Card title="API Reference" href="/api-reference/overview">
|
||||
Explore the complete API documentation
|
||||
</Card>
|
||||
<Card title="Self-Hosting" href="/self-hosting/introduction">
|
||||
Deploy Plunk on your own infrastructure
|
||||
</Card>
|
||||
<Card title="Guides" href="/guides/contacts">
|
||||
Step-by-step guides for common use cases
|
||||
<Card title="Domain Verification" href="/guides/verifying-domains">
|
||||
Learn how to verify your domains for sending emails
|
||||
</Card>
|
||||
<Card title="API Keys" href="/guides/api-keys">
|
||||
Manage your API keys and authentication
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
{
|
||||
"pages": [
|
||||
"index",
|
||||
"---Getting Started---",
|
||||
"getting-started",
|
||||
"---Tutorials---",
|
||||
"tutorials",
|
||||
"---Core Concepts---",
|
||||
"---Docs---",
|
||||
"concepts",
|
||||
"---Automation---",
|
||||
"automation-patterns",
|
||||
"guides",
|
||||
"---API Reference---",
|
||||
"api-reference",
|
||||
"---Self-Hosting---",
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
title: Send Your First Email
|
||||
description: Send a transactional email in 5 minutes
|
||||
icon: Mail
|
||||
---
|
||||
|
||||
## 1. Get your API key
|
||||
|
||||
1. Go to **Settings → General**
|
||||
2. Copy your **Secret Key** (starts with `sk_`)
|
||||
|
||||
## 2. Send the email
|
||||
|
||||
```bash
|
||||
curl -X POST {{API_URL}}/v1/send \
|
||||
-H "Authorization: Bearer sk_your_secret_key" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"to": "user@example.com",
|
||||
"subject": "Hello from Plunk",
|
||||
"body": "<p>Your first email!</p>"
|
||||
}'
|
||||
```
|
||||
|
||||
## 3. With variables
|
||||
|
||||
```javascript
|
||||
await fetch('{{API_URL}}/v1/send', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.PLUNK_SECRET_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
to: user.email,
|
||||
subject: 'Reset your password',
|
||||
body: '<p>Hi {{name}}, click here: <a href="{{resetLink}}">Reset</a></p>',
|
||||
name: user.name,
|
||||
resetLink: `https://app.com/reset/${token}`
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
## 4. Using a template
|
||||
|
||||
1. Create template in **Templates → Create Template**
|
||||
2. Send using template ID:
|
||||
|
||||
```javascript
|
||||
{
|
||||
to: user.email,
|
||||
template: 'clx123abc456',
|
||||
name: user.name,
|
||||
resetLink: resetUrl
|
||||
}
|
||||
```
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"title": "Tutorials",
|
||||
"pages": ["first-transactional-email", "welcome-series-workflow", "newsletter-campaign", "segment-based-targeting"]
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
title: Send a Newsletter
|
||||
description: Broadcast an email to your audience
|
||||
icon: Send
|
||||
---
|
||||
|
||||
## 1. Create a campaign
|
||||
|
||||
1. Go to **Campaigns → Create Campaign**
|
||||
2. Name: `March Newsletter`
|
||||
|
||||
## 2. Write your email
|
||||
|
||||
- **From:** Your verified domain
|
||||
- **Subject:** `March updates you'll love`
|
||||
- Write your content
|
||||
|
||||
## 3. Select audience
|
||||
|
||||
Choose one:
|
||||
- **All contacts:** Everyone subscribed
|
||||
- **Segment:** A saved segment
|
||||
- **Filtered:** Custom filters for this campaign
|
||||
|
||||
## 4. Test
|
||||
|
||||
1. Click **Send Test**
|
||||
2. Check your inbox
|
||||
3. Verify links and content
|
||||
|
||||
## 5. Send
|
||||
|
||||
- **Send Now:** Starts immediately
|
||||
- **Schedule:** Pick date and time
|
||||
|
||||
## 6. Monitor
|
||||
|
||||
View stats at **Campaigns → Your campaign**:
|
||||
- Sent, delivered, opened, clicked, bounced
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
title: Target with Segments
|
||||
description: Send to specific audiences
|
||||
icon: Users
|
||||
---
|
||||
|
||||
## 1. Create a segment
|
||||
|
||||
1. Go to **Segments → Create Segment**
|
||||
2. Name: `Premium Users`
|
||||
|
||||
## 2. Add filters
|
||||
|
||||
Example: Premium subscribers
|
||||
|
||||
- Field: `plan`
|
||||
- Operator: `equals`
|
||||
- Value: `premium`
|
||||
|
||||
Add more conditions with AND/OR.
|
||||
|
||||
## 3. Use in campaigns
|
||||
|
||||
1. Create campaign
|
||||
2. Audience: Select **Segment**
|
||||
3. Choose `Premium Users`
|
||||
|
||||
## 4. Use in workflows
|
||||
|
||||
1. Create workflow
|
||||
2. Trigger: **Segment entry**
|
||||
3. Choose your segment
|
||||
4. Enable **Track membership changes** on the segment
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
title: Build a Welcome Series
|
||||
description: Create a 3-email onboarding workflow
|
||||
icon: Workflow
|
||||
---
|
||||
|
||||
## What you'll build
|
||||
|
||||
- Day 0: Welcome email (immediate)
|
||||
- Day 1: Feature tour
|
||||
- Day 3: Help offer
|
||||
|
||||
## 1. Create templates
|
||||
|
||||
Create 3 templates in **Templates → Create Template**:
|
||||
- `Welcome` (use `{{name}}` for personalization)
|
||||
- `Feature Tour`
|
||||
- `Help Offer`
|
||||
|
||||
## 2. Create the workflow
|
||||
|
||||
1. Go to **Workflows → Create Workflow**
|
||||
2. Name: `Welcome Series`
|
||||
3. Trigger: Event `user_signed_up`
|
||||
4. Allow Re-entry: No
|
||||
|
||||
## 3. Build the flow
|
||||
|
||||
```
|
||||
[Trigger: user_signed_up]
|
||||
↓
|
||||
[Send: Welcome]
|
||||
↓
|
||||
[Delay: 1 day]
|
||||
↓
|
||||
[Send: Feature Tour]
|
||||
↓
|
||||
[Delay: 2 days]
|
||||
↓
|
||||
[Send: Help Offer]
|
||||
↓
|
||||
[Exit]
|
||||
```
|
||||
|
||||
## 4. Enable the workflow
|
||||
|
||||
Toggle the workflow ON.
|
||||
|
||||
## 5. Track signups
|
||||
|
||||
Add to your app:
|
||||
|
||||
```javascript
|
||||
await fetch('{{API_URL}}/v1/track', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${PLUNK_PUBLIC_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
event: 'user_signed_up',
|
||||
email: user.email,
|
||||
data: { name: user.name }
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
Use your **Public Key** (starts with `pk_`).
|
||||
Reference in New Issue
Block a user