How to download file from external api response source using Laravel?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# How to Download Files from External API Responses Using Laravel: A Comprehensive Guide
Dealing with external APIs often involves more than just exchanging JSON data; sometimes, the response points to another resourceâin this case, a downloadable file. When you receive a URL pointing to a file (like the `src` field in your example), the challenge shifts to reliably fetching that remote content and serving it correctly within your Laravel application.
This guide will walk you through the process of downloading files from external API sources using Laravel, addressing the common pitfalls developers face when integrating external services. We will look at why raw cURL calls can fail and how to implement a robust solution.
## The Challenge: Fetching Files Dynamically
Your scenario involves two main steps:
1. Calling an initial API endpoint to get metadata (like `src` and `filename`).
2. Using the `src` URL obtained from step 1 to download the actual file (e.g., a PDF) and send it to the user.
The error you encountered, `Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException`, typically occurs because Laravel's `download()` method expects a local file path or streamable resource that it can physically access on the server filesystem. When you pass an external URL directly to functions expecting a local path, it cannot resolve the remote file, leading to this exception.
## Solution Strategy: Streaming vs. Local Storage
There are two primary ways to handle this: streaming the content directly or temporarily saving the file. For large files, streaming is generally preferred as it avoids overloading your server's memory by downloading the entire file into a temporary disk location first.
### Method 1: Direct Streaming (The Efficient Way)
Instead of trying to use `response()->download()` on an external URL, we should leverage PHP's stream capabilities to pipe the remote file content directly into the Laravel response stream. This is much more memory-efficient and avoids unnecessary disk I/O.
We will use Guzzle or Laravel's built-in HTTP client to fetch the raw file content first, and then return that content as a response with the correct headers.
### Implementation Example using Laravel HTTP Client
Let's refine your logic by properly fetching the file content from the `src` URL:
```php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
class FileController extends Controller
{
public function downloadFileFromApi(Request $request)
{
// 1. Call the initial API to get file metadata
$apiUrl = 'http://webservice.test.de/merchants/orders/getOrderInvoice?key=1234567894&format=json&order_no=444555666';
$response = Http::get($apiUrl);
if ($response->successful()) {
$data = $response->json();
// Check if the required data exists
if (isset($data['result']['invoice']['src']) && isset($data['result']['invoice']['filename'])) {
$fileSourceUrl = $data['result']['invoice']['src'];
$fileName = $data['result']['invoice']['filename'];
// 2. Download the actual file content from the 'src' URL
try {
$fileContent = Http::get($fileSourceUrl)->body();
// 3. Set appropriate headers and return the file stream
return response($fileContent, 200, [
'Content-Type' => 'application/pdf', // Or appropriate MIME type based on extension
'Content-Disposition' => 'attachment; filename="' . $fileName . '"',
]);
} catch (\Exception $e) {
// Handle errors during the file download itself
return response()->json(['error' => 'Failed to download file content: ' . $e->getMessage()], 500);
}
} else {
return response()->json(['error' => 'Missing required file information in API response.'], 400);
}
} else {
return response()->json(['error' => 'Failed to fetch metadata from external API.'], 500);
}
}
}
```
## Best Practices and Conclusion
### Why This Approach Works Better
1. **Avoids File System Issues:** By streaming the content directly via `Http::get()`, you bypass the need for Laravel to physically save a potentially massive file to the server's disk, which solves the `FileNotFoundException`.
2. **Leverages Laravel Tools:** Using the `Illuminate\Support\Facades\Http` facade makes network requests cleaner, more readable, and easier to manage than raw cURL calls. This is fundamental to building scalable applications on **Laravel**.
3. **Correct HTTP Headers:** Setting the `Content-Disposition` header explicitly tells the browser how to handle the response (forcing a download with a specific filename), which is crucial for file delivery.
### Conclusion
Downloading files from external API sources requires careful handling of HTTP requests and response streams. Do not attempt to pass an external URL directly to file manipulation functions; instead, treat the remote source as raw data to be streamed back to the client. By utilizing Laravel's powerful HTTP client and stream functions, you can build robust, efficient, and secure solutions for complex data retrieval tasks. Mastering these patterns is key to developing high-quality applications on the **Laravel** framework.