How to Get a Resend API Key (and Scope It Right)
Create a Resend API key in 4 steps, scoped to sending-only on one domain. Then Ringtail mints the scoped key from Resend's official API — value-free.

Rocco found the Resend key on the third click, like always. He scoped it to sending-only on the way out.

🦝 Rocco: full-access token to send one welcome email? nah. sending-only, one domain, done.
To get a Resend API key, sign in at resend.com, open API Keys in the left sidebar, click Create API Key, name it, set the permission to Sending access, restrict it to a single domain, and copy the re_… value once — Resend shows it only at creation. That gives you a least-privilege key that can send mail and nothing else. Below is the full flow, the scope choices, and how Ringtail mints the same key from Resend's official API without ever showing the value to your coding agent.
Where do you create a Resend API key?
You create it in the Resend dashboard under API Keys, not in the domain or account settings. Sign in at resend.com, and the API Keys item sits in the left navigation. Every key you mint is listed there with its name, permission, and last-used date, so it doubles as your audit surface later.
Before you mint a sending key, add and verify your domain under Domains — a key scoped to an unverified domain can't actually send. Resend walks you through the DKIM and SPF records; add them at your DNS provider (if that's GoDaddy, see how to change nameservers and wire a domain on GoDaddy) and wait for the green verified badge.
What are the steps to create the key?
Four steps, start to finish:
- Sign in at resend.com and click API Keys in the sidebar.
- Click Create API Key and give it a descriptive name — tie it to the project and environment, like
acme-app-prod-send, so a leaked key is traceable. - Set Permission to Sending access (not Full access), and under Domain pick the single verified domain this key should send from.
- Click Add, then copy the
re_…value immediately — Resend displays it once and never again.
Paste it into .env.local as RESEND_API_KEY, never into a committed file. If you're new to keeping keys out of your repo, stop committing secrets to git covers the .gitignore and history-scrub basics.
How should you scope a Resend API key?
Scope it to Sending access on one domain — that's the least-privilege default for any app that only sends transactional or marketing mail. Resend offers two permission levels:
- Full access — read and write across your whole account: domains, keys, audiences, everything. Only a provisioning or admin tool needs this.
- Sending access — can send emails and read its own sending stats, nothing else. This is what your production app should carry.
Then narrow the Domain field from "All domains" to the specific verified domain. A production send key that can only send from mail.acme.com is a small blast radius if it leaks — the finder can't rotate your other keys or read your audiences. This is the same reasoning behind least-privilege API key provisioning: the key should do exactly its job and no more.

🦝 Rocco: one key, one domain, one verb. leaks smaller when the key can barely do anything.
How do you use the Resend key in code?
Read it from the environment — never inline the string. With the Resend Node SDK:
npm install resend
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);
await resend.emails.send({
from: "hello@mail.acme.com",
to: "you@example.com",
subject: "Welcome",
html: "<p>You're in.</p>",
});
The from address must be on the domain your key is scoped to, or Resend returns a 403 — which is the scope working as designed.
How does Ringtail get the Resend key for you?
Once you've connected your Resend account to Ringtail one time, Ringtail mints the scoped sending key for you by driving Resend's official API — you never open the dashboard again for a new project. Ringtail reads RESEND_API_KEY from your .env.example, calls the Resend API to create a sending-scoped key bound to your verified domain, validates that it can actually send, and writes the value straight into .env.local and your Infisical.
The key property is value-free: the re_… string is returned by Resend's API directly into your local files. Your coding agent orchestrates which key to mint and how to scope it, but never sees the secret value — the model handles variable names and scopes, not the credential itself. Install it once and point it at a repo:
curl -fsSL ringtail.sh | sh
ringtail up
Ringtail uses official provider APIs only — it never puppets a browser login. For Resend, which has a first-class key-minting API, that means fully zero-touch after the initial one-time connection. For the bigger picture of provisioning every key in a project this way, see how to stop juggling 15 API keys on every new project.
FAQ
Where do I find my Resend API key?
Your Resend API key is created and listed in the Resend dashboard under API Keys in the left sidebar. Resend only shows the full re_… value once, at the moment you create the key — after that the list shows the name, permission, and last-used date but never the secret again. If you lost the value, delete the old key and create a new one.
What permission should a Resend API key have?
For an app that only sends email, choose Sending access and restrict it to a single verified domain. Full access grants read-write over your entire account — domains, other keys, audiences — and should be reserved for admin or provisioning tools, not your running application. Least-privilege keeps the blast radius small if the key ever leaks.
Why is my Resend key returning a 403?
A 403 usually means the key's scope doesn't cover the action. If a sending-scoped key is bound to one domain, sending from a from address on a different domain returns 403 by design. Confirm the domain is verified in Resend and that the key's domain matches the address you're sending from.
Can Ringtail create a Resend key without me visiting the dashboard?
Yes. After you connect your Resend account to Ringtail once, Ringtail calls Resend's official API to mint a sending-scoped key for each new project, validates it, and writes it to .env.local and Infisical — value-free, so the secret never reaches your coding agent. It uses the official API only, never a browser bot, so the flow is safe to let an agent run.
