This example demonstrates how to add standards-based HTTP deprecation and sunset headers to your API responses using Zuplo's built-in outbound policy. Clients can detect deprecated or soon-to-retire endpoints and adapt before the sunset date.
This pattern is useful for:
- API versioning: Signal that an endpoint or version is deprecated and direct clients to migration docs
- Sunset communication: Publish a concrete date when an endpoint will be retired (RFC 8594)
- Migration guidance: Link to documentation so integrators know how to upgrade
Prerequisites
- A Zuplo account. You can sign up for free.
- A Zuplo project (optional for local dev; required if you deploy or use Zuplo services)
Working with this Example
Locally
Working locally is the best way to explore and understand the code for this example. You can get a local version by using the Zuplo CLI:
Then install dependencies:
Before running the dev server, you may optionally link to your Zuplo project (see Setup).
Deploy this example to Zuplo
It is also possible to deploy this example directly to your Zuplo account and work with it via the Zuplo Portal. You can do this by clicking the Deploy to Zuplo button anywhere on this page.
Setup
This example does not require API key authentication or environment variables for the deprecation feature. To run it locally:
1. (Optional) Link Your Local Environment
To connect your local development environment to Zuplo services, run:
Follow the prompts to select your account, project, and environment. This creates a .env.zuplo file. You can still run the gateway without linking; the deprecation policy works the same.
Note: Don't commit
.env.zuploor.envto version control. These files contain environment-specific configuration.
For more details, see Connecting to Zuplo Services Locally.
How It Works
The example proxies requests to the Todo API and adds deprecation metadata to every response via an outbound policy. Flow:
- A request hits a route (e.g.
GET /todos). - The URL Forward handler forwards the request to the backend (
https://todo.zuplo.io). - The backend responds with the usual status and body.
- The HTTP Deprecation Outbound policy runs on the response and adds (or merges) the
Deprecation,Sunset, andLinkheaders before the response is sent to the client.
Deprecation options are configured in config/policies.json for the http-deprecation-outbound policy: deprecation: true, a link URL to migration docs, and a sunset date in ISO 8601 format.
Response Headers
When you call any of the API endpoints, the response includes standard HTTP headers plus the deprecation-related headers added by the policy. Below is an example of what a typical response looks like.
| Header | Value |
|---|---|
content-type | application/json |
date | Tue, 17 Feb 2026 12:07:40 GMT |
deprecation | true |
link | <https://example.com/docs/v2-migration>; rel="deprecation" |
sunset | Mon, 30 Jun 2025 23:59:59 GMT |
transfer-encoding | chunked |
vary | Accept-Encoding |
When running behind Zuplo's edge or with other infrastructure, you may also see headers such as cf-cache-status, cf-ray, server, and zp-rid (request ID). The ones that convey deprecation to clients are:
deprecation: Indicates the endpoint is deprecated (valuetrueper draft RFC).sunset: The date and time after which the endpoint may be retired (RFC 8594). Shown in HTTP-date format in the response.link: A URL to migration or deprecation documentation, withrel="deprecation".
Clients can parse these headers to warn users, log deprecation, or drive automated migration.
Project Structure
Key files to explore:
config/policies.json: Defines thehttp-deprecation-outboundpolicy and its options (deprecation,link,sunset).config/routes.oas.json: Defines the/todosand/todos/{id}routes; each route’sx-zuplo-route.policies.outboundincludeshttp-deprecation-outbound.
API Endpoints
This example exposes a Todo API that forwards to the demo backend and adds deprecation headers to all responses:
| Method | Path | Description |
|---|---|---|
GET | /todos | Get all todos |
POST | /todos | Create a new todo |
PUT | /todos/{id} | Update a todo |
DELETE | /todos/{id} | Delete a todo |
Running the Example
Start the API Gateway:
The server will start on http://localhost:9000.
Testing the Deprecation Headers
Use curl to call any endpoint and inspect the response headers. The deprecation-related headers will be present on every response.
To see only the headers:
Look for deprecation: true, sunset: Mon, 30 Jun 2025 23:59:59 GMT, and link: <https://example.com/docs/v2-migration>; rel="deprecation" in the output.
Example response (status and key headers; body is a list of todos):
Example: Create a todo and check headers
The response body is from the backend; the deprecation and sunset headers are added by the gateway.
Extending This Example
- Per-route deprecation: Create separate outbound policies (e.g. different
linkorsunsetper route) and attach them only to the routes you want to deprecate. - Conditional headers: Use a custom outbound policy that inspects
requestorcontextand only sets deprecation headers for certain paths or API versions. - Different sunset dates: Change the
sunsetvalue inpolicies.jsonor in a policy’s options to match your retirement schedule. - Multiple links: The
Linkheader can include multiple relations; you can extend the policy or use a custom policy to add morereltypes (e.g.help,alternate).
Troubleshooting
If deprecation headers are missing or incorrect, work through this checklist:
- Dev server is running (
npm run dev) - You are calling the correct base URL (e.g.
http://localhost:9000) - The route uses the outbound policy: in
routes.oas.json, the route’spolicies.outboundarray includes"http-deprecation-outbound" - In
policies.json, thehttp-deprecation-outboundpolicy has the expectedoptions(deprecation,link,sunset)
Common issues:
| Error | Cause | Fix |
|---|---|---|
No deprecation / sunset / link headers | Policy not attached or wrong name | Ensure the route’s outbound array includes the policy name from policies.json |
sunset format looks wrong | Policy expects ISO 8601 (e.g. 2025-06-30T23:59:59Z) | Zuplo converts to HTTP-date in the response; keep config in ISO 8601 |
| Backend returns 4xx/5xx | Backend or network issue | Check backend URL and that https://todo.zuplo.io is reachable; deprecation headers are still added to the response |
Learn More
- HTTP Deprecation and Sunset Headers (Zuplo docs)
- RFC 8594 – Sunset HTTP Header Field
- draft-ietf-httpapi-deprecation-header (Deprecation header)
- URL Forward Handler