Update wiki

This commit is contained in:
Dries Augustyns
2025-12-07 10:25:18 +01:00
parent b2ecf60a13
commit 0003e44db8
23 changed files with 3336 additions and 5 deletions
@@ -0,0 +1,177 @@
---
title: Send Your First Email
description: Send a transactional email in 5 minutes
icon: Mail
---
## Get your API key
1. Go to [Settings → General]({{DASHBOARD_URL}}/settings)
2. Copy your **Secret Key** (starts with `sk_`)
**Important:** Use Secret Key server-side only. Never expose it in client code.
## 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": "[email protected]",
"subject": "Reset your password",
"body": "<p>Click here to reset: <a href=\"https://app.com/reset/abc123\">Reset Password</a></p>",
"subscribed": true
}'
```
Replace `sk_your_secret_key` and `[email protected]` with your values.
### With JavaScript
```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>Click here: <a href="${resetLink}">Reset Password</a></p>`,
subscribed: true
})
});
```
### With Python
```python
import requests
import os
requests.post('{{API_URL}}/v1/send',
headers={
'Authorization': f'Bearer {os.environ["PLUNK_SECRET_KEY"]}',
'Content-Type': 'application/json'
},
json={
'to': user.email,
'subject': 'Reset your password',
'body': f'<p>Click here: <a href="{reset_link}">Reset Password</a></p>',
'subscribed': True
}
)
```
## Use variables
Make emails dynamic 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}`,
subscribed: true
})
});
```
Variables in the body (`{{name}}`, `{{resetLink}}`) are replaced with the values you provide.
## Use templates
Instead of passing HTML every time, create reusable templates.
### Create a template
1. Go to **Templates** → **Create Template**
2. Name: `Password Reset`
3. Type: `Transactional`
4. Subject: `Reset your password`
5. Body:
```html
<p>Hi {{name}},</p>
<p>Click here to reset your password:</p>
<p><a href="{{resetLink}}">Reset Password</a></p>
<p>This link expires in 1 hour.</p>
```
### Send with template
```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,
template: 'password-reset', // Use template slug
name: user.name,
resetLink: `https://app.com/reset/${token}`,
subscribed: true
})
});
```
No need to pass `subject` or `body` - they come from the template.
## Integration example
```javascript
// Express.js password reset endpoint
app.post('/forgot-password', async (req, res) => {
const { email } = req.body;
const user = await db.users.findOne({ email });
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
const token = crypto.randomBytes(32).toString('hex');
await db.resetTokens.create({ userId: user.id, token, expiresAt: Date.now() + 3600000 });
// Send email via Plunk
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>Click here: <a href="https://app.com/reset/${token}">Reset Password</a></p>`,
subscribed: true
})
});
res.json({ success: true });
});
```
## Troubleshooting
**"Unauthorized" error** — Check your API key. Must be Secret Key (starts with `sk_`).
**Email not received** — Check spam folder. If using custom domain, verify it in Settings → Domains.
**Variables not replaced** — Ensure variable names match exactly (case-sensitive).
## Next steps
- [Build a workflow](/tutorials/welcome-series-workflow) for automated sequences
- [Set up custom domain](/guides/custom-domains) for better deliverability
- [Track events](/tutorials/event-tracking-integration) to trigger workflows