docs: Improve docs with core-concept and guides

This commit is contained in:
Dries Augustyns
2025-12-28 10:46:46 +01:00
parent 862babb8f5
commit 2ddfceca36
46 changed files with 652 additions and 1195 deletions
@@ -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": "[email protected]",
"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": "[email protected]",
"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": "[email protected]",
"data": {
"locale": "de" // German
}
}
```
**Via tracking:**
```javascript
POST /v1/track
{
"event": "signup",
"email": "[email protected]",
"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": "[email protected]",
"from": "[email protected]",
"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 -12
View File
@@ -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.