Send Your First Email with SendGrid REST API — Step-by-Step Guide
In this tutorial, you will learn about Send Your First Email with SendGrid REST API. We cover key concepts, practical examples, and best practices to help you master this topic.
Send your first email through SendGrid's REST API using the Python SDK — learn the Mail object structure, API authentication, response handling, and delivery confirmation.
What You'll Learn
How to send a basic email with SendGrid, structure the Mail object, handle API responses, check delivery status, and troubleshoot common send failures.
Why It Matters
Sending email programmatically is the foundation of transactional messaging. DodaTech's first integration sent a simple welcome email; from there, we built the entire notification system serving 500K+ users.
Real-World Use
A user creates an account on the DodaTech platform. The sign-up flow calls SendGrid to send a welcome email. The API responds with 202 Accepted, confirming the email is queued for delivery.
flowchart LR
A["Python App\nsend()"] --> B["SendGrid REST API\nPOST /v3/mail/send"]
B --> C{"Validate\nRequest"}
C -->|Invalid| D["400 Bad Request\n+ Error Body"]
C -->|Valid| E["202 Accepted\nEmail Queued"]
E --> F["Delivery to\nRecipient"]
style A fill:#dbeafe,stroke:#2563eb
style E fill:#bbf7d0,stroke:#16a34a
style D fill:#fecaca,stroke:#dc2626
Install and Setup
pip install sendgrid
import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")
sg = SendGridAPIClient(SENDGRID_API_KEY)
Send a Basic Email
def send_welcome_email(to_email, user_name):
message = Mail(
from_email="welcome@dodatech.com",
to_emails=to_email,
subject="Welcome to DodaTech Security",
plain_text_content=f"Hello {user_name},\n\nThank you for choosing DodaTech. Your account is ready.\n\nBest,\nThe DodaTech Team"
)
try:
response = sg.send(message)
print(f"Status: {response.status_code}")
print(f"Headers: {dict(response.headers)}")
if response.status_code == 202:
print("Email queued successfully")
return response
except Exception as e:
print(f"Send failed: {e}")
if hasattr(e, "body"):
print(f"Error body: {e.body}")
return None
send_welcome_email("alice@example.com", "Alice")
# Expected output: Status: 202
# Email queued successfully
Sending HTML Email
def send_html_email(to_email, user_name, report_url):
html_content = f"""
<h1>Welcome to DodaTech!</h1>
<p>Hello {user_name},</p>
<p>Your security dashboard is ready. <a href="{report_url}">View your first report</a></p>
<p>Best,<br>The DodaTech Team</p>
"""
message = Mail(
from_email="welcome@dodatech.com",
to_emails=to_email,
subject="Welcome to DodaTech Security",
html_content=html_content
)
response = sg.send(message)
print(f"HTML email sent: {response.status_code}")
send_html_email("bob@example.com", "Bob", "https://dodatech.com/dashboard")
# Expected output: HTML email sent: 202
Multiple Recipients
def send_to_multiple(recipients):
message = Mail()
message.from_email = "noreply@dodatech.com"
message.subject = "Weekly Security Report Available"
for email in recipients:
message.add_to(email)
message.template_id = "d-abc123def456"
response = sg.send(message)
print(f"Batch sent to {len(recipients)} recipients: {response.status_code}")
send_to_multiple(["alice@example.com", "bob@example.com", "carol@example.com"])
# Expected output: Batch sent to 3 recipients: 202
Common Mistakes
1. Using Invalid From Email
The from email must be verified in SendGrid. Sending from unverified addresses returns a 401 error with "from address not verified."
2. Ignoring 4xx and 5xx Responses
A 202 response means queued, not delivered. 4xx errors indicate client issues (invalid email, bad request). 5xx errors are server issues — retry with backoff.
3. Not Handling Exceptions
Network issues cause exceptions. Always wrap send() in try/except and implement retry logic for transient failures.
4. Exceeding Rate Limits
SendGrid has per-second rate limits (varies by plan). HTTP 429 means too many requests. Implement exponential backoff when you get 429 responses.
5. Sending Without Content
SendGrid requires at least one content type (plain text or HTML). Emails without content are rejected with a 400 error.
Practice Questions
- What does status code 202 mean from SendGrid?
- How do you send both plain text and HTML in one email?
- What information is in the response headers?
- How do you handle Rate Limiting (429)?
Answers:
- 202 Accepted means SendGrid has received and queued your email for delivery. It does not mean the email was delivered successfully.
- Set both
plain_text_contentandhtml_contenton the Mail object. SendGrid sends the appropriate version based on the recipient's email client. - Response headers include
X-Message-Id(SendGrid's unique message ID), date, and server headers. - Check
response.status_code == 429, implement exponential backoff (wait 1s, 2s, 4s, 8s between retries), and queue emails to stay within limits.
Challenge: Write a function that sends a welcome email with HTML content, handles 202 success and 4xx/5xx errors, logs the message ID, and retries up to 3 times with exponential backoff on failure.
FAQ
Mini Project
Build a welcome email system: send a personalized HTML welcome email with your company branding, handle the API response, log the message ID, and set up a retry mechanism for transient failures.
What's Next
Email Personalization — personalize emails with dynamic subscriber data.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro