Preview a personalized email
Returns the fully personalized subject and body for a given sequence step,
lead, and mailbox. All variables ({{firstName}}, custom fields, {{senderName}}, etc.),
conditional blocks (IF/ELSE), and spintax ({option1|option2}) are resolved.
Use contentOverride to preview unsaved draft content without modifying the campaign.
curl -X POST "https://api.sendkit.ai/v1/campaigns/example_string/preview-email" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"sequenceStep": 1,
"leadId": "665d4e5f6a7b8c9d0e1f2a3b",
"mailboxId": "665b1c2d3e4f5a6b7c8d9e0f"
}'
import requests
import json
url = "https://api.sendkit.ai/v1/campaigns/example_string/preview-email"
headers = {
"Content-Type": "application/json",
"X-Api-Key": "YOUR_API_KEY"
}
data = {
"sequenceStep": 1,
"leadId": "665d4e5f6a7b8c9d0e1f2a3b",
"mailboxId": "665b1c2d3e4f5a6b7c8d9e0f"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://api.sendkit.ai/v1/campaigns/example_string/preview-email", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": "YOUR_API_KEY"
},
body: JSON.stringify({
"sequenceStep": 1,
"leadId": "665d4e5f6a7b8c9d0e1f2a3b",
"mailboxId": "665b1c2d3e4f5a6b7c8d9e0f"
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"sequenceStep": 1,
"leadId": "665d4e5f6a7b8c9d0e1f2a3b",
"mailboxId": "665b1c2d3e4f5a6b7c8d9e0f"
}`)
req, err := http.NewRequest("POST", "https://api.sendkit.ai/v1/campaigns/example_string/preview-email", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Api-Key", "YOUR_API_KEY")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://api.sendkit.ai/v1/campaigns/example_string/preview-email')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['X-Api-Key'] = 'YOUR_API_KEY'
request.body = '{
"sequenceStep": 1,
"leadId": "665d4e5f6a7b8c9d0e1f2a3b",
"mailboxId": "665b1c2d3e4f5a6b7c8d9e0f"
}'
response = http.request(request)
puts response.body
{
"success": true,
"data": {
"subject": "Quick question, John",
"body": "<p>Hi John,</p><p>I noticed Acme Corp is growing fast...</p>",
"to": {
"name": "John Doe",
"email": "john@acme.com"
},
"from": {
"name": "Sarah from SendKit",
"email": "sarah@sendkit.ai"
}
}
}
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "sequenceStep, leadId, and mailboxId are required"
}
}
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid sequence step or not an email step"
}
}
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Campaign not found"
}
}
/v1/campaigns/{campaignId}/preview-emailTarget server for requests. Edit to use your own host.
Platform API key (sk_user_...) or Workspace API key (sk_...)
Campaign ID
The media type of the request body
1-based index of the email step to preview (only counts email steps, skips wait steps)
Lead ID to personalize with
Mailbox ID for sender variables and signature
A/B variant label (e.g. "B") - uses main step if omitted
Override step content for unsaved drafts
Request Preview
Response
Response will appear here after sending the request
Authentication
API Key for authentication. Platform API key (sk_user_...) or Workspace API key (sk_...)
Path Parameters
Campaign ID
Body
1-based index of the email step to preview (only counts email steps, skips wait steps)
1Lead ID to personalize with
Mailbox ID for sender variables and signature
A/B variant label (e.g. "B") - uses main step if omitted
Override step content for unsaved drafts
Responses
Missing required fields or invalid sequence step
Campaign, lead, or mailbox not found