API v1.0

SendPigeon Documentation

Everything you need to send transactional emails. SDKs for Node.js, Python, Go, PHP and REST API.

Tracking

Track email opens and clicks. Configure organization defaults and per-domain overrides.

Paid plan required. Tracking is available on Starter, Growth, and Pro plans.

Per-Email Tracking

Tracking is opt-in per email. This gives you full control - enable tracking on marketing emails while keeping security emails (password resets, 2FA) tracking-free. Request tracking when sending an email:

cURLbash
curl -X POST https://api.sendpigeon.dev/v1/emails \
-H "Authorization: Bearer sp_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"from": "hello@yourdomain.com",
"subject": "Welcome!",
"html": "<p>Hello world</p>",
"tracking": {
"opens": true,
"clicks": true
}
}'

If tracking is disabled at the organization level, tracking options are ignored and a warning is returned in the response.

How It Works

TypeMechanism
Open trackingInvisible 1x1 pixel loaded when email is viewed
Click trackingLinks rewritten to pass through tracking endpoint

Organization Settings

Configure organization-wide tracking settings (master toggle, privacy mode, webhook behavior):

cURLbash
# Get organization tracking defaults
curl https://api.sendpigeon.dev/v1/tracking/defaults \
-H "Authorization: Bearer sp_live_xxx"
 
# Update organization tracking defaults
curl -X PATCH https://api.sendpigeon.dev/v1/tracking/defaults \
-H "Authorization: Bearer sp_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"trackingEnabled": true,
"privacyMode": false,
"webhookOnEveryOpen": false,
"webhookOnEveryClick": false
}'

Webhook behavior: By default, webhooks fire only on the first open/click per email. Enable webhookOnEveryOpen or webhookOnEveryClick to receive a webhook for every event. This can significantly increase webhook volume.

Webhook Events

When tracking is enabled, you'll receive webhook events for opens and clicks:

Webhook Payloadsjson
// email.opened
{
"event": "email.opened",
"timestamp": "2025-01-15T10:30:00Z",
"data": {
"emailId": "em_abc123",
"toAddress": "user@example.com",
"openedAt": "2025-01-15T10:30:00Z"
}
}
 
// email.clicked
{
"event": "email.clicked",
"timestamp": "2025-01-15T10:31:00Z",
"data": {
"emailId": "em_abc123",
"toAddress": "user@example.com",
"clickedAt": "2025-01-15T10:31:00Z",
"linkUrl": "https://example.com/activate",
"linkIndex": 0
}
}

Custom Tracking Domain

By default, tracking links use t.sendpigeon.dev. On Pro, you can use your own subdomain like t.yourdomain.com.

Why it matters: Custom tracking domains improve deliverability because links point to your domain, not a third-party. Email clients trust links that match your sending domain. It also removes SendPigeon branding from your emails.

TypeNameValue
CNAMEt.yourdomain.comt.sendpigeon.dev
cURLbash
# Set custom tracking domain
curl -X POST https://api.sendpigeon.dev/v1/domains/{domainId}/tracking/set-domain \
-H "Authorization: Bearer sp_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "trackingDomain": "t.yourdomain.com" }'
 
# Verify CNAME is configured
curl -X POST https://api.sendpigeon.dev/v1/domains/{domainId}/tracking/verify \
-H "Authorization: Bearer sp_live_xxx"

Privacy Mode

Enable privacy mode to track opens/clicks without collecting IP addresses, user agents, or location data. Counts only.

cURLbash
curl -X PUT https://api.sendpigeon.dev/v1/domains/{domainId}/tracking \
-H "Authorization: Bearer sp_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"openTracking": true,
"clickTracking": true,
"privacyMode": true
}'

Bot filtering: We filter out known bots, image proxies, and prefetch requests to give you accurate metrics.