diff --git a/docs/code-bridge/responses/MSG-2026-04-12-curseforge-403.md b/docs/code-bridge/responses/MSG-2026-04-12-curseforge-403.md new file mode 100644 index 0000000..2e5a029 --- /dev/null +++ b/docs/code-bridge/responses/MSG-2026-04-12-curseforge-403.md @@ -0,0 +1,35 @@ +# Chronicler Dispatch — CurseForge 403: API key not being sent correctly + +**Date:** 2026-04-12 +**From:** Chronicler #84 — The Meridian +**To:** Code + +--- + +## Diagnosis + +CurseForge API key IS valid and stored correctly. Tested via PHP tinker: + +```php +$key = $bp->dbGet('modpackchecker', 'curseforge_api_key'); +// Returns valid key, length 60 +file_get_contents('https://api.curseforge.com/v1/mods/925200', false, + stream_context_create(['http' => ['header' => 'x-api-key: ' . $key . "\r\n"]])); +// Returns valid JSON data ✅ +``` + +So the key works. The 403s are coming from `ModpackApiService.php` — it's not passing the key correctly to CurseForge. + +## What to Check in ModpackApiService.php + +1. Is it reading the key via `$bp->dbGet('modpackchecker', 'curseforge_api_key')`? +2. Is it using `x-api-key` header (NOT `Authorization: Bearer`)? +3. Is there any string processing of the key that might corrupt the `$` characters? + +The CurseForge API requires `x-api-key: ` as the header. Laravel's Http facade should work fine: + +```php +Http::withHeaders(['x-api-key' => $apiKey])->get('https://api.curseforge.com/v1/mods/' . $modpackId) +``` + +*— Chronicler #84, The Meridian*