Quickstart
Send your first transactional email
Use the public REST API from your server. You need an API key, a verified sending domain, and an idempotent POST /v1/emails request.
Before you start
- Create an API key in your Constant Contact for Agents account.
- Verify the domain used in the
fromaddress. - Store the API key in a server-side secret manager or environment variable.
Send a message
Send-creating requests require Idempotency-Key. Reuse the same key only when retrying the same logical request after a timeout or lost response.
curl -X POST "https://api.ctct.dev/v1/emails" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: quickstart-001" \
-d '{
"from": "noreply@constantcontact.com",
"to": ["ada@example.com"],
"subject": "Your receipt is ready",
"html": "<p>Your receipt AB-1042 is ready.</p>",
"message_class": "transactional"
}'const response = await fetch("https://api.ctct.dev/v1/emails", {
method: "POST",
headers: {
Authorization: "Bearer <API_KEY>",
"Content-Type": "application/json",
"Idempotency-Key": "quickstart-001"
},
body: JSON.stringify({
from: "noreply@constantcontact.com",
to: ["ada@example.com"],
subject: "Your receipt is ready",
html: "<p>Your receipt AB-1042 is ready.</p>",
message_class: "transactional"
})
});
console.log(response.status, await response.json());import requests
response = requests.post(
"https://api.ctct.dev/v1/emails",
headers={
"Authorization": "Bearer <API_KEY>",
"Content-Type": "application/json",
"Idempotency-Key": "quickstart-001",
},
json={
"from": "noreply@constantcontact.com",
"to": ["ada@example.com"],
"subject": "Your receipt is ready",
"html": "<p>Your receipt AB-1042 is ready.</p>",
"message_class": "transactional",
},
)
print(response.status_code, response.json())Expected response
The send is asynchronous. A 202 Accepted response means the request was accepted for processing and includes a send_id you can follow later.
{
"email_id": "msg_...",
"message_id": "msg_...",
"send_id": "send_...",
"status": "accepted",
"subject": "Your receipt is ready",
"from": "noreply@constantcontact.com",
"recipients": {
"to": ["ada@example.com"]
},
"message_class": "transactional",
"created_at": "2026-05-18T12:00:00Z"
}
Request fields
| Name | Type | Description | |
|---|---|---|---|
| from | string | Required | Verified sender address, usually on a domain you have added and verified. |
| to | string[] | Required | Recipient email addresses. First-copy examples use an array. |
| subject | string | Required | Email subject, 300 characters or fewer. |
| html | string | Optional | HTML body. Either html or text is required. |
| text | string | Optional | Plain-text body. Required only when html is omitted. |
| message_class | string | Optional | Defaults to transactional. The current public send path rejects non-transactional classes. |
Common errors
401
authentication_required — Missing
Authorization: Bearer <API_KEY>.
400
missing_idempotency_key — Send-creating requests require
Idempotency-Key.
400
invalid_request — A required field is missing or invalid.
429
rate_limited — Back off using
Retry-After and the X-RateLimit-* headers.
Next: verify a sending domain before production sends, then use send status or webhooks to track outcomes.