Everything you need to install, set up and run Formlane, the self-hosted PHP form builder. Want to see it first? Open the live demo.
Contents
- Requirements
- Installation
- Cron job
- First steps
- Building a form
- Putting a form on your website
- Answers
- Emails
- Spam protection
- Webhooks
- Team and roles
- Licence and updates
- Backups and moving
- Troubleshooting
Requirements
- PHP 8.3 or newer with the extensions
pdo,mbstring,openssl,curl,json,tokenizer,xml,ctype,fileinfoandzip. - A database: MySQL 8 or MariaDB 10.6+ (an empty database and its user), or SQLite for small sites (nothing to create).
- A domain or subdomain with HTTPS.
- A way to run a task every minute: a cron line, or a web cron calling a secret address.
The installer checks all of this and shows in red what is missing.
Installation
- Create the site in your hosting panel and point its document root to the
publicfolder of Formlane. If your host does not let you choose the document root, upload Formlane into the site folder anyway: the.htaccessfile at the root sends visitors topublicand blocks the private files. - MySQL only: create an empty database and a user with all rights on it.
- Upload the zip into the site folder and extract it. The
storageandbootstrap/cachefolders and the.envfile must be writable by PHP (most shared hosts already allow this). For SQLite, thedatabasefolder must be writable too. - Open
https://your-site.com/installand fill in the form: name, address, database and your owner account. The installer creates the tables, then locks itself for good. - Add the cron job shown at the end of the installer (see below).
Cron job
Formlane sends emails and webhooks, retries failed calls, checks for updates and deletes old answers in the background. Add one of these two lines in your hosting panel, to run every minute. Both are shown in Settings → Cron job with your real path and key.
* * * * * php /path/to/formlane/artisan formlane:cron >> /dev/null 2>&1
If your host has no command line, call this address every minute with its web cron (or a free service such as cron-job.org):
https://your-site.com/cron/YOURKEY
Settings shows when the cron last ran. New cron URL makes a new key; the old address stops working.
First steps
- My account: turn on two-factor sign-in.
- Licence & updates: enter your licence key (copies bought on the Aluleth Market). Copies bought on a marketplace update by uploading the new zip on the same page.
- Team: add the people who work with you (see Team and roles).
- Settings: name of the installation, default language, time zone, sending emails, spam protection.
Building a form
In Forms → New form, start from one of the 31 ready-made forms (try any of them first) or from a blank form. Then:
- Build: click or drag a field from the palette, drag fields to reorder them, put two fields side by side (half width), and split the form into steps. The panel on the right sets the label, help text, placeholder, required, choices, limits, file types and size, a default value, and the key used in exports and webhooks. Ctrl+Z undoes, Ctrl+S saves.
- Rules: in a field’s panel, Show or hide makes it appear only for some answers (is, is not, contains, is empty, more than…). Rules can only use fields placed before, and hidden fields are never required nor saved.
- Design: pick one of 12 looks, then change colors, font, corners, field and button styles, width and logo. The preview shows computer and phone width.
- Settings: language of the form (buttons and error messages), button texts, progress bar, message or page after sending, closed message, limits (number of answers, closing date), keeping IP addresses, automatic deletion of old answers.
- Publish the form when it is ready; drafts can only be previewed.
Putting a form on your website
Each form has three ways, in its Share tab:
- Code for your website (best): paste it where the form should appear. WordPress: a Custom HTML block. Elementor: the HTML widget. Webflow, Wix and others: their embed or HTML element. The form takes the height it needs, and the parameters of the page address (for example
?utm_source=newsletter) fill the hidden fields that use them. - Link: a page with only the form, to share by email or on social media.
- Iframe: for sites that refuse scripts; you set the height.
<div data-formlane="FORM-ID"></div>
<script src="https://your-site.com/embed.js" async></script>
Answers
- The Answers tab shows views, answers and the answer rate over 30 days, a chart per day, and the list with search, dates and unread filter. Select several answers to mark them read or unread, or delete them.
- Each answer shows the page it was sent from, its language, the browser and, if you keep it, the IP address. Uploaded files are stored outside the public folder and download only from the admin.
- Export CSV exports the answers shown (with the filters applied): one line per answer, one column per field, then one column for each field renamed or deleted since (“Field deleted since”). The file opens cleanly in Excel, accents included.
- Export CSV, one line per value gives one line for each answer value (number, date, field, answer), so any number of fields fits. Use it when the usual export would have more columns than a spreadsheet opens: Formlane then tells you so instead of making it.
- Files sent to an upload field that was renamed or deleted since stay downloadable from the answer.
- If you delete a field and later give a new field the same key, even with another type, the answers sent before keep reading the way they were sent: a text stays a text, files stay files, Yes/No and stars only where they apply.
Emails
Set up sending first: Settings → Sending emails. Choose SMTP server and enter the details of a mailbox, usually found in your hosting panel under “Email accounts”: server, port (465 with SSL or 587 with TLS), user name and password. Use a sender address of your own domain, then click Send a test email to me. Until this is set up, emails are only written to storage/logs.
Then, in each form’s Emails tab:
- Email to your team: sent for each answer, to the owners or the addresses you enter. Reply goes to the person, so you answer them straight from your mailbox.
- Confirmation to the person: sent to the address typed in the form (the form needs an Email field), in the language of the form, with an optional copy of the answers.
Subjects and messages can use these tags:
| Tag | Replaced by |
|---|---|
{field_key} | The answer to that field, for example {name} or {email} |
{all_fields} | All the answers, as a list |
{form_title} | The name of the form |
{answer_number} | The number of the answer |
{site_name} | The name of the installation |
Spam protection
Every form already stops most robots on its own: a hidden field, a time check, a signed page and limits per visitor (10 answers a minute, 60 an hour). For a form that still gets spam, add a captcha:
- Create a site in Cloudflare Turnstile (free, asks nothing to most people), hCaptcha or reCAPTCHA v2.
- Paste its site key and secret key in Settings → Spam protection.
- Tick Ask for a captcha in the settings of the forms that need it.
Webhooks
A webhook sends each new answer as JSON to another app: Zapier, Make, n8n or your own. In a form’s Settings → Webhooks, paste the address your app gives you (up to 5 per form). Send a test sends the latest answer. Failed calls are tried again after 1, 5 and 30 minutes, and the last calls are listed with their result.
Example of what your app receives:
{
"event": "answer.created",
"form": { "id": 2, "public_id": "quote", "title": "Quote request" },
"answer": {
"id": 374,
"created_at": "2026-10-25T03:38:50+00:00",
"data": { "name": "Hana Dubois", "email": "hana@example.com", "budget": "5,000 – 15,000" },
"labels": { "name": "Your name", "email": "Email", "budget": "Budget" },
"page": "https://your-website.com/services/",
"language": "en",
"admin_url": "https://forms.your-site.com/admin/forms/2/answers/374"
}
}
A test call has "event": "test". Each call carries the headers X-Formlane-Event and X-Formlane-Signature: sha256=<HMAC-SHA256 of the raw body with the webhook secret>. The secret is shown under Signature secret. To check the signature in PHP:
$body = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $body, 'YOUR_SECRET');
if (! hash_equals($expected, $_SERVER['HTTP_X_FORMLANE_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
$answer = json_decode($body, true);
Addresses inside your own network (localhost, 10.x, 192.168.x…) are refused, so a form cannot be used to reach private services. To allow them, add FORMLANE_PRIVATE_WEBHOOKS=true to the .env file.
Team and roles
| Role | Can do |
|---|---|
| Owner | Everything, including licence, updates and other owners |
| Admin | Everything except licence, updates and owners |
| Editor | Create and change forms, read and manage answers |
| Viewer | Read answers |
Each person chooses their language in My account (English, French, Spanish, German, Portuguese or Tagalog) and can turn on two-factor sign-in.
Licence and updates
- Bought on the Aluleth Market: enter your licence key in Licence & updates. New versions then install in one click. A Standard licence covers one domain, Agency covers ten. To move a licence, deactivate it on the old site first.
- Bought on a marketplace: download the new full zip and use Update from a zip on the same page.
- If the server refuses the upload (the zip is about 18 MB and some hosts allow less): extract it on your computer and upload its files over the old ones by FTP, keeping your
.envfile andstoragefolder. Database changes apply on the next visit.
Before copying, Formlane checks the zip and saves the files it replaces in storage/app/updates (the 3 newest backups are kept). Your .env file, storage folder and database are never replaced. After 12 months Formlane keeps working; you only need a new licence for new versions and support.
Backups and moving
- Back up the database (or the SQLite file in
database), the.envfile and thestoragefolder. The.envfile holds the encryption key of the installation: without it, saved passwords (SMTP, captcha) cannot be read. - To move to another server, copy the whole folder and the database, then update
APP_URLand the database details in.env.
Troubleshooting
| Problem | What to do |
|---|---|
| Settings says the cron job never ran | Add the cron line or web cron (see Cron job), then wait one minute. |
| Emails do not arrive | Send a test from Settings. Check the spam folder, use a sender address of your own domain, and ask your host for the right port and security (SSL 465 or TLS 587). |
| Blank page or error 500 | Check that PHP is 8.3 or newer and that storage, bootstrap/cache and .env are writable. Details are in storage/logs. |
| Locked out and no email set up | On the server, run php artisan formlane:reset-password you@example.com: it prints a new password and turns off two-factor sign-in for that account. |
| Where is the admin? | At /admin. Change it with FORMLANE_ADMIN_PATH= in .env. |
| A webhook says “Address refused” | The address points inside your server network; see Webhooks. |
Still stuck? Write to us from the Support page with your order number.