| title | Quickstart |
|---|---|
| sidebarTitle | Quickstart |
| description | Send your first email in under 5 minutes with AhaSend |
| icon | rocket |
Get up and running with AhaSend in under 5 minutes. This guide will walk you through sending your first email using either our REST API or SMTP relay.
**Before you start:** You'll need an AhaSend account. [Sign up for free](https://dash.ahasend.com/user/register) to get 1,000 emails per month at no cost. 1. **[Sign up for a free account](https://dash.ahasend.com/user/register)** 2. **Verify your email address** by clicking the link in your inbox 3. **Log in to your dashboard** to continue setup Before you can send emails, you need to add and verify your domain:1. **Add your domain** in your dashboard under [Domains](https://dash.ahasend.com/account/-/settings/domains)
2. **Add the DNS records** provided by AhaSend to your domain's DNS settings
3. **Wait for verification** (usually takes a few minutes)
<Info>
**Need help with domain setup?** Check out our detailed [domain configuration guide](/domains) for step-by-step instructions for all major DNS providers.
</Info>
<Warning>
**Important:** You cannot send emails until your domain is verified. The verification process ensures good deliverability and prevents spoofing.
</Warning>
<CardGroup cols={2}>
<Card title="HTTP API" icon="code" href="#http-api">
**Recommended for most applications**
- Faster and more reliable
- Better error handling
- Rich metadata support
</Card>
<Card title="SMTP Relay" icon="envelope" href="#smtp-relay">
**Use with existing email libraries**
- Works with any SMTP-compatible library
- Easy migration from other providers
- Supports all programming languages
</Card>
</CardGroup>
**For HTTP API:**
- Go to **API Keys** in your dashboard
- Click "Create API Key"
- Copy and securely store your API key
**For SMTP:**
- Go to **SMTP Credentials** in your dashboard
- Click "Create SMTP Credential"
- Save the username and password
<Warning>
Keep your credentials secure! Never commit them to version control or expose them in client-side code.
</Warning>
**After sending:**
1. **Check your inbox** - Your test email should arrive within seconds
2. **Check the Messages page** in your dashboard to see delivery status
3. **Look for a 202 response** with a message ID
<Check>
**Success!** See your email in both your inbox and the Messages page? You're all set up! 🎉
</Check>
Jump to: [HTTP API](#http-api) | [SMTP Relay](#smtp-relay)
Send emails using our modern HTTP API. Perfect for web applications and microservices.
**API Version Note:** These examples use our latest API v2, which provides the most powerful features including advanced tracking, bulk sending, and better error handling. For simpler use cases, you can also use our [API v1](/api-reference/v1).curl -X POST https://api.ahasend.com/v2/accounts/{account_id}/messages \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"from": {
"name": "My App",
"email": "[email protected]"
},
"recipients": [
{
"name": "John Doe",
"email": "[email protected]"
}
],
"subject": "Welcome to My App!",
"text_content": "Thanks for signing up. We'\''re excited to have you!",
"html_content": "<h1>Welcome!</h1><p>Thanks for signing up. We'\''re <strong>excited</strong> to have you!</p>"
}'const axios = require('axios');
const sendEmail = async () => {
try {
const email = {
from: {
name: 'My App',
email: '[email protected]'
},
recipients: [
{
name: 'John Doe',
email: '[email protected]'
}
],
subject: 'Welcome to My App!',
text_content: 'Thanks for signing up. We\'re excited to have you!',
html_content: '<h1>Welcome!</h1><p>Thanks for signing up. We\'re <strong>excited</strong> to have you!</p>'
};
const response = await axios.post('https://api.ahasend.com/v2/accounts/{account_id}/messages', email, {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
}
});
console.log('Email sent:', response.data);
} catch (error) {
console.error('Error:', error.response.data);
}
};
sendEmail();import requests
def send_email():
url = 'https://api.ahasend.com/v2/accounts/{account_id}/messages'
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
}
email = {
'from': {
'name': 'My App',
'email': '[email protected]'
},
'recipients': [
{
'name': 'John Doe',
'email': '[email protected]'
}
],
'subject': 'Welcome to My App!',
'text_content': 'Thanks for signing up. We\'re excited to have you!',
'html_content': '<h1>Welcome!</h1><p>Thanks for signing up. We\'re <strong>excited</strong> to have you!</p>'
}
response = requests.post(url, json=email, headers=headers)
if response.status_code == 202:
print('Email sent:', response.json())
else:
print('Error:', response.json())
send_email()<?php
$email = [
'from' => [
'name' => 'My App',
'email' => '[email protected]'
],
'recipients' => [
[
'name' => 'John Doe',
'email' => '[email protected]'
]
],
'subject' => 'Welcome to My App!',
'text_content' => 'Thanks for signing up. We\'re excited to have you!',
'html_content' => '<h1>Welcome!</h1><p>Thanks for signing up. We\'re <strong>excited</strong> to have you!</p>'
];
$options = [
'http' => [
'header' => "Content-type: application/json\r\nAuthorization: Bearer YOUR_API_KEY",
'method' => 'POST',
'content' => json_encode($email)
]
];
$context = stream_context_create($options);
$response = file_get_contents('https://api.ahasend.com/v2/accounts/{account_id}/messages', false, $context);
var_export($response, true);
?>package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type Email struct {
From Contact `json:"from"`
Recipients []Contact `json:"recipients"`
Subject string `json:"subject"`
TextContent string `json:"text_content"`
HTMLContent string `json:"html_content"`
}
type Contact struct {
Name string `json:"name"`
Email string `json:"email"`
}
func main() {
email := Email{
From: Contact{
Name: "My App",
Email: "[email protected]",
},
Recipients: []Contact{
{
Name: "John Doe",
Email: "[email protected]",
},
},
Subject: "Welcome to My App!",
TextContent: "Thanks for signing up. We're excited to have you!",
HTMLContent: "<h1>Welcome!</h1><p>Thanks for signing up. We're <strong>excited</strong> to have you!</p>",
}
jsonData, _ := json.Marshal(email)
req, _ := http.NewRequest("POST", "https://api.ahasend.com/v2/accounts/{account_id}/messages", bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}Use our SMTP servers with any email library. Great for existing applications or when you need SMTP compatibility.
Host: send.ahasend.com
Ports: 25, 587, 2525 (all support STARTTLS)
Authentication: Required
Username: Your SMTP username (from dashboard)
Password: Your SMTP password (from dashboard)
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransporter({
host: 'send.ahasend.com',
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: 'YOUR_SMTP_USERNAME',
pass: 'YOUR_SMTP_PASSWORD'
}
});
const mailOptions = {
from: '"My App" <[email protected]>',
to: '[email protected]',
subject: 'Welcome to My App!',
text: 'Thanks for signing up. We\'re excited to have you!',
html: '<h1>Welcome!</h1><p>Thanks for signing up. We\'re <strong>excited</strong> to have you!</p>'
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.error('Error:', error);
} else {
console.log('Email sent:', info.response);
}
});import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# Create message
msg = MIMEMultipart('alternative')
msg['Subject'] = 'Welcome to My App!'
msg['From'] = 'My App <[email protected]>'
msg['To'] = '[email protected]'
# Create text and HTML parts
text = "Thanks for signing up. We're excited to have you!"
html = "<h1>Welcome!</h1><p>Thanks for signing up. We're <strong>excited</strong> to have you!</p>"
msg.attach(MIMEText(text, 'plain'))
msg.attach(MIMEText(html, 'html'))
# Send email
try:
server = smtplib.SMTP('send.ahasend.com', 587)
server.starttls()
server.login('YOUR_SMTP_USERNAME', 'YOUR_SMTP_PASSWORD')
server.send_message(msg)
server.quit()
print('Email sent successfully!')
except Exception as e:
print(f'Error: {e}')<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try {
// Server settings
$mail->isSMTP();
$mail->Host = 'send.ahasend.com';
$mail->SMTPAuth = true;
$mail->Username = 'YOUR_SMTP_USERNAME';
$mail->Password = 'YOUR_SMTP_PASSWORD';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
// Recipients
$mail->setFrom('[email protected]', 'My App');
$mail->addAddress('[email protected]', 'John Doe');
// Content
$mail->isHTML(true);
$mail->Subject = 'Welcome to My App!';
$mail->Body = '<h1>Welcome!</h1><p>Thanks for signing up. We\'re <strong>excited</strong> to have you!</p>';
$mail->AltBody = 'Thanks for signing up. We\'re excited to have you!';
$mail->send();
echo 'Email sent successfully!';
} catch (Exception $e) {
echo "Error: {$mail->ErrorInfo}";
}
?>package main
import (
"gopkg.in/gomail.v2"
"log"
)
func main() {
m := gomail.NewMessage()
m.SetHeader("From", "[email protected]")
m.SetHeader("To", "[email protected]")
m.SetHeader("Subject", "Welcome to My App!")
m.SetBody("text/plain", "Thanks for signing up. We're excited to have you!")
m.AddAlternative("text/html", "<h1>Welcome!</h1><p>Thanks for signing up. We're <strong>excited</strong> to have you!</p>")
d := gomail.NewDialer("send.ahasend.com", 587, "YOUR_SMTP_USERNAME", "YOUR_SMTP_PASSWORD")
if err := d.DialAndSend(m); err != nil {
log.Fatal(err)
}
log.Println("Email sent successfully!")
}Now that you've sent your first email, here's what to do next:
**Add and verify domains** for better deliverability and custom from addresses **Use SMTP credentials** to send emails through your existing email libraries **Advanced API features** like templates, attachments, and bulk sending **Test safely** with sandbox mode to avoid sending emails to real recipientsHaving issues? Here are the most common problems:
- Check that your API key is correct and properly formatted - Make sure you're using the `Authorization: Bearer` header format - Verify your API key has the correct scopes in your dashboard - DNS changes can take up to 24 hours to propagate - Double-check that you added all required DNS records exactly as shown - Use a DNS checker tool to verify your records are live - Contact support if verification fails after 24 hours - Double-check your SMTP username and password - Make sure you created SMTP credentials in your dashboard (not your login password) - Try port 2525 if 587 is blocked by your network - Check your dashboard message logs for delivery status - Verify the recipient email address is correct - Check the recipient's spam folder - Make sure you're not hitting rate limits (1,000 emails/month on free plan) **Need more help?** Email our engineering team at [[email protected]](mailto:[email protected]) - we typically respond within a few hours!