Payload — the data part of a request or response (not headers)
Concept
Payload — the actual data content of a request or response, as distinct from the envelope (headers, status line, metadata).
Etymology: From physics/aviation — the "payload" is the carried weight that is the purpose of the trip (cargo, passengers), as opposed to the weight of the vehicle itself (fuel, structure). In HTTP, the payload is what you're actually trying to send or receive.
Request payload: The body of a POST, PUT, or PATCH request. Contains the data being sent to the server.
Response payload: The body of a response. The resource, data, or message the server is returning.
What is NOT the payload:
- HTTP method, URL, query string (these are the address/routing).
- Headers (these are the envelope metadata).
- Status code (result indicator, not data).
Payload formats:
- JSON:
Content-Type: application/json. Most common for APIs. - Form-encoded:
Content-Type: application/x-www-form-urlencoded. HTML form default.name=Alice&age=30. - Multipart:
Content-Type: multipart/form-data. File uploads. - XML:
Content-Type: application/xml. SOAP, RSS. - Plain text:
Content-Type: text/plain. - Binary: Images, PDFs, binary streams.
Payload size considerations:
- HTTP has no hard size limit by default, but server configs impose limits (PHP's
post_max_size, Nginx'sclient_max_body_size). - Large payloads should be broken into chunks (multipart uploads, streaming).
- For very large data transfers, consider presigned URLs (S3) so clients upload directly to storage, not through your app server.
JWT payload: In JWT, the "payload" specifically means the claims section — the middle base64-encoded segment. Not to be confused with the HTTP body payload.
Code Example
<?php
// REQUEST PAYLOAD — data sent TO the server
// JSON payload (POST /orders)
/*
POST /orders HTTP/1.1
Content-Type: application/json
Content-Length: 72
Authorization: Bearer eyJ...
← blank line — headers end
{ ← PAYLOAD STARTS HERE
"items": [{"product_id": 1, "quantity": 2}],
"shipping_address": "123 Main St"
} ← PAYLOAD ENDS HERE
*/
// Reading different payload formats in Laravel
Route::post('/upload', function (Request $request) {
// JSON payload
$json = $request->json()->all(); // ['items' => [...]]
$name = $request->json('name'); // specific key
// Form-encoded payload (application/x-www-form-urlencoded)
$form = $request->post(); // ['name' => 'Alice', 'age' => '30']
// Multipart payload (file upload)
$file = $request->file('avatar'); // UploadedFile object
$text = $request->input('name'); // form field from multipart
// Raw payload — when format is unusual
$raw = $request->getContent(); // raw string, any format
$xml = simplexml_load_string($raw); // XML payload
});
// RESPONSE PAYLOAD — data sent back FROM the server
// JSON response payload
Route::get('/orders/{id}', function (int $id) {
$order = Order::with('items')->findOrFail($id);
return response()->json([ // PAYLOAD: JSON body
'id' => $order->id,
'total' => $order->total,
'items' => $order->items->map(fn($i) => ['product_id' => $i->product_id, 'qty' => $i->quantity]),
]);
// Headers are NOT the payload: Content-Type, Cache-Control, etc.
// Status code is NOT the payload: 200 OK
});
// Empty payload — 204 No Content
Route::delete('/orders/{id}', function (int $id) {
Order::findOrFail($id)->delete();
return response()->noContent(); // NO payload — empty body
});
// Large payload — stream instead of loading into memory
Route::get('/exports/users', function () {
return response()->stream(function () {
echo "id,name,email\n";
User::query()->cursor()->each(function (User $user) {
echo "{$user->id},{$user->name},{$user->email}\n";
ob_flush(); flush();
});
}, 200, ['Content-Type' => 'text/csv']);
// Payload streams chunk by chunk — no memory overflow
});
// Payload size limits in PHP
// php.ini: post_max_size = 8M (default)
// upload_max_filesize = 2M (default)
// nginx: client_max_body_size 10m;
// Laravel can also set: Request::setMaxInputVars(5000);