Laravel Retainer Check-In Form Template | FilaForms                                 [ ![Filaforms Logo](https://filaforms.app/logo.svg)FilaForms

 ](https://filaforms.app)  [ Features ](https://filaforms.app#features) [ Pricing ](https://filaforms.app/pricing) [ Blog ](https://filaforms.app/blog) [ Documentation ](https://docs.filaforms.app)  [ Try Demo ](https://filaforms.app/login) [ Buy a license ](https://filaforms.app/pricing#plans) 

 [ Features ](https://filaforms.app#features) [ Pricing ](https://filaforms.app/pricing) [ Blog ](https://filaforms.app/blog) [ Documentation ](https://docs.filaforms.app) [ Try Demo ](https://filaforms.app/login) [ Buy a license ](https://filaforms.app/pricing#plans) 

  1. [Home](https://filaforms.app)
2. /
3. [Form Templates](https://filaforms.app/templates)
4. /
5. Review a client's retainer hours and priorities every month

 Agency &amp; Freelance template

Review a client's retainer hours and priorities every month
===========================================================

Import a Laravel retainer check-in form for Filament to record monthly hours, client satisfaction, priorities, and renewal risk.

 [ Open this template in the demo builder ](https://filaforms.app/app/templates/retainer-check-in) 14 fields, 8 required. Free demo account, no card. 

 Updated September 2, 2026

 This Laravel retainer check-in form gives an agency client a regular place to report hours used, satisfaction, and current priorities. Import it into FilaForms to collect one monthly check-in, then review the stored submission beside the client work your Laravel application already manages.

The field table below supplies the imported structure for the conversation. Each completed check-in records the hours used, satisfaction response, and priorities as a submission in your application's database. Your account manager can review the response before the next monthly planning call.

  Fields in this template (14 fields, 8 required) 
-------------------------------------------------

 Field types used: Text, Email, Date, Number, Currency, Radio, Textarea, Toggle Buttons. Every field is editable in the builder after import.

### Account

    Field Type Required Validation      Client Name `client_name`   Text  Yes  `required`     Contact Email `email`   Email  Yes  `required | email`     Reporting Month `reporting_month`   Date  Yes  `required`     Account Manager `account_manager`   Text  No  none     

### This Month

    Field Type Required Validation      Hours Used `hours_used`   Number  Yes  `required | numeric | min:0`     Hours Included `hours_included`   Number  Yes  `required | numeric | min:0`     Overage Charge `overage`   Currency  No  none     Satisfaction This Month `satisfaction`   Radio, 4 options  Yes  `required`     What Went Well `went_well`   Textarea  No  none     What Should Change `should_change`   Textarea  No  none     

### Next Month

    Field Type Required Validation      Priorities `priorities`   Textarea  Yes  `required`     Renew Retainer `renew`   Toggle Buttons, 4 options  Yes  `required`     Adjusted Monthly Hours `adjusted_hours`   Number  No  `numeric | min:0`     Notes `notes`   Textarea  No  none     

 Turn a monthly response into an account action
----------------------------------------------

The field table below groups operational review details before future planning. Start with hours used because it frames the client's view of the month. Follow it with satisfaction and priorities, because raw capacity figures cannot explain whether the work served the client's current needs.

Keep the monthly cadence consistent when you want to compare responses over time. A client may report low usage because they lacked requests, because delivery moved slowly, or because the agreed scope changed. The priorities response gives the account manager context before they draw a conclusion from the hours alone.

Use the settings block to decide who receives the form and when. Send the request before a scheduled monthly review, not after the month has already closed. That timing lets the client name upcoming work while the team still has time to adjust the next period's plan.

The submission dashboard is useful for reviewing individual answers. Your application should own the client relationship rules that follow. It may match a submission to an account record, add a review task, or notify the person responsible for the renewal conversation.

Flag a client before renewal risk becomes a surprise
----------------------------------------------------

A low satisfaction response deserves a deliberate follow-up. Treat it as a signal for an account manager to review the complete response, rather than as an automatic decision about the client relationship. The priorities value can reveal a missed expectation, a new business need, or a request that belongs in a separate scope discussion.

The listener below reads `hours_used`, `satisfaction`, and `priorities` from this template. It records the answers and marks recognised low satisfaction values in the application log. Replace that log destination with your existing account-review queue or notification workflow after you define who owns the follow-up.

Save the listener as `app/Listeners/LogRetainerCheckIn.php`. Laravel 12 discovers listeners in `app/Listeners` automatically.

```
submission;
        $data = $submission->data;
        $satisfaction = $data['satisfaction'] ?? null;

        Log::info('Retainer check-in submitted', [
            'form_id' => $event->form->getKey(),
            'submission_id' => $submission->getKey(),
            'hours_used' => $data['hours_used'] ?? null,
            'satisfaction' => $satisfaction,
            'priorities' => $data['priorities'] ?? null,
            'needs_account_review' => in_array($satisfaction, ['low', '1', '2'], true),
        ]);
    }
}

```

Read the log entry as a triage record, not as a client-health score. An account manager should see the full submission before contacting the client. They can confirm whether the response reflects a one-off delivery issue, an expected quiet period, or a genuine concern about the value of the retainer.

If your application already has account ownership, route low satisfaction to that owner. Include the submitted priorities in the review task so the recipient can prepare a useful response. Keep escalation rules outside the form when they depend on contract value, renewal timing, or a client's history.

Adapt the check-in for fixed monthly scope
------------------------------------------

For retainers with a fixed monthly scope, drop the `adjusted_hours` field. A fixed-scope arrangement measures whether agreed work happened, not whether hours were rebalanced. Removing that field keeps the check-in aligned with the agreement and avoids asking clients to interpret a number they do not use.

Add a `renewal_date` field when the account team needs contract timing beside each monthly response. That value helps the team see which conversations need to move from routine planning into renewal preparation. Make the field relevant to an existing contract record when possible, so your application has one source of truth for the term.

Do not use a changed form structure to rewrite earlier submissions. A check-in from a prior period should retain the questions the client saw then. New fields can begin with the next reporting cycle, while the saved response remains an accurate record of that month's conversation.

Use check-ins as a renewal signal, not an invoice
-------------------------------------------------

Monthly check-ins work best when the account manager reviews patterns across several submissions. Repeated low satisfaction, unclear priorities, and a widening gap between planned work and reported usage can justify an earlier conversation. A single answer can start that review, but it should not replace judgment from the team that knows the account.

Use this template alongside a [Laravel form builder for Filament](/) when the check-in belongs in the client portal your agency operates. Review the [FilaForms features for Laravel and Filament](/features) when you need to connect submissions to notifications, analytics, or the rest of your application workflow.

This form does not calculate overage billing on its own. The listener only stores the answers, so invoicing still happens in a separate system. Keep billing calculations in the system that owns rates, approved time, invoice status, and financial records.

Know when another workflow fits better
--------------------------------------

Choose this template when a monthly account review needs a structured client response before a planning or renewal discussion. It gives the account manager a repeatable input surface and keeps the original response available for later review. Use a separate workflow when the primary job is calculating charges or issuing invoices.

The template does not decide whether a client should renew. It gives your team timely evidence for that decision. That boundary matters. An account manager may need to compare the submitted response with project delivery, open requests, contract terms, and conversations that a form cannot capture.

 Use this template in your own application
-----------------------------------------

 With FilaForms installed, one call creates the form with every field, rule, and setting listed above. Then edit it in the builder.

```
use FilaForms\Core\Support\FormTemplates;

$form = FormTemplates::createFormFromTemplate('retainer-check-in');
```

  Template schema (JSON) ```
{
    "name": "Retainer Check-In",
    "description": "Run a monthly retainer review with hours and priorities",
    "icon": "heroicon-o-arrow-trending-up",
    "category": "Agency & Freelance",
    "popularity": "Medium",
    "sections": [
        {
            "name": "Account",
            "fields": [
                {
                    "label": "Client Name",
                    "type": "text",
                    "code": "client_name",
                    "required": true,
                    "width": "50"
                },
                {
                    "label": "Contact Email",
                    "type": "email",
                    "code": "email",
                    "required": true,
                    "validation": [
                        {
                            "name": "email",
                            "parameters": []
                        }
                    ],
                    "width": "50"
                },
                {
                    "label": "Reporting Month",
                    "type": "date",
                    "code": "reporting_month",
                    "required": true,
                    "width": "50"
                },
                {
                    "label": "Account Manager",
                    "type": "text",
                    "code": "account_manager",
                    "required": false,
                    "width": "50"
                }
            ]
        },
        {
            "name": "This Month",
            "fields": [
                {
                    "label": "Hours Used",
                    "type": "number",
                    "code": "hours_used",
                    "required": true,
                    "validation": [
                        {
                            "name": "numeric",
                            "parameters": []
                        },
                        {
                            "name": "min",
                            "parameters": [
                                "0"
                            ]
                        }
                    ],
                    "width": "50"
                },
                {
                    "label": "Hours Included",
                    "type": "number",
                    "code": "hours_included",
                    "required": true,
                    "validation": [
                        {
                            "name": "numeric",
                            "parameters": []
                        },
                        {
                            "name": "min",
                            "parameters": [
                                "0"
                            ]
                        }
                    ],
                    "width": "50"
                },
                {
                    "label": "Overage Charge",
                    "type": "currency",
                    "code": "overage",
                    "required": false,
                    "width": "50"
                },
                {
                    "label": "Satisfaction This Month",
                    "type": "radio",
                    "code": "satisfaction",
                    "required": true,
                    "options": [
                        {
                            "value": "Very satisfied"
                        },
                        {
                            "value": "Satisfied"
                        },
                        {
                            "value": "Neutral"
                        },
                        {
                            "value": "Dissatisfied"
                        }
                    ],
                    "width": "50"
                },
                {
                    "label": "What Went Well",
                    "type": "textarea",
                    "code": "went_well",
                    "required": false,
                    "width": "100"
                },
                {
                    "label": "What Should Change",
                    "type": "textarea",
                    "code": "should_change",
                    "required": false,
                    "width": "100"
                }
            ]
        },
        {
            "name": "Next Month",
            "fields": [
                {
                    "label": "Priorities",
                    "type": "textarea",
                    "code": "priorities",
                    "required": true,
                    "width": "100"
                },
                {
                    "label": "Renew Retainer",
                    "type": "toggle-buttons",
                    "code": "renew",
                    "required": true,
                    "options": [
                        {
                            "value": "Yes"
                        },
                        {
                            "value": "Adjust hours"
                        },
                        {
                            "value": "Pause"
                        },
                        {
                            "value": "Cancel"
                        }
                    ],
                    "width": "100"
                },
                {
                    "label": "Adjusted Monthly Hours",
                    "type": "number",
                    "code": "adjusted_hours",
                    "required": false,
                    "validation": [
                        {
                            "name": "numeric",
                            "parameters": []
                        },
                        {
                            "name": "min",
                            "parameters": [
                                "0"
                            ]
                        }
                    ],
                    "width": "50"
                },
                {
                    "label": "Notes",
                    "type": "textarea",
                    "code": "notes",
                    "required": false,
                    "width": "50"
                }
            ]
        }
    ]
}
```

  Frequently asked questions
--------------------------

  What does this Laravel retainer check-in form record? It records the hours used, satisfaction response, and priorities for one monthly retainer check-in as a submission in your application's database. 

 Can I use this form for a fixed-scope retainer? Yes. Drop the adjusted\_hours field when the retainer has a fixed monthly scope. 

 How can I flag a client who may not renew? Listen for FilaForms\\\\Core\\\\Events\\\\FormSubmitted, read hours\_used, satisfaction, and priorities from the submission data, then route a low satisfaction response to the account manager. 

 Does this form calculate retainer overage billing? No. The form does not calculate overage billing on its own. The listener only stores the answers, so invoicing still happens in a separate system. 

   Run this form inside your Laravel app.
--------------------------------------

 FilaForms installs as a Filament plugin. Submissions land in your own database.

 [ Try it in the demo ](https://filaforms.app/app/templates/retainer-check-in) [ See pricing ](https://filaforms.app/pricing) 

More templates
--------------

- [ Get everything you need from a new client before kickoff Import a Laravel client onboarding form for Filament, collect project details, and route e... ](https://filaforms.app/templates/client-onboarding)
- [ Capture scope changes and client approval before work starts Import a Laravel change request form for Filament, record scope, cost, priority, and clien... ](https://filaforms.app/templates/change-request)
- [ Brief a writer with everything they need before they start Import a Laravel content request form template for Filament, collect complete writer brief... ](https://filaforms.app/templates/content-request)
- [ Run structured performance reviews your managers can complete in minutes Import a Laravel performance review form for Filament, then route manager ratings into you... ](https://filaforms.app/templates/performance-review)
- [ Ask attendees how your event went, right after it ends Import a Laravel event feedback form for Filament, collect attendee ratings, and route eac... ](https://filaforms.app/templates/event-feedback)
- [ Capture honest feedback before an employee's last day Install a Laravel exit interview form for Filament, route sensitive answers carefully, and... ](https://filaforms.app/templates/exit-interview)
- [ Collect customer testimonials your marketing team can actually publish Import a Laravel testimonial collection form for Filament, collect publishable customer fe... ](https://filaforms.app/templates/testimonial-collection)
- [ Enroll a student with guardian and medical details in one form Import a Laravel student enrollment form for Filament, collect guardian and medical detail... ](https://filaforms.app/templates/student-enrollment)

    ![FilaForms Logo](/logo.svg) FilaForms 

 Laravel form infrastructure for Filament. Stop rebuilding forms on every project.

 [ Buy a license   ](https://filaforms.app/pricing#plans) 

 ### Product

 [ Features ](https://filaforms.app#features) [ Documentation ](https://docs.filaforms.app) [ Blog ](https://filaforms.app/blog) [ Compare form builders ](https://filaforms.app/compare) [ Templates ](https://filaforms.app/templates) [ Pricing ](https://filaforms.app/pricing) [ About ](https://filaforms.app/about) [ Contact ](mailto:hello@filaforms.app) 

 ### Legal

 [ Terms of Service ](https://filaforms.app/terms-of-service) [ Privacy Policy ](https://filaforms.app/privacy-policy) 

  © 2025-2026 FilaForms. All rights reserved.

 [    ](mailto:hello@filaforms.app) [    ](https://x.com/MinasyanManuk)
