Appearance
Quickstart
Send your first email with SendGrail. This takes about five minutes, plus DNS propagation time while your domain verifies.
Before you start
You'll need:
- A SendGrail account — sign in to the dashboard, or create an account if you don't have one.
- A domain you control, with access to its DNS records.
Step 1 — Verify your sending domain
You can only send from a domain you've verified. In the dashboard:
- Go to Domains → Add domain.
- Enter the domain (apex like
example.com, or a subdomain likemail.example.com) and pick an AWS region. - SendGrail shows a set of DNS records — DKIM, MAIL FROM and SPF. Add them at your DNS provider.
- Click Verify.
Verification flips the domain to verified once DNS propagates — usually a few minutes, occasionally up to an hour. Full walkthrough: Domains & verification.
TIP
You don't have to wait idle — create your API key (Step 2) while DNS propagates.
Step 2 — Create an API key
- Go to API keys → Create API key.
- Give it a name (e.g.
Production), and leave the permission as Sending access. - Copy the key — it starts with
sg_and is shown only once.
Store it as a secret in your application, never in source control:
ini
SENDGRAIL_API_KEY=sg_i8CtWNyXYLp7ZXgvFIAucVe2XBz4pCSBjiZiVT87More on permissions and scoping: API keys.
Step 3 — Send an email
Once your domain shows verified, send a message. Set from to an address on your verified domain, and to to an inbox you can check.
bash
curl https://api.sendgrail.com/v1/emails \
-H "Authorization: Bearer $SENDGRAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <hello@example.com>",
"to": "you@your-inbox.com",
"subject": "Hello from SendGrail",
"html": "<p>It works! 🎉</p>"
}'js
const res = await fetch('https://api.sendgrail.com/v1/emails', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SENDGRAIL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'Acme <hello@example.com>',
to: 'you@your-inbox.com',
subject: 'Hello from SendGrail',
html: '<p>It works! 🎉</p>',
}),
});
const { id } = await res.json();
console.log('Queued:', id);python
import os, requests
res = requests.post(
"https://api.sendgrail.com/v1/emails",
headers={"Authorization": f"Bearer {os.environ['SENDGRAIL_API_KEY']}"},
json={
"from": "Acme <hello@example.com>",
"to": "you@your-inbox.com",
"subject": "Hello from SendGrail",
"html": "<p>It works! 🎉</p>",
},
)
print("Queued:", res.json()["id"])php
$response = $http->post('https://api.sendgrail.com/v1/emails', [
'headers' => [
'Authorization' => 'Bearer '.getenv('SENDGRAIL_API_KEY'),
],
'json' => [
'from' => 'Acme <hello@example.com>',
'to' => 'you@your-inbox.com',
'subject' => 'Hello from SendGrail',
'html' => '<p>It works! 🎉</p>',
],
]);
$id = json_decode((string) $response->getBody())->id;A successful call returns 202 Accepted — the message is queued:
json
{
"id": "3f5c9a1e-8b2d-4e6f-9a1c-7d4b2e8f0a63",
"from": "Acme <hello@example.com>",
"to": ["you@your-inbox.com"],
"status": "queued",
"scheduled_at": null,
"created_at": "2026-05-21T08:12:32.000000Z"
}Keep the id — it identifies this message in the dashboard and in every webhook event about it.
Step 4 — Confirm delivery
Open Emails in the dashboard. Your message appears with status Queued, then Sent, then Delivered once the recipient's mail server accepts it. Click the row to see headers, the rendered body and an event timeline.
If the message doesn't arrive, check Errors & rate limits — the API response usually says exactly what went wrong.
Next steps
- Send an email — every field, attachments, scheduled sends and batch sending.
- Webhooks — get delivered / bounced / complained events pushed to your app.
- Suppressions — the do-not-send list that protects your sender reputation.