Documentation

Build with Pigeonify

Everything you need to integrate Pigeonify into your application.

Quick start guide

API integration

Send emails programmatically using our RESTful API.

View API docs

SMTP setup

Configure SMTP to send emails from your application.

SMTP guide

Billing & plans

Compare plans and manage your subscription.

View pricing

Send your first email

One HTTPS call, or standard SMTP if you already have a mail layer. Pick your language, paste it in, and swap the sending address for a domain you've verified.

curl -X POST https://www.pigeonify.com/api/v1/send \
  -H "X-API-Key: $PIGEONIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "You <hello@yourdomain.com>",
    "to": "recipient@example.com",
    "subject": "Hello from Pigeonify",
    "html": "<strong>It works!</strong>"
  }'

Every example reads your key from PIGEONIFY_API_KEY rather than hardcoding it — an API key committed to a repository is a key you have to rotate. Create one under Dashboard → API Keys.

API documentation

Authentication

All API requests require an API key. You can generate API keys from your dashboard under Settings → API Keys.

Include your API key in the X-API-Key header:

X-API-Key: pgn_your_api_key_here

Send email

POST/api/v1/send

Send a single email through the Pigeonify API.

Request headers:

Content-Type: application/json
X-API-Key: pgn_your_api_key_here

Request body:

{
  "from": "noreply@yourdomain.com",
  "to": "recipient@example.com",
  "subject": "Hello from Pigeonify",
  "html": "<h1>Hello!</h1><p>This is a test email.</p>",
  "text": "Hello! This is a test email.",
  "reply_to": "support@yourdomain.com"
}
Required fields: from, to, subject, html
Optional fields: text, reply_to

Example request (cURL):

curl --location 'https://pigeonify.com/api/v1/send' \
--header 'Content-Type: application/json' \
--header 'X-API-Key: pgn_your_api_key_here' \
--data-raw '{
  "from": "noreply@yourdomain.com",
  "to": "recipient@example.com",
  "subject": "Hello from Pigeonify",
  "html": "<h1>Hello!</h1><p>This is a test email.</p>",
  "text": "Hello! This is a test email."
}'

Success response (200):

{
  "success": true,
  "message": "Email sent successfully",
  "sent": 2,
  "suppressed": ["unsubscribed@example.com"]
}

Recipients that have unsubscribed, hard bounced, or reported spam are skipped automatically and returned in suppressed. The rest of the batch is still delivered, and sent counts what actually went out. Manage the list under Suppressions in the dashboard.

Error responses:

401 Unauthorized
{
  "error": "Missing X-API-Key header"
}
400 Bad Request
{
  "error": "Missing required fields: from, to, subject, html"
}

How to get your API key

  1. Log in to your Pigeonify dashboard
  2. Navigate to Dashboard → API Keys
  3. Click "Create API Key"
  4. Give your key a name (e.g., "Production API")
  5. Copy the generated key (it starts with pgn_)
  6. Store it securely — you won't be able to see it again!

SMTP configuration

SMTP settings

Use your personal SMTP credentials to send emails from your verified domains. Generate your credentials in the Settings → SMTP section.

Host:
smtp.pigeonify.com
Port (STARTTLS):
587
Port (implicit TLS):
465
Username:
Your SMTP username (from Settings)
Password:
Your SMTP password (from Settings)
Max message size:
25 MB

TLS is required. Authentication is refused on an unencrypted connection, so your credentials are never sent in clear. On port 587 your client must issue STARTTLS before logging in — most do automatically, but set requireTLS or the equivalent if yours allows plaintext fallback. Port 465 is encrypted from the first byte.

Send only from verified domains. The address in your From header must be on a domain you have verified under Domains, or the message is refused with a 550.

Node.js example (Nodemailer):

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'smtp.pigeonify.com',
  port: 587,
  secure: false,      // STARTTLS on 587
  requireTLS: true,   // refuse to send if the upgrade fails
  auth: {
    user: 'smtp-12345678',      // Your SMTP username
    pass: 'your-smtp-password'  // Your SMTP password
  }
});

// Or, for implicit TLS:
//   port: 465, secure: true   (requireTLS is unnecessary)

await transporter.sendMail({
  from: 'sender@yourdomain.com', // Must be a verified domain
  to: 'recipient@example.com',
  subject: 'Hello from Pigeonify',
  html: '<h1>Hello World</h1>'
});

Python example (smtplib):

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg['Subject'] = 'Hello from Pigeonify'
msg['From'] = 'sender@yourdomain.com'   # Must be a verified domain
msg['To'] = 'recipient@example.com'
msg.set_content('Hello World')
msg.add_alternative('<h1>Hello World</h1>', subtype='html')

# STARTTLS on 587
with smtplib.SMTP('smtp.pigeonify.com', 587) as server:
    server.starttls()
    server.login('smtp-12345678', 'your-smtp-password')
    server.send_message(msg)

# Implicit TLS on 465
# with smtplib.SMTP_SSL('smtp.pigeonify.com', 465) as server:
#     server.login('smtp-12345678', 'your-smtp-password')
#     server.send_message(msg)

What we add to your messages

Every message is signed with DKIM for your domain, and an unsubscribe link and the List-Unsubscribe headers are added automatically. Gmail and Yahoo require those headers from bulk senders, and we cannot tell a newsletter from a receipt over SMTP, so they are applied to everything.

Reply codes

A 5xx means the message will never be accepted as sent: an unverified sending domain, a recipient who has unsubscribed or is known undeliverable, or content our checks refused. Do not retry these.

A 4xx is temporary — a rate limit, a plan limit, or a problem at our end. Retry with backoff. Sending is limited to 100 messages per minute per account, with a per-second ceiling on top, so a client that paces itself will not see these.

Getting started:

  1. Go to Settings → SMTP in your dashboard
  2. Click "Generate SMTP Credentials" to create your credentials
  3. Copy your SMTP username and password (password shown only once)
  4. Verify a domain in the Domains section
  5. Use the credentials in your application to send emails

Domain setup

Verify your domain

To send emails from your domain, you need to verify it by adding DNS records:

  1. Go to Dashboard > Domains and add your domain
  2. Copy the provided DNS records (TXT, SPF, DKIM, DMARC)
  3. Add these records to your domain's DNS settings
  4. Click "Verify" to confirm the setup

Note: DNS changes can take up to 48 hours to propagate, but usually complete within a few hours.

Need help?

Can't find what you're looking for? Our support team is here to help.

Contact support