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

Creating requests

The Requests facade is the discoverable entry point. The fully-qualified RoundlyConsulting\Requests\Facades\Requests always works; a short Requests alias is also registered when the name is free:

use RoundlyConsulting\Requests\Facades\Requests;

$request = Requests::make()
    ->author($user)
    ->type('Claim')
    ->title('Expense reimbursement')
    ->description('Travel costs for the client visit.')
    ->meta(['ip' => request()->ip()])
    ->requireApprovalsFrom([$alice, $bob])   // saved approver models — only they may decide
    ->expiresAt(now()->addDays(7))
    ->create();

create() saves the request, associates the author, opens the approval flow when approvers, stages or a workflow are given, and dispatches RequestCreated. requireApprovalsFrom() accepts a saved model or a list of them — only they, or their delegates, may decide, and their keys are recorded in require_approvals_from. A bare id is refused with InvalidApprover. The request and its approval round are written together, so a round that can’t open leaves no request behind.

Builder reference

MethodSets
author(?Model)The polymorphic author.
type(?string)The request type, e.g. Claim.
title(?string)The title.
description(?string)The description.
meta(iterable)Free-form metadata, stored as a Collection.
status(Status)The initial status (default New).
requireApprovalsFrom(Model|iterable)The declared approvers — saved models only (a bare id throws InvalidApprover); only they, or their delegates, may decide.
rule(ApprovalRule)Unanimous (default), Quorum, Any or Weighted.
quorum(?int)The quorum / weight threshold for Quorum and Weighted.
stages(array)An ad-hoc sequential pipeline of StageDefinition objects.
rejectOnStageRejection(bool)Whether a rejected stage rejects the whole request (default true).
workflow(?string)A named preset from config('approvals.workflows').
stageApprovers(array)One approver group per stage, for a staged preset.
expiresAt(?CarbonInterface)The expiry deadline (overrides default_ttl).
toDto()Returns the assembled CreateRequestDto without saving.
create()Terminal — saves the request, opens the approval flow and returns the Request.

Requests without approvers

Declaring approvers is optional. Without them no approval request is opened, and the first approve or reject resolves the request immediately:

// No approvers declared — the first decision resolves the request.
$request = Requests::make()
    ->author($user)
    ->type('AccessRequest')
    ->title('Access to the billing dashboard')
    ->create();

Building the DTO only

toDto() returns the assembled CreateRequestDto without saving — handy for queueing or for passing to the manager later:

// Build the DTO without persisting, then hand it to the manager.
$dto = Requests::make()
    ->author($user)
    ->title('Expense reimbursement')
    ->toDto();

$request = Requests::create($dto);

Expiry

expiresAt() stamps a deadline on the request. Without it, requests.default_ttl (in minutes) applies when set; otherwise the request never expires on its own (Cancel & expire).

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.