Relay API Design: Building Email Infrastructure on Cloudflare Workers

1. Why We Didn't Use a Major Provider's Email API

When building an app that sends memos via email, a major mail provider's sending API is the first thing that comes to mind. However, for indie developers, the Google OAuth verification process presents a formidable barrier.

Apps that haven't passed Google OAuth verification display a warning screen: "This app isn't verified by Google." For a memo app, this warning is devastating. Users send their personal thoughts and private information as memos. If "unverified" appears during their very first experience, who would trust this app?

The Google OAuth verification process is a steep climb for solo developers. Preparing a privacy policy, justifying scope requirements, undergoing security assessments -- for a team at a large company, this is routine. But for a solo-developed app, the cost of going through all this just for a single email-sending feature is disproportionately high.

What we needed was a solution that could send emails without compromising user trust and without the complexity of OAuth verification. The answer was building our own Relay API.

2. Cloudflare Workers + Resend API Architecture

The Relay API architecture is simple yet robust. It receives requests from the iOS app and relays them to an email delivery service -- a design focused on doing exactly one thing well.

iOS App → Relay API (Cloudflare Workers) → Resend API → Email Delivery

Cloudflare Workers is a serverless platform that executes TypeScript code at edge locations around the world. According to Cloudflare, Workers runs code in lightweight isolates, which removes the cold starts of virtual-machine-based serverless platforms.

Resend API is a modern email delivery service. It makes SPF/DKIM/DMARC configuration straightforward, and its API is simple to call from TypeScript.

On cost, the Cloudflare Workers Free plan allows 100,000 requests a day, and the Resend Free plan allows 100 emails a day and 3,000 a month (each provider's pricing page, October 2026). You can start small and move to a paid plan as sending grows.

3. Email Address Verification (6-Digit Code)

The Relay API only sends memos to verified email addresses. This is the most fundamental layer of abuse prevention.

Before any memos can be sent, the destination email address must go through a verification flow:

  • User enters their email address in the app
  • Relay API sends a 6-digit verification code to that address
  • User enters the received 6-digit code back into the app
  • Verification complete. Memo sending to that email address is now permitted

This mechanism prevents unauthorized sending to other people's email addresses. The code goes to that address's inbox, so someone who cannot read the inbox cannot verify the address as a destination.

Verification is a one-time process per email address. Once verified, users can continue sending memos without re-entering any code.

4. Multi-Layer Rate Limiting

To prevent abuse of the email sending API, we implement rate limiting across multiple layers.

const RATE_LIMITS = {
  devicePerMinute: 30,
  devicePerDay: 200,
  ipPerHour: 120,
  globalPerDay: 300,
};
Device Level
Per-Device Limiting
Prevents excessive sending from a single device. Limits set at 30 per minute and 200 per day. These thresholds are unreachable during normal memo usage but stop automated mass sending.
IP Level
Per-IP Address Limiting
Limits mass requests from the same network. 120 per hour. Protects infrastructure even against attacks using multiple devices on the same network.
Global
Global Limit
Protects the entire infrastructure. A global cap of 300 per day is the last backstop (all limit values are the design-time ones and may change).
Update, 2026-09
Current limits
The per-device limits and the global daily cap were removed in June 2026. The sending limit in place now is the per-IP hourly cap.

Counters are stored in Cloudflare KV and reset per time window. This lets normal sending through while limiting abusive traffic.

5. Idempotency: Avoiding Duplicate Memos

Network communication is inherently unreliable. Between tapping send and receiving a response, the connection can drop. The app detects a timeout and retries the send, but the first request had actually reached the server -- a common scenario.

Idempotency handles this case:

  • Each memo is assigned a unique UUID (message ID)
  • The Relay API passes that message ID to the email service (Resend) as the request's Idempotency-Key
  • Resend remembers the key for 24 hours; if the same request arrives again, it returns the earlier response without sending the email again
  • The app gets a success response (the same response as the first time)

With this design, retries caused by an unstable network do not send the same memo twice within those 24 hours (the period Resend keeps the key). A resend after that cannot be recognized as a duplicate, so duplicates are prevented only within that window.

6. The Edge Computing Advantage

The primary reason for choosing Cloudflare Workers as our email infrastructure is the fundamental advantages of edge computing.

Latency
Global Edge Locations = Low Latency
Cloudflare has locations in over 300 cities worldwide. Requests are handled at a location near the user, which shortens the network path compared with a single distant server (the total response time still depends on the email service).
Cold Start
No Virtual-Machine Cold Starts
Serverless platforms that run on virtual machines or containers can make the first request after an idle period wait for start-up (a cold start). Cloudflare says Workers avoids this wait because it runs in isolates.
Operations
Auto-Scaling with No Infrastructure Management
Server management, capacity planning, scaling configuration -- none of these are needed. The system scales automatically as requests increase, and incurs no cost when idle.

For a memo app, this combination was a practical choice: requests start near the user, there are no servers to manage, and costs stay low at a small scale. That is why we built the Relay API on edge computing.

Try Simple Memo - for Obsidian, built on this technical foundation.

Download on the App Store

References