NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Requests for Laravel

The Requests facade

The Requests facade is the recommended entry point. The fully-qualified RoundlyConsulting\Requests\Facades\Requests always works; a short Requests alias is also registered when the name is free. It resolves RequestManager, so every call below also works on an injected manager (see DI, actions & the DTO). The full surface:

use RoundlyConsulting\Requests\Enums\Status;
use RoundlyConsulting\Requests\Facades\Requests;

// Create — fluently, or from a ready DTO
$request = Requests::make()->author($user)->title('Expense reimbursement')
    ->requireApprovalsFrom([$alice, $bob])->create();
$request = Requests::create($dto);

// Decide — the reason is optional
Requests::approve($request, $alice, reason: 'Within budget');
Requests::reject($request, $carol, reason: 'Out of policy');
Requests::reopen($request, $alice);        // back to New — a finished round reopens fresh

// Close
Requests::cancel($request);                // status = Cancelled
Requests::expire($request);                // status = Expired
Requests::expireDue();                     // int — expire every open, past-due request

// Ask the lifecycle graph
Requests::canTransition($request, Status::Approved);   // bool

Method reference

MethodReturnsPurpose
make()RequestBuilderStart a fluent request; ->create() saves it.
create(CreateRequestDto $dto)RequestCreate a request from a ready DTO.
approve($request, $actor, ?$reason)RequestRecord an approval; the rule decides when the request flips.
reject($request, $actor, ?$reason)RequestRecord a rejection.
reopen($request, $actor, ?$reason)RequestBack to New; withdraws the actor’s decision, or opens a fresh round once the last one is over.
cancel($request)RequestStatus Cancelled; closes the open approval round.
expire($request)RequestStatus Expired; closes the open approval round.
expireDue(bool $dryRun = false, int $chunk = 500)intExpire every open, past-due request; a dry run only counts them.
canTransition($request, Status $to)boolWhether the lifecycle graph allows the move.
fake()RequestsFakeSwap in the recording fake — see Testing.

approve(), reject() and reopen() take any model that implements GivesApprovalsInterface. The fluent builder behind make() is covered in Creating requests.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.