Migration and rollback
Move your email to SendHog in small steps, with a way to switch back if needed.
Start by moving one kind of email, such as a sign-in message or a receipt. Keep your current provider running until you have checked that the new setup works. Rollback means switching that email back to your previous provider if something goes wrong.
Choose your provider for specific steps. We remember this choice across the guides and code examples. If there is no matching SDK style, the examples use SendHog’s own library.
Migrate from your current provider
Starting a new application?
Use SendHog’s own code library and follow Getting started. You do not need to choose another provider’s SDK style.
Already using another email service? Select it above for the steps to move and switch back safely. Keep that service active until SendHog is ready for live email.
Amazon SES to SendHog
Move one kind of outgoing email from Amazon SES to SendHog. Keep your existing AWS setup available so other services keep working and you can switch back.
Check what you use today
- Your AWS region, verified domains, email-authentication records (DKIM and custom MAIL FROM) and sending limits.
- The sending features your application uses, including templates, configuration sets and SNS delivery notifications.
- AWS access permissions (IAM), incoming-email rules and any files saved in S3.
Connect your application to SendHog
Use the SendHog SES-style SDK and a SendHog API key instead of AWS credentials. It supports the listed SES v2 Simple text/HTML methods: SendEmailCommand in JavaScript and send_email in Python. Your developer must change the package and client setup, not just the server address.
Check the supported SDK methods and sending options before changing code. For JavaScript and TypeScript, run npm install @sendhog/sdk. For Python, run python -m pip install sendhog-sdk (Python 3.11+).
Steps to move safely
- Add and verify the domain in SendHog without removing existing SES domain verification or DKIM records. Only add the records SendHog asks for. If SPF needs an update, change the existing record instead of adding a second one.
- Move a basic text or HTML message first. Templates, attachments, configuration sets and tags are not supported by this SDK version; leave those emails with SES or change how your application creates them.
- Keep existing delivery notifications and incoming-email rules running. Sending a test email does not require changing where incoming mail is delivered or removing AWS permissions.
How to switch back to Amazon SES
Restore the previous AWS SES library, region and credentials. Keep the verified domains, IAM permissions and delivery notifications until you have decided the move is successful.
Postmark to SendHog
Move one kind of Postmark email while keeping blocked-address lists, delivery notifications and incoming mail working.
Check what you use today
- The Postmark server, verified sender and message stream used for this email. A stream separates types of email, such as account messages and broadcasts.
- Saved templates and the information your application fills into them, including TemplateID and MessageStream options.
- Blocked recipients, delivery and bounce notifications, tracking and incoming-email handling.
Connect your application to SendHog
Use the SendHog Postmark-style SDK and a SendHog API key instead of your Postmark server token. Supported calls use sendEmail in JavaScript and outbound.send in Python. Check the API reference for the message fields you can keep.
Check the supported SDK methods and sending options before changing code. For JavaScript and TypeScript, run npm install @sendhog/sdk. For Python, run python -m pip install sendhog-sdk (Python 3.11+).
Steps to move safely
- Choose one transactional message, such as a receipt. Keep marketing audiences separate, and save the blocked-address and unsubscribe lists that apply to this email.
- Verify the domain in SendHog. Keep existing Postmark DKIM and return-path records; review any SPF change before editing it.
- Move basic text/HTML messages using the SendHog Postmark-style SDK. Saved template IDs, tracking and MessageStream options are not supported. Have your application create the finished message, or leave template-based emails with Postmark.
- Review automatic delivery notifications separately: their IDs and data can differ. Keep Postmark incoming email unchanged while moving outgoing email.
How to switch back to Postmark
Restore the Postmark library, server token and message stream. Keep templates, blocked-address lists and notifications. Check which messages were already accepted before trying them again.
SendGrid to SendHog
Move a small part of your SendGrid sending first. Keep unsubscribe groups, templates and delivery notifications until their replacements are ready.
Check what you use today
- Verified domains, branded links, sending IP settings and API-key permissions.
- Dynamic templates, message personalization, categories and unsubscribe groups (ASM).
- Unsubscribes, bounced addresses, spam reports, delivery notifications (Event Webhook) and incoming email (Inbound Parse).
Connect your application to SendHog
Use the SendHog SendGrid-style SDK with a SendHog API key. It supports the listed send method and basic message fields. Keeping @sendgrid/mail and only changing its server address will not connect it to SendHog.
Check the supported SDK methods and sending options before changing code. For JavaScript and TypeScript, run npm install @sendhog/sdk. For Python, run python -m pip install sendhog-sdk (Python 3.11+).
Steps to move safely
- Save unsubscribe groups and blocked addresses before moving anything. Make sure your application keeps those people blocked; SendGrid lists are not transferred automatically.
- Add and verify the domain in SendHog while keeping SendGrid verification available. Leave Inbound Parse and incoming-mail records alone when moving only outgoing email.
- Use the SendHog SendGrid-style SDK for the supported sender, recipients, subject and text/HTML fields. Dynamic templates, ASM and tracking need separate work; do not drop those settings without checking their purpose.
- Check which delivery information SendHog provides before changing an Event Webhook handler. A successful send request does not prove the email reached the recipient.
How to switch back to SendGrid
Restore the SendGrid library, API key, templates and unsubscribe-group settings. Check accepted messages before sending them again so recipients do not get duplicates.
Mailgun to SendHog
Move one kind of Mailgun email to SendHog’s own library. Existing Mailgun requests need changes; they cannot be sent to SendHog unchanged.
Check what you use today
- Your Mailgun sending domain, US/EU region, API keys and domain verification.
- Saved templates, personalized values, tags, tracking and the way your application submits messages.
- Blocked addresses, unsubscribes, mailing lists, delivery notifications and incoming-mail Routes.
Connect your application to SendHog
There is no Mailgun-style SDK yet. Use the SendHog SDK or call the SendHog API directly with a SendHog key. Your developer will map the sender, recipients, subject and message to client.send(message); Mailgun keys and request formats will not work.
Check the supported SDK methods and sending options before changing code. For JavaScript and TypeScript, run npm install @sendhog/sdk. For Python, run python -m pip install sendhog-sdk (Python 3.11+).
Steps to move safely
- Save unsubscribe and blocked-address lists, including bounced addresses. Check whether the chosen email depends on a mailing list or personalized values, and preserve each recipient’s permission to receive it.
- Verify the domain in SendHog while keeping Mailgun DNS and Routes available. Do not change incoming-mail records just to move outgoing email.
- Have your application send the supported sender, recipients, subject and finished text/HTML message. Create saved-template content in your application or keep those emails on Mailgun; Mailgun-only options are not supported.
- Review delivery notifications separately and test the new success/error results before moving live email.
How to switch back to Mailgun
Restore the Mailgun library, domain, regional server address and API key. Keep Routes, templates, blocked-address lists and delivery notifications until testing is complete.
Resend to SendHog
Move one kind of Resend email, while checking how your message is built and how blocked addresses and delivery notifications are handled.
Check what you use today
- Your Resend domains, API keys, sender addresses and DNS settings.
- How messages are built, including React Email, templates, attachments, scheduled sends, batches and tags.
- Delivery notifications and their security checks, blocked-address lists, marketing audiences and incoming mail.
Connect your application to SendHog
Use the SendHog Resend-style SDK and a SendHog API key, not your Resend key. Supported text/HTML calls use emails.send in JavaScript and Emails.send in Python. Change the package and client setup; supported method names and response fields stay familiar.
Check the supported SDK methods and sending options before changing code. For JavaScript and TypeScript, run npm install @sendhog/sdk. For Python, run python -m pip install sendhog-sdk (Python 3.11+).
Steps to move safely
- Choose one account or application message and save its recipient-permission and blocked-address rules. Keep broadcasts and audience management separate.
- Verify your domain in SendHog while retaining Resend DNS settings so you can switch back. Leave incoming-mail settings unchanged until you review receiving separately.
- Switch to the SendHog Resend-style SDK. If you use React Email, turn it into finished HTML in your application first. React components, attachments, scheduling and batches are not supported as send options.
- Test success and error results and review available delivery information. Do not reuse Resend webhook secrets or assume its notification security checks apply to SendHog.
How to switch back to Resend
Restore the Resend library, API key and previous message-building code. Keep domain verification and delivery-notification settings until the new setup has passed your tests.
Brevo to SendHog
Move one application email from Brevo, without changing your marketing lists, automated campaigns or recipient permissions.
Check what you use today
- Your sending code or SMTP settings, verified senders, domains and API keys.
- Templates, personalized values, contact details, marketing lists and automated campaigns.
- Sending logs, blocked contacts, unsubscribes and automatic delivery notifications.
Connect your application to SendHog
There is no Brevo-style SDK yet. Use SendHog’s own SDK or API with a SendHog key. Your developer will replace sendTransacEmail or SMTP sending with client.send(message). Brevo API keys and SMTP passwords do not work with SendHog.
Check the supported SDK methods and sending options before changing code. For JavaScript and TypeScript, run npm install @sendhog/sdk. For Python, run python -m pip install sendhog-sdk (Python 3.11+).
Steps to move safely
- Choose an application email that does not rely on a Brevo campaign sequence. Save blocked and unsubscribed contacts and the record of each recipient’s permission.
- Verify your domain in SendHog while keeping Brevo DNS settings. Moving outgoing email should not change your contact lists or campaign rules.
- Send the basic sender, recipients, subject and finished text/HTML message through SendHog. Replace templateId/params with content built by your application, or keep those emails on Brevo.
- Review marketing automation and delivery notifications separately. Check SendHog results and errors before retiring Brevo logs or notifications.
How to switch back to Brevo
Restore the Brevo API or SMTP settings and original templates. Keep blocklists, recipient permissions and campaigns intact while you test.
Mailjet to SendHog
Move one kind of Mailjet email. Templates and campaign settings do not move automatically, so keep them available while you test.
Check what you use today
- Verified senders and domains, API keys, subaccounts and the Mailjet Send API version in use.
- Templates and personalized values, including Messages arrays, TemplateID, TemplateLanguage and Variables.
- Contact lists, unsubscribes, excluded addresses, delivery notifications (Event Tracking) and incoming mail.
Connect your application to SendHog
There is no Mailjet-style SDK yet. Use SendHog’s own SDK or API with a SendHog key. Your developer will replace the Mailjet package and message format with client.send(message); the Mailjet API key and secret cannot be reused.
Check the supported SDK methods and sending options before changing code. For JavaScript and TypeScript, run npm install @sendhog/sdk. For Python, run python -m pip install sendhog-sdk (Python 3.11+).
Steps to move safely
- Choose one application email and save the relevant excluded addresses, unsubscribes and recipient permissions. A contact list is not permission to email people who have opted out.
- Verify the same domain in SendHog without removing Mailjet verification. Keep incoming mail and other applications on their current settings.
- Send one basic message using SendHog’s sender, recipients, subject and text/HTML fields. Have your application create the finished template content, or leave those emails with Mailjet. Batches and Mailjet template IDs are not supported.
- Review returned IDs, error handling and delivery notifications separately. Check recipient limits before moving messages addressed to many people.
How to switch back to Mailjet
Restore the Mailjet library, API key/secret and message format. Keep templates, sender verification, excluded addresses and delivery notifications until the new setup passes your tests.
Code example: SendHog. If your provider does not have a matching SDK style, this shows SendHog’s own library; the provider’s migration steps above still apply.
import { SendHog } from '@sendhog/sdk';
const client = new SendHog(process.env.SENDHOG_API_KEY ?? '');
const { id } = await client.send({
"from": "sender@example.com",
"to": "recipient@example.net",
"subject": "Hello from SendHog",
"text": "Hello from your application."
});
console.log(id);npm install @sendhog/sdkimport { SendHog } from '@sendhog/sdk';
const client = new SendHog(process.env.SENDHOG_API_KEY ?? '');
const { id } = await client.send({
"from": "sender@example.com",
"to": "recipient@example.net",
"subject": "Hello from SendHog",
"text": "Hello from your application."
});
console.log(id);npm install @sendhog/sdkimport os
from sendhog import SendHog
client = SendHog(os.environ['SENDHOG_API_KEY'])
result = client.send({
"from": "sender@example.com",
"to": "recipient@example.net",
"subject": "Hello from SendHog",
"text": "Hello from your application."
})
print(result['id'])python -m pip install sendhog-sdk# Native SendHog HTTP; the SDK translates the SendHog call above.
curl 'https://app.sendhog.com/v1/send' \
-H "Authorization: Bearer $SENDHOG_API_KEY" \
-H 'Content-Type: application/json' \
--data '{
"from": "sender@example.com",
"to": [
"recipient@example.net"
],
"subject": "Hello from SendHog",
"text": "Hello from your application."
}'No SDK installation required.import { SESv2Client, SendEmailCommand } from '@sendhog/sdk/ses';
const apiKey = process.env.SENDHOG_API_KEY;
if (!apiKey) throw new Error('Set SENDHOG_API_KEY on your server.');
const client = new SESv2Client({ apiKey });
const result = await client.send(new SendEmailCommand({
"FromEmailAddress": "sender@example.com",
"Destination": {
"ToAddresses": [
"recipient@example.net"
]
},
"Content": {
"Simple": {
"Subject": {
"Data": "Hello from SendHog"
},
"Body": {
"Text": {
"Data": "Hello from your application."
}
}
}
}
}));
console.log(result.MessageId);npm install @sendhog/sdkimport { SESv2Client, SendEmailCommand } from '@sendhog/sdk/ses';
const apiKey = process.env.SENDHOG_API_KEY;
if (!apiKey) throw new Error('Set SENDHOG_API_KEY on your server.');
const client = new SESv2Client({ apiKey });
const result = await client.send(new SendEmailCommand({
"FromEmailAddress": "sender@example.com",
"Destination": {
"ToAddresses": [
"recipient@example.net"
]
},
"Content": {
"Simple": {
"Subject": {
"Data": "Hello from SendHog"
},
"Body": {
"Text": {
"Data": "Hello from your application."
}
}
}
}
}));
console.log(result.MessageId);npm install @sendhog/sdkimport os
from sendhog.ses import SESv2Client
client = SESv2Client(os.environ['SENDHOG_API_KEY'])
result = client.send_email(**{
"FromEmailAddress": "sender@example.com",
"Destination": {
"ToAddresses": [
"recipient@example.net"
]
},
"Content": {
"Simple": {
"Subject": {
"Data": "Hello from SendHog"
},
"Body": {
"Text": {
"Data": "Hello from your application."
}
}
}
}
})
print(result['MessageId'])python -m pip install sendhog-sdk# Native SendHog HTTP; the SDK translates the Amazon SES call above.
curl 'https://app.sendhog.com/v1/send' \
-H "Authorization: Bearer $SENDHOG_API_KEY" \
-H 'Content-Type: application/json' \
--data '{
"from": "sender@example.com",
"to": [
"recipient@example.net"
],
"subject": "Hello from SendHog",
"text": "Hello from your application."
}'No SDK installation required.import { ServerClient } from '@sendhog/sdk/postmark';
const apiKey = process.env.SENDHOG_API_KEY;
if (!apiKey) throw new Error('Set SENDHOG_API_KEY on your server.');
const client = new ServerClient({ apiKey });
const result = await client.sendEmail({
"From": "sender@example.com",
"To": "recipient@example.net",
"Subject": "Hello from SendHog",
"TextBody": "Hello from your application."
});
console.log(result.MessageID);npm install @sendhog/sdkimport { ServerClient } from '@sendhog/sdk/postmark';
const apiKey = process.env.SENDHOG_API_KEY;
if (!apiKey) throw new Error('Set SENDHOG_API_KEY on your server.');
const client = new ServerClient({ apiKey });
const result = await client.sendEmail({
"From": "sender@example.com",
"To": "recipient@example.net",
"Subject": "Hello from SendHog",
"TextBody": "Hello from your application."
});
console.log(result.MessageID);npm install @sendhog/sdkimport os
from sendhog.postmark import ServerClient
import asyncio
async def main():
async with ServerClient(os.environ['SENDHOG_API_KEY']) as client:
result = await client.outbound.send({
"sender": "sender@example.com",
"to": "recipient@example.net",
"subject": "Hello from SendHog",
"text_body": "Hello from your application."
})
print(result.message_id)
asyncio.run(main())python -m pip install sendhog-sdk# Native SendHog HTTP; the SDK translates the Postmark call above.
curl 'https://app.sendhog.com/v1/send' \
-H "Authorization: Bearer $SENDHOG_API_KEY" \
-H 'Content-Type: application/json' \
--data '{
"from": "sender@example.com",
"to": [
"recipient@example.net"
],
"subject": "Hello from SendHog",
"text": "Hello from your application."
}'No SDK installation required.import { Resend } from '@sendhog/sdk/resend';
const apiKey = process.env.SENDHOG_API_KEY;
if (!apiKey) throw new Error('Set SENDHOG_API_KEY on your server.');
const client = new Resend({ apiKey });
const { data, error } = await client.emails.send({
"from": "sender@example.com",
"to": [
"recipient@example.net"
],
"subject": "Hello from SendHog",
"text": "Hello from your application."
});
if (error) throw new Error(error.message);
console.log(data.id);npm install @sendhog/sdkimport { Resend } from '@sendhog/sdk/resend';
const apiKey = process.env.SENDHOG_API_KEY;
if (!apiKey) throw new Error('Set SENDHOG_API_KEY on your server.');
const client = new Resend({ apiKey });
const { data, error } = await client.emails.send({
"from": "sender@example.com",
"to": [
"recipient@example.net"
],
"subject": "Hello from SendHog",
"text": "Hello from your application."
});
if (error) throw new Error(error.message);
console.log(data.id);npm install @sendhog/sdkimport os
from sendhog.resend import Resend
client = Resend(os.environ['SENDHOG_API_KEY'])
result = client.Emails.send({
"from": "sender@example.com",
"to": [
"recipient@example.net"
],
"subject": "Hello from SendHog",
"text": "Hello from your application."
})
print(result['id'])python -m pip install sendhog-sdk# Native SendHog HTTP; the SDK translates the Resend call above.
curl 'https://app.sendhog.com/v1/send' \
-H "Authorization: Bearer $SENDHOG_API_KEY" \
-H 'Content-Type: application/json' \
--data '{
"from": "sender@example.com",
"to": [
"recipient@example.net"
],
"subject": "Hello from SendHog",
"text": "Hello from your application."
}'No SDK installation required.import { SendGridClient } from '@sendhog/sdk/sendgrid';
const apiKey = process.env.SENDHOG_API_KEY;
if (!apiKey) throw new Error('Set SENDHOG_API_KEY on your server.');
const client = new SendGridClient({ apiKey });
const [response] = await client.send({
"from": "sender@example.com",
"to": "recipient@example.net",
"subject": "Hello from SendHog",
"text": "Hello from your application."
});
console.log(response.headers['x-message-id']);npm install @sendhog/sdkimport { SendGridClient } from '@sendhog/sdk/sendgrid';
const apiKey = process.env.SENDHOG_API_KEY;
if (!apiKey) throw new Error('Set SENDHOG_API_KEY on your server.');
const client = new SendGridClient({ apiKey });
const [response] = await client.send({
"from": "sender@example.com",
"to": "recipient@example.net",
"subject": "Hello from SendHog",
"text": "Hello from your application."
});
console.log(response.headers['x-message-id']);npm install @sendhog/sdkimport os
from sendhog.sendgrid import SendGridAPIClient
client = SendGridAPIClient(os.environ['SENDHOG_API_KEY'])
response = client.send({
"from": {
"email": "sender@example.com"
},
"personalizations": [
{
"to": [
{
"email": "recipient@example.net"
}
]
}
],
"subject": "Hello from SendHog",
"content": [
{
"type": "text/plain",
"value": "Hello from your application."
}
]
})
print(response.headers['x-message-id'])python -m pip install sendhog-sdk# Native SendHog HTTP; the SDK translates the SendGrid call above.
curl 'https://app.sendhog.com/v1/send' \
-H "Authorization: Bearer $SENDHOG_API_KEY" \
-H 'Content-Type: application/json' \
--data '{
"from": "sender@example.com",
"to": [
"recipient@example.net"
],
"subject": "Hello from SendHog",
"text": "Hello from your application."
}'No SDK installation required.Write down your current setup
Note what causes the email to be sent, who receives it, the sending domain, daily and monthly volume, and the provider you use. Include templates, repeat attempts and any automatic delivery notifications your application depends on.
Save the current code and settings so you can restore them. Keep existing domain records and provider access. Record your actual costs so you can compare them later.
Start with one kind of email
- Choose a small, low-risk use case and someone responsible for checking it.
- Keep unsubscribe and blocked-address lists. These are sometimes called suppression lists.
- Confirm you are allowed to contact the recipients and that your sending domain is verified.
- Check which sending features SendHog supports and how your application handles errors.
- Confirm sending is enabled and account limits cover the emails you plan to send.
Your developer will replace the provider package, client setup and credentials with the SendHog SDK. Supported sending calls can stay familiar, but changing only the server address will not work. Receiving is not yet available. Keep your current provider active until you have verified the migrated workflow and its rollback.
Test before moving more email
Once sending is activated, send a test to someone who has agreed to receive it. Check that the request succeeds, the email arrives and the saved message status is correct. Test how your application handles failures and avoids duplicate emails. Confirm blocked recipients remain blocked.
Monitor costs, usage and support needs over time. One successful test does not prove every kind of email is ready to move.
Keep a way to switch back
Keep your old provider active until the new setup has passed your checks. Write down the settings to restore, who can approve the switch and what to do with emails already being processed.
- Check whether a message was already accepted before sending it again through either provider.
- Keep unsubscribes and blocked addresses honored in both systems.
- Keep API keys private; do not put them in notes or reports.
- Test switching back with an agreed test recipient before relying on it.