API deprecation email templates, from announcement to retirement
Retiring an API version takes five emails: an announcement when you deprecate it, reminders 30, 7 and 1 day before the retirement date, and a note the day after. Send each only to the clients still calling the old version, with the date, their own calls and what to change in the first three lines.
A deprecation date nobody is reminded about is a date nobody remembers. These five emails take a client from the announcement to the day after retirement. Copy them, replace the bracketed parts, and send each one only to the clients still calling the old version.
Every email follows the same rule: say what is changing, by when, and exactly what the reader has to do, in the first three lines. The engineer who reads it may not have built the integration.
When should each deprecation email go out?
Send the announcement the day you deprecate the version, then reminders 30, 7 and 1 day before the retirement date, and a last note the day after. Five emails, each only to the clients still calling:
| When | Who gets it | |
|---|---|---|
| The announcement | The day of deprecation, at least your notice period ahead | Every client that called the old version in the last 90 days |
| Thirty days out | 30 days before the date | Clients still calling it |
| Seven days out | 7 days before | Clients still calling it, plus a direct message to the owner |
| One day out | The day before | Clients still calling it |
| The day after | The day after retirement | Clients that called in the last week before it |
1. The announcement
Send when you deprecate the version, at least as far ahead as your policy promises.
Subject: [API name] v1 will be retired on [date]
Hi [name],
[API name] v1 will stop working on [date]. Your integration, [client name],
called it [N] times in the last 30 days.
What to do: move these calls to v2 before [date].
- [GET /v1/invoices] → [GET /v2/invoices]
- [POST /v1/charges] → [POST /v2/payments]
The migration guide covers each change: [migration guide URL]
Why: [one sentence, e.g. "v2 supports multi-currency invoices, and we can't
add that to v1 without breaking it."]
If you need more time, reply to this email before [date].
[Your name]
[Team]
2. Thirty days out
Subject: 30 days until [API name] v1 is retired
Hi [name],
[API name] v1 will be retired on [date], 30 days from today. [Client name]
is still calling it: [N] calls in the last 7 days, most recently [time].
These are the calls still on v1:
- [GET /v1/invoices] ([N] calls) → [GET /v2/invoices]
Migration guide: [URL]
Reply if anything is blocking you. We'd rather hear it now than on [date].
3. Seven days out
Subject: Action needed: [API name] v1 stops working on [date]
Hi [name],
In 7 days, on [date], requests from [client name] to [API name] v1 will start
failing with 410 Gone. You made [N] v1 calls yesterday.
To keep working, move [GET /v1/invoices] to [GET /v2/invoices]: [URL]
If you can't migrate by [date], reply today and we'll talk about options.
4. One day out
Subject: Tomorrow: [API name] v1 is retired
Hi [name],
[API name] v1 will be retired tomorrow, [date], at [time and time zone].
[Client name] called it [N] times in the last 24 hours, so this will affect you.
Migration guide: [URL]
Contact: [name, email, phone]
5. The day after
Send only if the client kept calling after the date.
Subject: [API name] v1 has been retired
Hi [name],
[API name] v1 was retired on [date]. Since then, [client name] has made [N]
requests to it, and each one has returned 410 Gone.
To restore service, move to v2: [URL]
We're here to help: [contact].
How do you get deprecation emails read?
Send them to the engineer who owns the integration, with that client's own numbers in the first lines. The rest is detail:
- Send to the owner, not the account. Billing contacts forward these late, or not at all. Keep a technical contact for every credential you issue.
- Include their own numbers. "You called this 4,200 times yesterday" gets action. "Some customers still use v1" doesn't.
- Stop sending once they've moved. A reminder to a client that already migrated teaches them to ignore the next one.
- Back it up in the response. Emails get lost. The Deprecation and Sunset headers reach whoever is running the code.
What subject line works?
One that names the API, the version and the date, so the reader can act on the subject alone. Compare:
- Works: "Acme API v1 will be retired on June 30, 2027", "7 days until Acme API v1 is retired".
- Gets skipped: "Important update about your account", "Changes to our platform", "Action may be required".
Send from a person's name on your team, not a no-reply address, and let replies reach someone who can answer a technical question. A reply that bounces tells the reader the date isn't serious either.
How do you list each client's own calls?
Group the old version's usage by client and route, then paste each client's rows into their email. The announcement above has two bracketed lines for this, and it is the part that gets read. A generic list of every changed endpoint makes the reader do the matching; their own three routes, each with its replacement, makes the job look as small as it often is.
-
List routes, not raw paths.
GET /v1/invoices/:idis one line; a thousand invoice IDs are not. - Order by how much they call it. The route a client calls ten thousand times a day is the one they will test first.
- Mark the routes with no replacement. Say what to do instead, and offer a call. These are the ones that miss the date.
- Refresh the list for every reminder. A reminder that still lists a route the client moved off last week reads as an automated message nobody checked.
Should you use channels besides email?
Yes, for the reminders close to the date. Email is the record, but by the seven-day mark the clients still calling are the ones whose inbox didn't work. Post the same message, with the same date and link, wherever that team already talks to you:
- A shared Slack or Teams channel with the customer, if you have one.
- A banner in your developer portal or dashboard, shown to the affected accounts only.
- A status page notice on the day itself, so anyone debugging a sudden failure finds the cause in one click.
- The response headers on every call, which reach the code even when no person reads anything.
Keep the wording identical across channels. Two dates in two places is worse than one message in one place.
What if a client never replies?
Check their usage, not their inbox. If their calls to the old version are falling, they are migrating and don't need to write back. If the calls are flat a week out, stop emailing and reach the owner another way: a call, your shared Slack channel, or their account manager. On the day, you can retire knowing exactly who breaks, or give that one client a short, written extension.
To fill in the "[N] calls" lines, you need usage by client. See how to find which clients still call an old API version.
Sources
-
RFC 8594, the
Sunsetheader that carries the same date as your emails. -
RFC 9745 on the IETF Datatracker, the
Deprecationheader. - MDN: 410 Gone, what callers get the day after.
Where EndPointBlank fits
EndPointBlank sends the reminders for you. Set a retirement date on a deprecated version and consumers are reminded 30, 7 and 1 day out, by email, Slack or Teams. The same record shows which clients are still calling it, so you know whose number to fill in for the personal follow-up.