We're rolling out API key authentication for direct file downloads from the CurseForge CDN (edge.forgecdn.net). If your application downloads files from CurseForge, this affects you.
There's no need to scramble, though. The change is optional today and will only become required on July 16th.
Here's everything you need to know.
TL;DR
• Direct CDN downloads now support an API key.
• It's optional now, required mid-July.
• Once enforcement begins, requests without a valid key return 401 Unauthorized.
• Authenticating lets us attribute downloads to your platform, giving mod authors accurate source analytics and crediting the traffic your tool delivers.
• Recommended: add your key now during the optional window so nothing breaks for your users later.
Who this is for?
This is aimed at the developers and operators of any tool or service that downloads files from the CurseForge CDN: launchers, modpack installers, server tools, and similar integrations.
If you only use the CurseForge app or website, there's nothing to do here. This is handled for you.
What's changing?
The endpoint itself stays the same:
https://edge.forgecdn.net/files/{id}/{subId}/{filename}
What's new is that you can now include an API key with your request. During the current phase, the key is optional, and unauthenticated downloads keep working as before. On July 16th, a valid key will be required, and any request without one will be rejected.
Why we're doing this?
This change will get us a step closer towards an improved analytics system for our mod authors. It's meant to give authors a clearer understanding of where their downloads are coming from, among other important information.
This is about attribution and analytics for creators, not gatekeeping content.
When a file is pulled directly from the CDN today, mod authors often can't tell which tool or platform delivered the download. By having each integration authenticate with its own key, we can attribute downloads to their source and give authors a much clearer picture of where and how their work is being used.
There's an upside for you, too: the downloads your platform delivers get credited to your platform. Instead of that traffic disappearing into an anonymous pool, authors can see the value your launcher or service brings to their content.
How to authenticate?
You can provide your API key in one of two ways. Both are valid, so pick whichever fits your setup.
Option 1: Request header (recommended)
Send your key in the x-api-key header. This is the preferred method for production, since it keeps the key out of server logs, browser history, and referrer headers.
GET https://edge.forgecdn.net/files/1234/56/ExampleMod-2.0-1.20.1.jar
x-api-key: YOUR_API_KEY
curl:
curl "https://edge.forgecdn.net/files/1234/56/ExampleMod-2.0-1.20.1.jar" \
--output ExampleMod.jar
JavaScript (fetch):
const response = await fetch( "https://edge.forgecdn.net/files/1234/56/ExampleMod-2.0-1.20.1.jar", { headers: { "x-api-key": "YOUR_API_KEY" } });
Python (requests):
import requestsurl = "https://edge.forgecdn.net/files/1234/56/ExampleMod-2.0-1.20.1.jar"headers = {"x-api-key": "YOUR_API_KEY"}response = requests.get(url, headers=headers)response.raise_for_status()with open("ExampleMod-2.0-1.20.1.jar", "wb") as f: f.write(response.content)
Option 2: Query parameter
Append ?api-key=YOUR_API_KEY to any CDN URL. Handy for quick tests in a browser or with curl:
curl "https://edge.forgecdn.net/files/1234/56/ExampleMod-2.0-1.20.1.jar?api-key=YOUR_API_KEY" \ -o ExampleMod-2.0-1.20.1.jar
Note: Query parameters can show up in server access logs and browser history. Prefer the header method anywhere it matters.
Timeline
Phase: Now
Behavior: API key accepted but optional. Unauthenticated requests still succeed.
Phase: Future (July 16th)
Behavior: API key required. Requests without a valid key return 401 Unauthorized.
What a rejected request looks like
Once enforcement is active, requests without a valid key will return an error:
HTTP/1.1 401 Unauthorized{ "error": "Unauthorized", "message": "A valid api-key is required."}
Build for this now: handle 401 responses gracefully and surface a clear, actionable message rather than failing silently.
For any questions, join the Authors Discord: Here!