Organizing Routes with Laravel Route Groups
In a Laravel application, each route tells Laravel which code handles an incoming HTTP request, such as GET /users. A route group…
When code on a Laravel server calls an external API, the server sends an HTTP request. The request’s headers are named values that tell the receiving server what response format the client expects and which credentials the request carries. Laravel’s HTTP Client has methods for adding headers and setting common authentication methods.
Use withHeaders to set general header values, withToken to send a bearer token, and Laravel’s authentication methods to send Basic or Digest credentials. Read secret values from server-side configuration so they stay out of source code and files sent to the browser.
Call withHeaders before the request method, passing an array of header names and values:
use Illuminate\Support\Facades\Http;
$response = Http::withHeaders([
'X-Client' => 'billing-service',
'Accept' => 'application/json',
])->get('https://api.example.com/v1/invoices');
Laravel sends these values with the outbound request. Accept tells the API what response format the client expects. For JSON responses, acceptJson() is a shortcut:
$response = Http::acceptJson()
->get('https://api.example.com/v1/invoices');
You can also call withHeaders on a request configuration that already has headers. It adds the supplied values to the existing headers. Call replaceHeaders to replace all of them. The Laravel HTTP Client documentation describes these methods and the acceptJson shortcut.
Accept tells the API which response format the client wants. Content-Type tells the API the format of the request body. If the API requires a specific content type, set it in a header:
$response = Http::withHeaders([
'Content-Type' => 'application/json',
])->post('https://api.example.com/v1/invoices', [
'reference' => 'INV-123',
]);
Set the header names and values the API requires. If a header is misspelled or its value is incorrectly formatted, the server still receives it as part of the request, and the API can reject the request or interpret it differently.
A bearer token is a secret value that gives a request the access granted to that token. Laravel’s withToken method sends it in the Authorization header with the Bearer scheme:
$response = Http::withToken($token)
->acceptJson()
->get('https://api.example.com/v1/account');
The header looks like this: Authorization: Bearer <token>. Laravel also provides withBasicAuth($username, $password) for Basic authentication and withDigestAuth($username, $password) for Digest authentication. Each method adds authentication details to the request. Use the method the API requires. The Laravel HTTP Client reference covers these options.
Do not put tokens or passwords in code you commit. Store the value in the server’s .env file, then make it available to your code through config/services.php:
PARTNER_API_TOKEN=your-secret-token
// config/services.php
'partner' => [
'token' => env('PARTNER_API_TOKEN'),
],
Read the configured value when you create the request:
$response = Http::withToken(config('services.partner.token'))
->acceptJson()
->get('https://api.example.com/v1/account');
Keep the .env file outside the directory the web server serves publicly. The server should serve the public directory, not the project root. Keep secret tokens on the server. Do not put them in JavaScript or other files sent to a user’s browser. The Laravel security discussion explains the risk of exposing environment files.
An incorrect header value or a mismatch with the API’s requirements can cause an authentication failure. A redirect before the request reaches the endpoint is another possible cause. Check that the API expects the authentication method you used and that your configured token is present. Also check whether the URL redirects. In one reported case involving Laravel 9 and Guzzle, a redirect dropped the Authorization header, and the server denied access. When possible, send the request directly to the API’s final HTTPS endpoint. If the request fails only after a redirect, investigate that redirect. The reported redirect case describes that setup, so use it as a troubleshooting lead, not as a rule for every Laravel request.
Laravel’s HTTP Client does not automatically throw an exception for every response with a 4xx or 5xx status. Check the response status before treating the request as successful:
if ($response->successful()) {
$data = $response->json();
} elseif ($response->clientError()) {
// The API rejected the request.
} elseif ($response->serverError()) {
// The API returned a server error.
}
The rejection alone does not identify whether authentication, another header, or the request body caused the problem. Use the response status and the API’s error message to narrow down the cause. Do not log secret header values while debugging.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com