lsnepomuceno/laravel-brazilian-ceps
| Install | |
|---|---|
composer require lsnepomuceno/laravel-brazilian-ceps |
|
| Latest Version: | 2.2.0 |
| PHP: | >=8.1 <8.6 |
| Laravel: | 10 – 13 |
| Older releases: | 9 |
| License: | MIT |
| Last Updated: | Sep 1, 2026 |
| Links: | GitHub · Packagist |
Search addresses easily with Laravel Brazilian CEPs
Minimum requirements
- PHP: ^8.1, ^8.2, ^8.3, ^8.4, ^8.5
- Laravel: 10, 11, 12 or 13
- PHP Extensions: fileinfo, mbstring, json
Install
Require this package in your composer.json and update composer. This will download the package and the dependencies libraries also.
composer require lsnepomuceno/laravel-brazilian-ceps
Export the settings file using the command below
php artisan vendor:publish --tag=brazilian-ceps
Usage
Using CepService:
<?php
use LSNepomuceno\LaravelBrazilianCeps\Services\CepService;
class ExampleController() {
// PHP 8: Constructor property promotion
public function __construct(protected CepService $cepService) { }
public function dummyFunction(string|int $cep){
$address = $this->cepService->get($cep);
dd($address);
}
}
The returned value will have the structure below, see CepEntity:
LSNepomuceno\LaravelBrazilianCeps\Entities\CepEntity {
city: string,
cep: string,
street: string,
state: string,
uf: string,
neighborhood: string,
number: string | int | null,
complement: string | null,
}
:exclamation: By default, if the CEP is not found, the returned value will be null. If you need exception handling, the option can be enabled in the configuration file.
// config/brazilian-ceps.php
<?php
'throw_not_found_exception' => true
:exclamation: After setting the value of the "throw_not_found_exception" variable to true, remember to update your code:
<?php
use LSNepomuceno\LaravelBrazilianCeps\Services\CepService;
use LSNepomuceno\LaravelBrazilianCeps\Exceptions\CepNotFoundException;
class ExampleController() {
// PHP 8: Constructor property promotion
public function __construct(protected CepService $cepService) { }
public function dummyFunction(string|int $cep){
try {
$address = $this->cepService->get($cep);
dd($address);
} catch(CepNotFoundException $e) {
// TODO necessary
}
}
}
Route API
By default, the package will provide an API route for looking up addresses, as specified below.
| Verb | URI | Invokable Controller | Route Name |
|---|---|---|---|
| GET | api/consult-cep/{cep} | LSNepomuceno\LaravelBrazilianCeps\Controllers\ConsultCepController | consult-cep.api |
:exclamation: In some cases it may be necessary to deactivate this route, in which case just change the value of the "enable_api_consult_cep_route" configuration variable to false, as example below:
// config/brazilian-ceps.php
<?php
'enable_api_consult_cep_route' => false
:exclamation: You can also change the message if the CEP is not found:
// config/brazilian-ceps.php
<?php
'not_found_message' => 'Type here the message you want.'
:exclamation: The initial middleware of the route is "guest", if it is necessary to modify it, just adjust the configuration file:
// config/brazilian-ceps.php
<?php
'api_route_middleware' => ['guest']
Validation Rule
The package provides a ValidCep rule that integrates with Laravel's validation system to validate Brazilian CEP format and, optionally, verify that the CEP actually exists.
Format validation only:
<?php
use LSNepomuceno\LaravelBrazilianCeps\Rules\ValidCep;
class AddressRequest extends FormRequest
{
public function rules(): array
{
return [
'cep' => ['required', 'string', new ValidCep],
];
}
}
Format + existence check:
Using the mustExist() method causes the rule to query the CEP providers to confirm the address exists. This performs an external HTTP request (subject to caching).
<?php
use LSNepomuceno\LaravelBrazilianCeps\Rules\ValidCep;
class AddressRequest extends FormRequest
{
public function rules(): array
{
return [
'cep' => ['required', 'string', (new ValidCep)->mustExist()],
];
}
}
:exclamation: When validation fails, the rule returns Portuguese error messages by default. You can override them via the messages() method in your Form Request:
public function messages(): array
{
return [
'cep.valid_cep' => 'The zip code is invalid.',
];
}
Address Search (Reverse Lookup)
The package provides a search() method to find CEPs by address components — the reverse of a regular CEP lookup. Multiple providers are queried in parallel and results are deduplicated by CEP code.
Providers that support address search:
- ViaCEP — structured search by UF, city, and street
- OpenStreetMap (Nominatim) — free global geocoding also added as a CEP provider fallback
<?php
use LSNepomuceno\LaravelBrazilianCeps\Facades\CEP;
// Returns a Collection of CepEntity
$addresses = CEP::search(uf: 'SP', city: 'São Paulo', street: 'Paulista');
foreach ($addresses as $address) {
echo "{$address->cep} — {$address->street}, {$address->neighborhood}";
}
:exclamation: You can also inject CepService directly:
<?php
use LSNepomuceno\LaravelBrazilianCeps\Services\CepService;
class AddressController
{
public function __construct(protected CepService $cepService) { }
public function search(string $uf, string $city, string $street)
{
$results = $this->cepService->search($uf, $city, $street);
return $results->toArray();
}
}
:exclamation: The street parameter requires at least 3 characters (ViaCEP restriction). Results are returned as a Collection<CepEntity> and are not cached.
Events
The package dispatches Laravel events on every CEP lookup, enabling listeners for logging, monitoring, analytics, or any custom behavior without modifying the core service.
| Event | When |
|---|---|
CepQueried |
Fired at the start of every get() call, before any provider is contacted |
CepFound |
Fired when a provider successfully resolves the CEP |
CepNotFound |
Fired when all providers fail to find the CEP |
Listening to events:
<?php
use LSNepomuceno\LaravelBrazilianCeps\Events\CepFound;
use LSNepomuceno\LaravelBrazilianCeps\Events\CepNotFound;
use LSNepomuceno\LaravelBrazilianCeps\Events\CepQueried;
// In your EventServiceProvider or using the #[AsEventListener] attribute:
Event::listen(CepQueried::class, function (CepQueried $event) {
Log::info("CEP lookup started: {$event->cep}");
});
Event::listen(CepFound::class, function (CepFound $event) {
Log::info("CEP found: {$event->cep}", $event->entity->toArray());
});
Event::listen(CepNotFound::class, function (CepNotFound $event) {
Log::warning("CEP not found: {$event->cep}");
});
:exclamation: All events are read-only — their properties are declared readonly. CepFound carries the resolved CepEntity via $event->entity.
Cache Results
By default, the results cache are cached and have a lifetime of 30 days, if you need to disable or change the lifetime, just update the configuration variables, as described below.
// config/brazilian-ceps.php
<?php
'cache_results' => true,
'cache_lifetime_in_days' => 30
Tests
To ensure the delivery of data, several public providers are used, with this, the need to standardize and apply tests for better code quality was seen. About 90+ tests are included in the package.
Tests can be verified through the badge 
License
The MIT License (MIT). Please see License File for more information.
Related Packages
Com esse pacote você poderá realizar consultas de CEP gratuitamente.
This package has the objective to consult the CEP within one or more web APIs th...
This package has the objective to consult the CEP within one or more web APIs th...
Package para pesquisa de serviços de busca por cep, calculo de frete e etc, dire...
A FilamentPHP plugin that validates Brazilian postal codes (CEP) and automatical...
Version History
| Version | Released | PHP | Laravel | License |
|---|---|---|---|---|
| 2.2.0 | >=8.1 <8.6 | ^10 || | MIT | |
| 2.1.0 | >=8.1 <8.6 | ^10 || | MIT | |
| 2.0.0 | >=8.1 <8.6 | ^10 || | MIT | |
| 1.1.0 | >=8.1 <8.5 | ^9 || | MIT | |
| 1.0.0 | ^8.1 || | ^9 || | MIT | |
| 0.0.5 | ^8.1 || | ^9 || | MIT | |
| 0.0.4 | ^8.1 || | ^9 || | MIT | |
| 0.0.3 | ^8.1 | ^9 | MIT | |
| 0.0.2 | ^8.1 | ^9 | MIT | |
| 0.0.1 | ^8.1 | ^9 | MIT |