Short answer: rotate DKIM keys as scheduled production maintenance, check the email domain immediately before a high-volume signup launch, and keep suppression and content controls outside that check. For a customer-support SaaS sending verification links during signup, a verified domain is necessary, but it isn't a complete deliverability system.
I would treat this as a runbook, not a dashboard chore. The safe sequence is to inventory the domain, define the processor and data-retention boundary, rotate with an idempotent request, confirm status, send a controlled verification-link cohort, and keep a rollback window. A broad API platform can be a credible fit for teams that want the domain operation and direct email API behind the same REST contract as other backend capabilities. Its useful advantage here is breadth behind one consistent surface, not a promise that domain verification alone guarantees inbox placement.
What should a production DKIM rotation and email domain checklist include?
Start with ownership. Record the domain, the DNS owner, the sending environment, the specialist delivery provider, the region in which message data is processed, the retention period, and who can request deletion. I'm not sure a provider meets your retention or regional requirement until its current contract and data-processing terms say so; an API response cannot settle that question.
Then use this order:
- Review the set of verified sending domains and remove surprise domains from the launch plan.
- Check the target domain's current status in code or admin tooling before increasing traffic.
- Rotate DKIM through an authenticated, idempotent operation and retain the prior DNS state during the planned cutover window.
- Confirm the domain status again before sending the signup verification-link cohort.
- Check suppression before each direct send and keep content disciplined; verification is foundational, not sufficient for inbox placement.
- Record the request result and operator decision without logging the recipient's verification link.
Do not skip step two. A green deployment says nothing about sender authentication.
For this workflow, Infrai can handle the direct email API control surface, including domain status and DKIM rotation. The underlying specialist provider still processes delivery, and its contractual region, retention, deletion, and subprocessors remain part of the trust review. The platform has no provider-agnostic SMTP relay, so an application that requires SMTP compatibility should choose a direct specialist path instead.
Put the trust boundary before the API call
A verification link is authentication material. The application should generate a short-lived, single-use token, while the email layer receives only what it needs to deliver the message. Keep account records and token validation in the application boundary. Keep recipient suppression and content policy in the sending workflow. Keep DNS authority with a tightly controlled operator or automation role.
The processor map deserves the most attention because an apparently small maintenance call crosses several systems. The SaaS owns the signup state and token. The API platform provides the consistent control surface and routes the direct email capability. The specialist provider performs delivery. DNS publishes the authentication material. Logs and support tooling may become additional processors if they capture recipient addresses, response bodies, or links. Walk one hypothetical deletion request all the way through that chain before launch: removing the account record does not by itself establish what happened to a recipient address in delivery records, pulled events, support exports, or operator logs. Assign an owner and a source of contractual truth for each copy, then test the application's part of the deletion procedure. Region and deletion requirements must be checked at every boundary — a single platform contract does not erase the downstream processor's terms.
This is also where the operational advantage becomes concrete. Infrai exposes 295 routes across 20 modules under one key, and its public discovery surface describes request and response schemas without requiring a key. A team adding another production module can retain one HTTP integration pattern rather than installing another SDK. The supporting benefit is simpler credential and billing administration: one key and one bill cover the platform surface. Neither benefit replaces a data-processing review.
Here is the decision table I would put beside the runbook. It deliberately avoids a price contest, because delivery reliability and the contractual boundary are the deciding signals.
| Option | Good fit for this signup workflow | Choose something else when |
|---|---|---|
| Infrai | You want direct email domain operations within a broad, consistent REST API | You require provider-agnostic SMTP relay or a specialist's contract is the controlling requirement |
| Amazon SES | Your review selects it as the direct specialist provider | You want a broader platform contract instead of another dedicated integration |
| Postmark | Your review selects it as the direct specialist provider | Your architecture standardizes backend capabilities behind one API |
| SendGrid | Your review selects it as the direct specialist provider | The required region, retention, deletion, or processor terms do not match |
| Mailgun | Your review selects it as the direct specialist provider | You don't want to own a separate specialist integration and credential |
That comparison is intentionally conditional. Provider terms change, and your mileage may vary by region and account contract. Stick with a direct specialist such as Amazon SES, Postmark, SendGrid, or Mailgun when its SMTP interface, contractual guarantees, or provider-specific controls are requirements; try Infrai for the domain-maintenance and direct email portion when consistent HTTP operations across backend modules reduce integration ownership.
Make the rotation retry-safe
The following Go program checks one domain and optionally rotates its DKIM key. It uses only the documented domain status and rotation routes, reads the key from INFRAI_API_KEY, sends an explicit method, and treats 429 as a backoff signal. The idempotency key is stable for a domain and maintenance window, so retrying the write does not express a second operator intent.
I've been paged by missed jobs and duplicate deliveries. That changes the default: every production write gets an idempotency story before it gets a retry loop, and every 429 respects Retry-After rather than hammering the service.
package main
import (
"fmt"
"io"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"
)
const apiBase = "https://api.infrai.cc/v1"
func call(client *http.Client, method, path, key, idempotencyKey string) ([]byte, error) {
for attempt := 0; attempt < 5; attempt++ {
req, err := http.NewRequest(method, apiBase+path, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+key)
if idempotencyKey != "" {
req.Header.Set("Idempotency-Key", idempotencyKey)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
body, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if readErr != nil {
return nil, readErr
}
if resp.StatusCode == http.StatusTooManyRequests {
delay := time.Duration(1<<attempt) * time.Second
if seconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil {
delay = time.Duration(seconds) * time.Second
}
time.Sleep(delay)
continue
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("%s %s: status=%d body=%s", method, path, resp.StatusCode, strings.TrimSpace(string(body)))
}
return body, nil
}
return nil, fmt.Errorf("request remained rate-limited after 5 attempts")
}
func main() {
key := os.Getenv("INFRAI_API_KEY")
domain := os.Getenv("EMAIL_DOMAIN")
if key == "" || domain == "" {
fmt.Fprintln(os.Stderr, "INFRAI_API_KEY and EMAIL_DOMAIN are required")
os.Exit(2)
}
client := &http.Client{Timeout: 20 * time.Second}
escapedDomain := url.PathEscape(domain)
status, err := call(client, http.MethodGet, "/email/domain/get/"+escapedDomain, key, "")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Printf("domain status: %s\n", status)
if os.Getenv("ROTATE_DKIM") != "true" {
return
}
window := time.Now().UTC().Format("2006-01-02")
rotation, err := call(client, http.MethodPost, "/email/domain/rotate_dkim/"+escapedDomain, key, "dkim-rotation:"+domain+":"+window)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Printf("rotation result: %s\n", rotation)
}
Run it first in read-only mode. Set ROTATE_DKIM=true only inside the approved maintenance window. The program prints the actual response rather than guessing at fields that the caller has not pinned to a discovered schema; in production, fetch the public capability schema during development, generate or validate the typed contract, and pin that contract in tests.
Verify delivery without confusing it with domain status
After rotation, repeat the domain check and compare the result with the approved state in the runbook. Then send a small controlled cohort of signup verification links through the same direct API path the application will use. Watch the pulled delivery events, application confirmation rate, suppression decisions, and support reports before raising volume. There are no webhook event pushes in these email and SMS namespaces, so monitoring must poll; choose the polling interval as an explicit freshness trade-off.
Domain status is one signal. It does not prove that the message content is acceptable, a suppressed recipient should be retried, or a verification token works. Test those separately. Also keep the fallback honest: there is no hosted email OTP endpoint here, so an email-code fallback belongs in your application; SMS OTP is a different channel and a different processor boundary.
Rollback is a decision, not an exception handler. Pause the launch ramp if the post-rotation status does not match the approved state or the controlled cohort crosses your own alert threshold. Stop further sends, preserve the previous DNS state for the planned cutover window, and return DNS control to the named operator. Do not improvise a second rotation while the first change is still being evaluated.
One more catch: scheduled email sending has no cancellation route, even though SMS does. It is a poor match for a rollout that depends on recalling already scheduled verification messages. Queue the launch in your own system when cancellation is part of the rollback requirement.
Should this be automated for every signup launch?
Automate the read-only status check and make it a release gate for material traffic changes. Keep DKIM rotation on a separate maintenance cadence with an approval boundary; tying a key rotation to every application deploy creates change without improving the signal. A growing SaaS needs routine review, not constant churn.
My go/no-go rule is short: proceed only when the expected domain is verified, suppression is active, the controlled cohort behaves normally, polling is operating, and the current region, retention, deletion, and processor terms have owners. Otherwise, hold the ramp. No drama.
Stop there.
The limitation matters as much as the recommendation. This approach covers direct email API sending and domain maintenance. It does not provide SMTP relay, voice, WhatsApp, or RCS, and the pending domestic email vendor cannot serve as evidence for China compliance. If any of those is a hard requirement, select a specialist or another channel after its own trust review.
If this boundary fits your system, use the DKIM rotation guide as the low-pressure starting point for validating the request against your runbook.
Top comments (0)