API reference
See what your application can do with SendHog and what each action returns.
The API lets your application send email and read saved messages. Our SDKs are ready-made libraries for calling these actions; you can also call the API directly. This page lists the supported actions, required information and results.
Every call needs a SendHog API key. A key only works for its assigned domain and the permissions you gave it. If you are setting up for the first time, follow Getting started.
Connect your application
Send requests to https://app.sendhog.com. Signing in to the dashboard does not replace the API key your application needs.
For direct HTTP calls, include Authorization: Bearer $SENDHOG_API_KEY. Requests containing JSON also need Content-Type: application/json. The SDK handles these headers for you.
Send an email
Send a text or HTML message from a verified domain. Sending is automatically approved after verification; account allowances and safety limits apply. A successful response includes a message ID, not a guarantee of inbox delivery.
POST /v1/send
Required permission: email.send. Response definition: SendResponse.
Provide a sender, recipient, subject and at least one message body: plain text, HTML or both.
JSON fields: from, subject, at least one recipient in to/cc/bcc, and text or html. Optional: replyTo. Recipient fields accept one address or a list. Maximum 50 recipients total and 10 reply-to addresses. Success returns { id, created_at }. While sending is paused, the API returns an error instead of a successful send.
List saved emails
Find messages saved for your domain. Choose sent or received emails and browse the results a page at a time.
GET /v1/messages
Required permission: email.read. Response definition: MessageList.
Query options: limit (1–100), direction (sent/received), and after (the previous page’s next_cursor). The response contains data, has_more and next_cursor. List results show message details but not the body.
Read one email
Use a message ID to open a saved email and read its details and plain-text content.
GET /v1/messages/{id}
Required permission: email.read. Response definition: Message.
Replace {id} with the message ID, up to 256 characters. The response contains saved message details and plain text. A missing ID or one outside the key’s domain returns 404.
Example: send an email
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.When something goes wrong
An error tells you why the request could not be completed. Keep its request ID if you need help investigating it. The SDK checks the response and does not automatically resend an email after a failure.
{
"error": {
"code": "SendingPaused",
"message": "Production sending is not activated. No message was sent.",
"request_id": "request-uuid"
}
} | HTTP status | What to check |
|---|---|
| 400 | Check the information you sent, the page cursor or your domain’s verification status. |
| 401 | The API key is missing, invalid or revoked. |
| 403 | The key does not have the required permission, or the sender is on a different domain. |
| 404 | The message was not found or is not available to this key. |
| 413 | The request is too large. |
| 429 | Too many requests. Wait before trying again. |
| 503 | Sending is paused. No message was sent. |
The API allows 120 requests per minute per client IP address. Responses include an x-request-id header and are not cached. Unsupported fields and provider options produce an error rather than being silently ignored.
Download the technical definitions
For development tools and exact field definitions: OpenAPI 3.1 and JSON Schema.