Workflow: Surveys — Feedback Collection
Modules involved: Surveys · Email Lists · Clients · Leads · Staff
Used by: Marketing · Customer Success · HR
Typical duration: Creation + sending = 30 min · Responses = 1–14 days
Overview
The Surveys module enables the creation of questionnaires with 6 question types, sending them via email to recipient lists, and collecting responses via a public link. Sending is 100% manual — there are no automatic triggers on CRM events (invoice paid, ticket closed, project completed).
There is no dedicated NPS type. The closest equivalent is the
ratingtype (1–5 stars), which is not a standard NPS scale (0–10) and does not calculate an NPS score. If you need real NPS, use theratingtype with custom instructions in the question text.
Responses are not linked to CRM records.
tblsurveyresultsetsstores only IP + user agent — no client_id, no lead_id. It is not possible to automatically identify who responded (unless you use custom fields in mail lists or personalized links).
Sending works through the cron. Emails are not sent instantly — they are queued and processed by the cron with a minimum of 1 hour between runs, maximum 100 emails per run.
Flow diagram
[CREATE SURVEY]
│
├── New Survey: subject, description (email body), viewdescription (public header)
├── Add questions: input / textarea / checkbox / radio / rating / progress1
├── Access options: active, onlyforloggedin, iprestrict, redirect_url
└── Public URL generated: site_url/survey/{id}/{hash}
│
↓
[SENDING — manual, staff initiates]
│
├── Surveys → {survey} → Send Survey tab
├── Select recipients (one or more options):
│ ├── All active contacts (with optional client group filter)
│ ├── All leads (with optional lead status filter)
│ ├── All active staff
│ └── Custom Mail Lists
│
├── Insert into tblsurveysemailsendcron (send queue)
├── Insert into tblsurveysendlog: total=0, iscronfinished=0
└── Status: "awaiting cron"
│
↓
[CRON PROCESSING]
│
├── Condition: current time - last_survey_send_cron ≥ 1 hour
├── Sends maximum survey_send_emails_per_cron_run (default 100) emails
├── Each email: replaces {survey_link} with the public URL
│ + custom fields from mail list (e.g.: {list-firstname})
├── On successful send: deletes the row from tblsurveysemailsendcron
└── On completion: tblsurveysendlog.iscronfinished = 1
│
↓
[COMPLETING THE SURVEY — respondent]
│
├── Respondent opens public URL: /survey/{id}/{hash}
├── Fills in the questions
├── On submit:
│ ├── Insert into tblsurveyresultsets: ip, useragent, date (no client_id!)
│ └── Insert into tblform_results: one row per answer (per boxid/boxdescriptionid)
└── Redirect to redirect_url (if configured) or confirmation message
│
↓
[VIEWING RESULTS]
│
├── Surveys → {survey} → Results tab
├── checkbox/radio/rating: progress bars with count and % per option
└── input/textarea/progress1: list of all text responses (modal)
[FEEDBACK COLLECTED ✓]
Step by step
1. Create a survey
Where: /admin/surveys → New Survey
| Field | Description |
|---|---|
subject |
The subject of the sending email |
description |
Email body (supports merge tag {survey_link}) |
viewdescription |
Text displayed in the public survey page header |
active |
1 = publicly visible · 0 = 404 for non-staff |
onlyforloggedin |
If 1, requires an authenticated session (client or staff) |
iprestrict |
If 1, allows only one response per IP address |
redirect_url |
Redirect URL after completion (optional) |
Visual fields (optional):
header_bg, footer_bg, wrapper_color, footer_description — customize the appearance of the public page.
2. Question types
Where: in the survey form → Add Question
Type (boxtype) |
Display | Stored response |
|---|---|---|
input |
Single-line text field | Free text in tblform_results.answer |
textarea |
Multi-line text field | Free text in tblform_results.answer |
checkbox |
Multiple selectable options | boxdescriptionid per selected option |
radio |
Single selectable option | boxdescriptionid of the chosen option |
rating |
5 stars (Bad / Good / Very good / Great / Awesome) | boxdescriptionid with value 1–5 |
progress1 |
Slider 0–100 | Numeric value in answer |
Type
progress2(numeric progress bars) is disabled in the interface (the PHP code for the add button is commented out). It cannot be added by staff.
Fields per question:
question— question textrequired—1= required for submitquestion_order— display order
3. Mail Lists — custom recipient lists
Where: /admin/surveys → Mail Lists → New List
Mail Lists allow sending to email addresses that are not necessarily contacts or leads in the CRM.
| Field | Description |
|---|---|
name |
List name |
| Emails | Individual addition or CSV import |
| Custom Fields | Additional fields per email (e.g.: First Name, Company) — usable as merge tags in email with syntax {list-name-fieldname} |
4. Send a survey
Where: /admin/surveys/{id} → tab Send Survey
Available recipients:
| Option | Optional filter | GDPR filtered? |
|---|---|---|
| All active contacts | Client group | Yes (if GDPR active) |
| All leads | Lead status | Yes (if GDPR active) |
| All active staff | — | No |
| Mail Lists | Select specific lists | No |
Required merge tag: Include
{survey_link}in thedescriptionfield (email body). Without it, the email does not contain the link to the survey.
Configure send volume:
Where: /admin/settings → Cron tab → Surveys
| Option | Default | Description |
|---|---|---|
survey_send_emails_per_cron_run |
100 | Emails sent per cron execution |
The minimum interval between cron runs is 1 hour (last_survey_send_cron option updated on each run).
5. View results
Where: /admin/surveys/{id} → tab Results
For checkbox, radio, rating:
- Each option displays: vote count / total completions = percentage
- Progress bar visualizes the distribution
For input, textarea, progress1:
- View All Answers button → modal with the list of all text responses
Important limitations:
- No CSV/Excel export of responses
- No trend analysis over time
- No cross-survey comparison
- No NPS calculation (even if using rating 1–5)
- Responses are not associated with client_id or lead_id
6. Available automations (limited)
The Surveys module has no integration with:
workflow_automation(no triggers on CRM events)ma(Marketing Automation)- Any other CRM hook (invoice paid, ticket closed, etc.)
The only existing automation: the send cron (processing the tblsurveysemailsendcron queue).
Required permissions
| Permission | Access |
|---|---|
surveys → view |
View surveys and results |
surveys → create |
Create new surveys |
surveys → edit |
Edit existing surveys |
surveys → delete |
Delete |
| Cron volume configuration | is_admin() |
Gotchas
| Problem | Cause | Solution |
|---|---|---|
| Emails not sending | Cron inactive or 1h interval not met | Verify the cron job is running + wait at least 1 hour |
| Survey shows 404 | active = 0 |
Set active = 1 on the survey |
| No link in email | {survey_link} absent from description |
Add the merge tag to the email body |
| Don't know who responded | tblsurveyresultsets does not store client_id |
Use mail lists with custom fields + ask for email in the survey |
| "Rating" is not real NPS | Rating is 1–5 stars, not 0–10 | Explicitly document the scale in the question text; calculate NPS manually from export |
| Cron sends fewer than 100 / run | survey_send_emails_per_cron_run = smaller value |
Adjust in Settings → Cron → Surveys |
Module references
- Clients — sending to contacts
- Leads — sending to leads
- Marketing Campaigns — email campaigns (for automated emails)
- GDPR — consent filtering on send
Schedule post-event surveys to send automatically at a fixed interval (e.g. 3 days after ticket resolution, 14 days after onboarding) — configure the trigger in survey settings so response timing is consistent without manual sending for every event.
Each survey recipient gets a unique participation link that requires no login. Responses are linked automatically to their CRM client or lead record, enabling segmented analysis by industry, tier, or product without manual data matching.