'Missing "target" parameter']); exit; } // Construct the full API URL — only allow requests to crdc-api.civilytics.org for security $apiBase = 'https://crdc-api.civilytics.org'; $url = $apiBase . $target; // Validate that we're not proxying arbitrary URLs (prevent SSRF) if (!str_starts_with($url, $apiBase . '/api/v1/')) { http_response_code(403); echo json_encode(['error' => 'Invalid target — must be under /api/v1/']); exit; } // Fetch the API response and return it with CORS headers $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_TIMEOUT => 30, CURLOPT_SSL_VERIFYPEER => false, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // Forward the response with appropriate status code and CORS headers http_response_code($httpCode); header('Access-Control-Allow-Origin: *'); echo $response;