FormVox stores all form data in .fvform files using JSON format. This document describes the complete schema.
Overview
A .fvform file contains:
1. Form metadata - Title, settings, timestamps
2. Questions - All form questions with their settings
3. Responses - All submitted responses
{
"version": "1.0",
"form": { ... },
"questions": [ ... ],
"responses": [ ... ]
}
Complete Schema
Root Object
| Field |
Type |
Required |
Description |
version |
string |
Yes |
Schema version (currently "1.0") |
form |
object |
Yes |
Form metadata |
questions |
array |
Yes |
Array of question objects |
responses |
array |
Yes |
Array of response objects |
{
"form": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Customer Feedback Survey",
"description": "Help us improve our service",
"created": "2024-01-15T10:00:00Z",
"modified": "2024-01-15T14:30:00Z",
"owner": "admin",
"settings": { ... },
"branding": { ... }
}
}
| Field |
Type |
Required |
Description |
id |
string |
Yes |
UUID of the form |
title |
string |
Yes |
Form title |
description |
string |
No |
Optional description |
created |
string |
Yes |
ISO 8601 timestamp |
modified |
string |
Yes |
ISO 8601 timestamp |
owner |
string |
Yes |
Nextcloud user ID |
settings |
object |
No |
Form settings |
branding |
object |
No |
Visual customization |
Settings Object
{
"settings": {
"isPublic": true,
"publicHash": "abc123def456",
"password": null,
"expiresAt": "2024-02-15T23:59:59Z",
"allowMultiple": false,
"showProgress": true,
"confirmationMessage": "Thank you for your response!",
"quizMode": false,
"restrictedUsers": [],
"restrictedGroups": []
}
}
| Field |
Type |
Default |
Description |
isPublic |
boolean |
false |
Enable public access |
publicHash |
string |
null |
Unique hash for public URL |
password |
string |
null |
Hashed password (bcrypt) |
expiresAt |
string |
null |
ISO 8601 expiration |
allowMultiple |
boolean |
true |
Allow multiple submissions |
showProgress |
boolean |
true |
Show progress bar |
confirmationMessage |
string |
null |
Custom confirmation |
quizMode |
boolean |
false |
Enable quiz scoring |
restrictedUsers |
array |
[] |
Allowed user IDs |
restrictedGroups |
array |
[] |
Allowed group IDs |
Branding Object
{
"branding": {
"headerImage": "https://example.com/logo.png",
"backgroundColor": "#ffffff",
"accentColor": "#0082c9",
"customCss": null
}
}
Question Object
{
"questions": [
{
"id": "q1",
"type": "text",
"title": "What is your name?",
"description": "Please enter your full name",
"required": true,
"order": 1,
"page": 0,
"options": { ... },
"conditions": [ ... ],
"quiz": { ... }
}
]
}
| Field |
Type |
Required |
Description |
id |
string |
Yes |
Unique question ID |
type |
string |
Yes |
Question type |
title |
string |
Yes |
Question text |
description |
string |
No |
Helper text |
required |
boolean |
No |
Is answer required |
order |
number |
Yes |
Display order |
page |
number |
No |
Page index (default 0) |
options |
object |
No |
Type-specific options |
conditions |
array |
No |
Conditional logic rules |
quiz |
object |
No |
Quiz mode settings |
Question Types
Text Types
// text
{ "type": "text", "options": { "placeholder": "Enter text...", "maxLength": 100 } }
// email
{ "type": "email", "options": { "placeholder": "email@example.com" } }
// textarea
{ "type": "textarea", "options": { "rows": 4, "maxLength": 1000 } }
Choice Types
// single_choice
{
"type": "single_choice",
"options": {
"choices": [
{ "id": "c1", "label": "Option A", "value": "a" },
{ "id": "c2", "label": "Option B", "value": "b" }
],
"allowOther": true,
"randomize": false
}
}
// multiple_choice
{
"type": "multiple_choice",
"options": {
"choices": [ ... ],
"minSelections": 1,
"maxSelections": 3
}
}
// dropdown
{
"type": "dropdown",
"options": {
"choices": [ ... ],
"placeholder": "Select an option..."
}
}
Date/Time Types
// date
{ "type": "date", "options": { "minDate": "2024-01-01", "maxDate": "2024-12-31" } }
// time
{ "type": "time", "options": { "format": "24h" } }
// datetime
{ "type": "datetime", "options": { ... } }
Rating Types
// linear_scale
{
"type": "linear_scale",
"options": {
"min": 1,
"max": 10,
"minLabel": "Not satisfied",
"maxLabel": "Very satisfied"
}
}
// rating
{
"type": "rating",
"options": {
"maxStars": 5
}
}
Matrix Type
{
"type": "matrix",
"options": {
"rows": [
{ "id": "r1", "label": "Quality" },
{ "id": "r2", "label": "Price" }
],
"columns": [
{ "id": "c1", "label": "Poor" },
{ "id": "c2", "label": "Average" },
{ "id": "c3", "label": "Excellent" }
],
"multiplePerRow": false
}
}
Conditions Array
{
"conditions": [
{
"questionId": "q1",
"operator": "equals",
"value": "yes",
"logic": "and"
}
]
}
| Operator |
Description |
equals |
Exact match |
not_equals |
Not equal |
contains |
Contains substring |
greater_than |
Numeric comparison |
less_than |
Numeric comparison |
is_empty |
Field is empty |
is_not_empty |
Field has value |
Quiz Object
{
"quiz": {
"correctAnswer": "c1",
"points": 10,
"feedback": {
"correct": "Well done!",
"incorrect": "The correct answer is Option A"
}
}
}
Response Object
{
"responses": [
{
"id": "r1",
"submitted": "2024-01-15T11:30:00Z",
"ip": null,
"userAgent": "Mozilla/5.0...",
"userId": null,
"answers": {
"q1": "John Doe",
"q2": ["c1", "c2"],
"q3": { "r1": "c2", "r2": "c3" }
},
"metadata": {
"duration": 120,
"score": 85
}
}
]
}
| Field |
Type |
Description |
id |
string |
Unique response ID |
submitted |
string |
ISO 8601 timestamp |
ip |
string |
IP address (if stored) |
userAgent |
string |
Browser user agent |
userId |
string |
Nextcloud user (if logged in) |
answers |
object |
Question ID → answer mapping |
metadata |
object |
Additional data |
| Question Type |
Answer Format |
| text, email, textarea |
"string value" |
| single_choice, dropdown |
"choice_id" |
| multiple_choice |
["c1", "c2"] |
| date |
"2024-01-15" |
| time |
"14:30" |
| datetime |
"2024-01-15T14:30:00" |
| linear_scale, rating |
5 (number) |
| matrix |
{ "row_id": "column_id" } |
Example Complete File
{
"version": "1.0",
"form": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Customer Feedback",
"description": "Please share your experience",
"created": "2024-01-15T10:00:00Z",
"modified": "2024-01-15T14:30:00Z",
"owner": "admin",
"settings": {
"isPublic": true,
"publicHash": "abc123",
"quizMode": false
}
},
"questions": [
{
"id": "q1",
"type": "text",
"title": "Your name",
"required": true,
"order": 1
},
{
"id": "q2",
"type": "linear_scale",
"title": "How satisfied are you?",
"required": true,
"order": 2,
"options": {
"min": 1,
"max": 5,
"minLabel": "Not at all",
"maxLabel": "Very satisfied"
}
}
],
"responses": [
{
"id": "r1",
"submitted": "2024-01-15T11:30:00Z",
"answers": {
"q1": "Jane Smith",
"q2": 4
}
}
]
}
Versioning
The version field indicates the schema version:
| Version |
Changes |
| 1.0 |
Initial release |
Future versions will maintain backwards compatibility where possible.
Next Steps