Sending and message events
Send an email and understand what happens to it afterward.
Send an email by providing who it is from, who should receive it, a subject and the message. You can send plain text, formatted HTML or both. The sender address must belong to a domain you have verified in SendHog.
An SDK is a code library that connects your application to SendHog. Choose the SendHog SDK for a new application, or use a familiar provider style for the supported sending methods. All options use your SendHog API key. The getting started guide covers the setup.
Send from your application
The example below shows the code for your chosen provider and language. Replace the example addresses with your verified sender and your own inbox.
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.What you can send
- A message with a subject and a plain-text or HTML body.
- Up to 50 recipients in total, including To, CC and BCC.
- Up to 10 reply-to addresses, which tell the recipient’s email app where to send replies.
Attachments, scheduled sends, email open/click tracking and batches are not supported. Publish SendHog templates in the dashboard for supported native template sends; original providers’ template IDs are not interchangeable. Unrecognized options produce an error rather than being silently ignored.
Technical limits: each text or HTML body can contain up to 100,000 characters. Use UTF-8 text encoding. The maximum HTTP request size is 1 MiB. Raw MIME messages, custom headers and provider-specific settings are not supported.
Understand the result
A successful request returns a message ID so you can identify the email later. If the request fails, the SDK reports an error with a code, explanation and request ID. It does not automatically try to send again.
In the SendHog SDK, call client.send with from, to, subject, and text or html. The result contains { id, created_at }; read result.id. Failures throw an exception. Optional fields are cc, bcc and replyTo (Python: reply_to). Recipients and reply-to accept one address or a list.
Provider styles use their familiar response fields: SES MessageId, Postmark MessageID, Resend id, and SendGrid’s response/body pair. See SDK response details for differences, including Resend’s JavaScript error result.
For direct HTTP calls, send the same message fields to POST /v1/send. See the API reference for authentication and field definitions.
Message events and delivery states
The dashboard email log shows saved messages and their latest status. A message ID means SendHog accepted the request; it does not mean the email has reached the recipient’s inbox.
| Status | Meaning |
|---|---|
accepted | The message was accepted for processing. Delivery is not yet confirmed. |
delivered | The recipient’s mail server accepted the email. It may still be placed in a spam folder rather than the inbox. |
bounced | The recipient’s mail system rejected the message. Check the reason and whether the address is blocked from further sends before trying again. |
failed | Processing failed. Check what happened before deciding whether it is safe to retry. |
received | An incoming email was saved. This does not describe an email you sent. |
These statuses describe saved messages. SendHog does not yet send delivery notifications to your application through webhooks, or track email opens and link clicks. Existing event handlers from another provider will not automatically work with SendHog.
Sending is automatically approved when your domain is verified. Account allowances, provider safety limits and abuse protections still apply. Sending can be disabled if necessary. Demo messages are examples, not real deliveries.
Read results in your application
Your application can look up saved messages using an API key with read-email permission, called email.read. A sending-only key cannot read message details.
Use GET /v1/messages?direction=sent to list sent mail and GET /v1/messages/{id} to open one message. See the API reference for fields and how to request more results.