How to Upload Multiple Images in a Laravel API (Step-by-Step)
If you're building a Laravel API that allows users to upload multiple images (like attachments to tasks), this guide will walk you through how to do it — simply and clearly. ✅ Step 1: Update Your Request Validation In your controller (TaskController), make sure to validate that users can upload multiple images: $validator = Validator::make($request->all(), [ 'title' => 'required|string|max:255', 'attachments' => 'nullable|array', 'attachments.*' => 'file|mimes:jpg,jpeg,png,pdf,docx|max:2048', ]); This accepts an array of files (attachments[]) with allowed formats and size. ✅ Step 2: Create a Database Table for Attachments Each task can have many images, so we need a table to store them. Run this command: php artisan make:migration create_task_attachments_table Edit the file: Schema::create('task_attachments', function (Blueprint $table) { $table->id(); $table->foreignId('task_id')->constrained()->onDelete('cascade'); $table->string('file_path'); $table->timestamps(); }); Then run the migration: php artisan migrate ✅ Step 3: Define Relationships in Models In Task.php: public function attachments() { return $this->hasMany(TaskAttachment::class); } In TaskAttachment.php: protected $fillable = ['file_path']; ✅ Step 4: Store the Uploaded Files In your store() method: $task = auth()->user()->tasks()->create([ 'title' => $request->title, // ... other fields ]); if ($request->hasFile('attachments')) { foreach ($request->file('attachments') as $file) { $path = $file->store('attachments', 'public'); $task->attachments()->create(['file_path' => $path]); } } On the above code, the attachments will be saved in the attachment folders on the storage folder inside public directory Make sure you’ve linked storage if not already: php artisan storage:link ✅ Step 5: Return Attachment URLs in API Response To show full URLs to the frontend: $tasks = Task::with('attachments')->get()->map(function ($task) { $task->attachments->map(function ($attachment) { $attachment->url = asset('storage/' . $attachment->file_path); return $attachment; }); return $task; }); Now your API will return: "attachments": [ { "file_path": "attachments/image1.jpg", "url": "http://localhost:8000/storage/attachments/image1.jpg" } ] ✅ Step 6: Upload Multiple Images in Postman Open Postman. Set method to POST. Select form-data. Add fields: title → your task title attachments[] → (select files one by one, each with name attachments[]) Hit Send.

If you're building a Laravel API that allows users to upload multiple images (like attachments to tasks), this guide will walk you through how to do it — simply and clearly.
✅ Step 1: Update Your Request Validation
In your controller (TaskController
), make sure to validate that users can upload multiple images:
$validator = Validator::make($request->all(), [
'title' => 'required|string|max:255',
'attachments' => 'nullable|array',
'attachments.*' => 'file|mimes:jpg,jpeg,png,pdf,docx|max:2048',
]);
This accepts an array of files (attachments[]
) with allowed formats and size.
✅ Step 2: Create a Database Table for Attachments
Each task can have many images, so we need a table to store them.
Run this command:
php artisan make:migration create_task_attachments_table
Edit the file:
Schema::create('task_attachments', function (Blueprint $table) {
$table->id();
$table->foreignId('task_id')->constrained()->onDelete('cascade');
$table->string('file_path');
$table->timestamps();
});
Then run the migration:
php artisan migrate
✅ Step 3: Define Relationships in Models
In Task.php
:
public function attachments()
{
return $this->hasMany(TaskAttachment::class);
}
In TaskAttachment.php
:
protected $fillable = ['file_path'];
✅ Step 4: Store the Uploaded Files
In your store()
method:
$task = auth()->user()->tasks()->create([
'title' => $request->title,
// ... other fields
]);
if ($request->hasFile('attachments')) {
foreach ($request->file('attachments') as $file) {
$path = $file->store('attachments', 'public');
$task->attachments()->create(['file_path' => $path]);
}
}
On the above code, the attachments will be saved in the attachment folders on the storage folder inside public directory
Make sure you’ve linked storage if not already:
php artisan storage:link
✅ Step 5: Return Attachment URLs in API Response
To show full URLs to the frontend:
$tasks = Task::with('attachments')->get()->map(function ($task) {
$task->attachments->map(function ($attachment) {
$attachment->url = asset('storage/' . $attachment->file_path);
return $attachment;
});
return $task;
});
Now your API will return:
"attachments": [
{
"file_path": "attachments/image1.jpg",
"url": "http://localhost:8000/storage/attachments/image1.jpg"
}
]
✅ Step 6: Upload Multiple Images in Postman
- Open Postman.
- Set method to
POST
. - Select
form-data
. - Add fields:
-
title
→ your task title -
attachments[]
→ (select files one by one, each with nameattachments[]
)- Hit Send.