What you'll build
By the end of this guide, you'll have a working approval workflow: a request form that routes submissions to the right approver based on request type, automatic email notifications at every stage, and a live dashboard where approvers review and close requests. No code, no spreadsheet, no chasing people through email.
When to use this
Your team receives approval requests over email and you're losing track of what's pending, what's approved, and what fell through the cracks
Different request types need to go to different approvers, but you're doing the routing manually every time
Requesters have no visibility into where their submission stands after they send it
You want a clear record of every decision for audit, compliance, or reporting purposes
Your approval process takes days when it should take hours
Step-by-step
The workflow we'll build in this tutorial has the following stages:
Client submits a project & quote request form
The submission is automatically assigned
Everyone gets notified
Assigned team member submits the quotes
The client is notified with a magic link
The client signs & submits the contract
Everyone gets notified
Contract PDF document is generated & attached
Step 1: Create the request form
From your Formaloo workspace, click + New project and select Form.
Name your project (e.g., "Quote request form") and click Create.
Open the form. You'll see a default text field already added. Rename it or replace it with the fields below.
Add the following fields to your form:
Short text: requester name (open field settings and set the field ID to
requester_name)Email: requester email (set the field ID to
requester_email)Dropdown: request type (e.g., "Website design", "Branding", "SEO"). This field drives your routing logic in the next step
Long text: request details
Single choice: budget, if applicable (e.g., Under $5k, $5k - $10k, $10k+)
File upload: supporting documents
Dropdown: status (e.g., "Pending", "Approved", "Rejected"). Set it as admin-only on the public form; approvers will update it from the dashboard. Having the field selected, set its default value to "Pending" from the right field properties sidebar. This auto-stamps every new submission.
Assignee: the team member or team that should take care of the submitted request. Set it as admin-only on the public form so clients can't see it on the form interface.
Short text: project title, admin-only so the assignee can set a recognizable title on the project. Set the field ID to
project_titleNumber: quote amount, admin-only so the assignee can update the request with the offered price. Set the field ID to
quote_amountLong text: terms and notes, admin-only so the assignee can describe the project quote, timeline, and implementation details. Set the field ID to
terms_notes
π‘ Assigning field IDs now saves you time in every later step. You'll reference @requester_name and @requester_email in notification emails and PDFs to personalize them automatically.
Step 2: Add conditional routing logic
Routing logic determines which approver gets notified based on what type of request was submitted.
In the form editor, get to the form settings panel on the right side.
Click Advanced logic.
Select the On submit trigger tab.
Click + Add rule.
Set the condition: "Request type" is "Website design".
Set the action: Send email β select your approver email notification template β enter your website design team's email address.
Repeat steps 4β6 for each request type, routing each to the appropriate approver.
βΉοΈ Set up your email templates before or while configuring these rules. You'll need them ready to select: How to create and send custom email templates
Step 3: Create the contract form with e-sign
When the approver updates the request with quote amount, project title, and terms and notes, the client receives an email with a magic link to the contract form so they can review and approve the quote (see the next step to set up email notifications).
Go back to your project, edit the project and type
/formin a new page. Then select + New form. This creates a new form to your existing project.Name your project (e.g., "Quote request form") and click Create.
Open the form. You'll see a default text field already added. Rename it or replace it with the fields below.
Short text: project title, admin-only so the assignee can set a recognizable title on the project. Set the field ID to
project_title. This ID will ensure the value of URL parameterproject_titleis automatically captured by this field.Number: quote amount, admin-only so the assignee can update the request with the offered price. Set the field ID to
quote_amount. This ID will ensure the value of URL parameterquote_amountis automatically captured by this field.Long text: terms and notes, admin-only so the assignee can describe the project quote, timeline, and implementation details. Set the field ID to
terms_notes. This ID will ensure the value of URL parameterterms_notesis automatically captured by this field.Email: requester email. Make it invisible, if it applies to your use case. Set the field ID to
requester_email. This ID will ensure the value of URL parameterrequester_emailis automatically captured by this field.Content: contract approval agreement to write down all the project terms & conditions for the client to review before signing. Use answer piping to pipe the value of fields like
project_title,quote_amount, andterms_notes.Checkbox: I approve this quote and agree to the scope and payment terms
Signature: So the client can sign the contract
Short text: legal name
Date: signing date
Step 4: Configure notifications for approvers and requesters
You need three notifications: one for the approver when a request arrives, one for the requester confirming receipt, and one for the requester when a decision is made.
π₯ Approver notification (already set in step 2)
Make sure your approver email template includes the request type, requester name (@requester_name), request details, and a direct link back to the submission in Formaloo.
βΉοΈ To pull form field values into the email body automatically, use answer piping: How to dynamically pull form data into custom emails, PDFs, and AI prompts
π₯ Requester confirmation (On submit)
Still in Advanced logic β On submit, click + Add rule.
Set the condition so the rule always runs, for example: "Request type" is answered. This way, the rule fires for every submission, as long as the request type is filled (make it a Required field so everyone has to answer it before submission).
Set the action: Send email β select your requester confirmation email template β set the recipient to the requester's email field (with
requester_emailID) value.
π₯ Decision notification (On update)
When an approver updates the status, the requester should hear about it automatically.
Click the On update trigger tab.
Click + Add rule.
Set the condition: "Status" is changed to "Approved". This will only run when the status field is change during the update. If your team changes other fields, but not the status field, this rule will not run.
Set the action: Send email β select your approval email notification template β set the recipient to requester's email field (with
requester_emailID) value.Click + Add rule again and repeat with "Status" is changed to "Rejected" for rejection notifications.
This email template should include a magic link to the "Contract form with e-sign" we built in step 3. To build this magic link, use URL parameters and answer piping.
This magic link will pass all the quote information to the contract form. This way, the contract form can automatically get populated with the quote information. Learn more about automatically populating a form β
Here is the formula to build your contract form URL:
[form-URL]?parameter1=@value1¶meter2=@value2
In our example, it could be:
[form-URL]?project_title=@project_title"e_amount=@quote_amount&terms_notes=@terms_notes&requester_email=@requester_email
Make sure to replace the form's URL in the above formulas.
Step 5: Set up the approval dashboard
Approvers need one place to see every pending request, update the status, and track decisions without digging through email.
Go back to your project, edit the project and organize your pages and data blocks.
Type
/kanbanin a new page. Then select the Kanban data block. A dialog will open allowing you to set up your Kanban board.Select the Quote request form you built in step 1 and choose to group it by the Status field on the form. This will show each and all of the submitted quote requests and will group them by their current status.
Select which fields you want to show on each quote request card in the Kanban board. You can change this later from the board's options.
On a new page, click + Add block and select Table.
Connect the data block to your quote request form.
Configure the view:
Filter by Status = Pending so only active requests appear by default
Add columns for requester name, request type, priority, date submitted, and status. Hide the rest of the columns.
βΉοΈ Optional: Activate a portal on this dashboard so each client logs in to submit their quote requests and sees only the their own requests. See How to create a portal and manage users access for the full setup.
In this case, you can manage access to the pages so clients see their relevant pages and page groups, and your team sees their own relevant pages & page groups.
π‘ If you're sharing this dashboard with external stakeholders, you can set a custom domain on your portal. Available on the Business plan or via the Brand removal add-on.
Step 6: Configure notifications and attach the signed contract document
You can create a customized and smart PDF template and attach it to your email as a final confirmation of the project kick-off. This way, when the client signs the contract form and submits it, both the client and your team receive an email that not only confirms the project kick-off, but also attaches the signed contract as a PDF document to the email.
Edit your contract form and click the Advanced logic β On submit, click + Add rule.
Set the condition so the rule always runs, then set the action: Send email β select your final confirmation email template β set the recipient to the requester's email field (with
requester_emailID) value. You can also send it to the Billing email field available on your contract form.Make sure the email template you're using in this logic has the PDF template attached to it. See how to attach a PDF template to an email template for the full setup.
Step 7: Test the workflow end-to-end
Before sharing the form with your team, run through the complete workflow yourself.
Open your request form and submit a test entry for each request type.
Confirm the approver notification arrives at the correct email for each request type.
Confirm the requester confirmation lands in the email address you used during testing.
Open the approval dashboard and verify the test submission appears with "Pending" status.
Update the status to "Approved" using inline editing.
Confirm the decision notification sends to the requester email with a magic link to the contract form with signature.
Submit the contract form with signature.
Open the approval dashboard and verify the test submission includes the quote information as well.
Confirm the final confirmation lands in the email address you used during testing and has the signed contract PDF attached.
Repeat with "Rejected" to verify that notification too.
Delete your test submissions before sharing the form with your team.
Watch the full workflow built live
We've covered this topic in our webinars live. Watch it here π
What you've built
You now have a complete, automated approval workflow. Requests route to the right approver the moment they're submitted. Every party gets notified at every stage without anyone chasing or following up manually. And every decision lives in one dashboard, searchable, filterable, and ready for audit.
Requests that used to take days bouncing through email threads can now close in hours.
Ready to build this?
π Use this template
Start in minutes with a pre-built version of this workflow.
Our team will help you set this up for your specific use case.
See how teams use Formaloo at scale with advanced permissions and integrations.

