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

Open source

Tickets for Laravel

Install
composer require roundly-consulting/tickets-for-laravel
Requires: PHP ^8.4 · Laravel ^12.0|^13.0

Overview

A headless helpdesk core for Laravel. Customers and colleagues open tickets with gap-free references, your team works them through swappable statuses, and everyone talks in one conversation per ticket — public replies plus internal notes requesters never see. Assignment, priorities, due dates, custom fields, guest requesters, merging, mail notifications in English and Slovak and an opt-in JSON API sit behind one facade. MIT-licensed and built only on official Laravel components and Roundly’s own packages for statuses, comments, custom fields, translations, files and filtering — no third-party helpdesk vendor.

What you get

Gap-free references

Human numbers like TCK-42, or SUP-42 per project — handed out in order with no gaps and no duplicates, even under concurrent creates.

Swappable statuses

Seven states in five categories on lifecycle-for-laravel, one-word transitions, automations and auto-close — or your own lifecycle.

Replies and internal notes

One conversation per ticket: public replies that can move the ticket on, and agent-only notes that never reach a requester, a mail or a count.

Assignment and due dates

Assign people or whole teams, let agents claim work, set category defaults, and flag overdue and due-soon tickets exactly once.

Custom fields

Typed fields globally, per project or per category, with allow-listed rules, encryption and requester visibility — filterable from PHP and the API.

Guests, merging and links

Requesters without an account behind revocable signed links, duplicate merging, typed ticket links, watchers and coloured tags.

Opt-in JSON API and mail

Role-aware resources, filters, bulk actions, rate limits and a policy — plus queued, visibility-checked mail in English and Slovak.

Facade, DI or actions

One Tickets facade, an injectable manager or single-purpose actions — and a recording fake that still performs every call.

Documentation

Use cases

Where the package fits — SaaS support, IT desks, agency projects, shops and public services — and the shipped capability behind each one.

Installation

Install via Composer, run tickets:install and migrate, settle key types, make your user an assignee, define the abilities and schedule the sweeps.

Configuration

Every config key with its env variable and default — keys, lifecycle, priorities, guests, watchers, authorization, attachments, routes and notifications.

Models, keys and references

Key types, gap-free references and sequences, the nine models, the Ticket model’s columns, status helpers and host metadata, model swaps and enums.

The Tickets facade

Tour the Tickets facade — make() and create(), the for($ticket) handle, categories, fields, tags, guests, projects, visibleTo() and sweep().

DI and actions

Skip the facade: inject TicketsManager or call a single-purpose action — every host-facing action with its execute() signature and facade path.

Filing and editing tickets

File tickets with the builder or CreateTicketData, fill defaults from categories, then edit, recategorise, hand over, delete and restore them.

Statuses and transitions

Seven states, five categories and nine transitions — plus named conveniences, automations, auto-close, the conversation lock and custom lifecycles.

Replies and internal notes

Public replies and agent-only notes on a comments-for-laravel thread — author roles, reply automations, first response, moderation, mentions and edits.

Categories and priorities

Nested, translatable categories with a default priority, assignee and due offset — plus the weighted priority enum and how to swap it.

Due dates and the sweep

Set, move or clear due dates, fill them from categories, and flag overdue and due-soon tickets exactly once with Tickets::sweep() or tickets:sweep.

Assignment and watchers

One assignee per ticket — a user or a team — with claim(), eligibility and default assignees, plus watchers, auto-watch and requester hand-overs.

Tags and links

Agent-only coloured tags, global or per project, with permanent names — and typed links between tickets with cycle checks.

Merging tickets

Merge a duplicate into the right ticket — conversation, watchers, tags and files move over in one transaction, and the source closes with a pointer.

Attachments

Files on the ticket itself in a private media-library bucket, served through short-lived signed URLs — plus attachments on replies and notes.

Custom fields

Typed fields globally, per project or per category, with allow-listed rules, encryption and requester visibility — set, read, filter and prune values.

Guests and guest links

Tickets from people without an account — configurable guest fields, safe matching of returning guests, conversion on sign-up and revocable signed links.

Projects

Number tickets per project (SUP-1, WEB-1) with their own categories, fields and tags through the TicketProject contract and the HasTickets trait.

Querying and the activity timeline

Eloquent scopes shared by PHP and the API — status, priority, category, assignee, fields, dates and search — plus the append-only activity timeline.

JSON API

An opt-in JSON API — routes, request bodies, bulk actions, role-aware resources, list filters and sorts, rate limits and error codes.

Policy and agent scope

The TicketPolicy behind the API, the Gate abilities you define, scoped managers, and an AgentScope that limits agents to the tickets they may work on.

Notifications

Ten queued, after-commit notifications in English and Slovak — recipients, visibility re-checks, payloads, swapping classes and other channels.

Extension points

Every swap point — contracts and their shipped implementations, the lifecycle, priority enum, models, policy and notifications — without forking.

Events

34 after-commit events, 33 of them TicketEvent — one typed listener hears every ticket change for webhooks, audit logs and dashboards.

Exceptions

Every TicketsException subclass, when it is thrown and the HTTP status the API answers with — plus how field and guest validation errors are keyed.

Artisan commands

tickets:install, tickets:doctor with its checks and exit codes, tickets:sweep for due dates and tickets:prune-fields for orphaned values.

Testing

Tickets::fake() records every operation and still performs it — every assertion and its negative twin, recorded operations, factories and app setup.

Requirements

PHP 8.4+, Laravel 12 or 13, MySQL or PostgreSQL (SQLite for tests) and the Roundly packages it builds on, installed by Composer.

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.