Post /surveys/{{survey-id}}/submit-page
This functionality is currently released in ALPHA and under testing. BETA release is expected in April 2026.

Example Request

https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page

The value of environment {{env}} variable depends upon your datacenter. Refer to the Environment page for more details.


Submits the respondent's answers for the current page and returns the next page (or a final status). The request body is a flat JSON object whose keys are derived directly from the formParam metadata embedded in each question's JSON on the previous GET /take response.


Send the x-survey-token received from the last GET /take or Post /submit-page or GET /previous-page response. The server returns a refreshed token in every response — always use the latest token on the next call.


Authorization

arrow_rightSession Token — x-survey-token
Name : x-survey-token
required
Location : Request Header
Type : string
Description : Signed session token obtained from the x-survey-token response header of the previous GET /take or POST /submit-page or GET /previous-page call. Echo it back verbatim. The server returns a refreshed token in the response header — always use the latest token on subsequent requests.
arrow_rightSecurity - API Key
Name : api-key
required
Location : Request Header
Type : string

Request Parameters

arrow_rightPath Parameters
survey-id integer
required

Request Body

arrow_rightFlat formParam JSON object
Content-Type: application/json
The body is a flat JSON object. Each key is constructed from the formParam metadata found in the questions[].json field of the GET /take response.
Key construction rule: {paramPrefix} + {questionId or answerId depending on paramIdType}
UniChoice (paramPrefix=u_, paramIdType=questionId): u_{questionId} = {answerId}
MultiChoice (paramPrefix=m_, paramIdType=questionId): m_{questionId} = [{answerId1}, {answerId2}]
Text / Open-ended (paramPrefix=t_, paramIdType=answerId): t_{answerId} = free text value
Rank Order (paramPrefix=r_, paramIdType=answerId): r_{answerId} = {rank position integer}
Constant Sum (paramPrefix=s_, paramIdType=answerId): s_{answerId} = {numeric value}
Date (day/month/year): dt_day_{answerId}, dt_month_{answerId}, dt_year_{answerId}
Date+Time: additionally dt_hr_{answerId}, dt_min_{answerId}, dt_ampm_{answerId}
Calendar: dt_cal_{answerId} = YYYY-MM-DD
Other option text (otherParamPrefix=t_, otherParamIdType=answerId): t_{otherAnswerId} = other text
arrow_rightExample — UniChoice
application/json

{
  "u_10001": "50002"
}
            
arrow_rightExample — MultiChoice
application/json

{
  "m_10002": ["60001", "60003"]
}
            
arrow_rightExample — Text / Open-ended
application/json

{
  "t_70001": "This is my open-ended response"
}
            
arrow_rightExample — UniChoice with Other option
application/json

{
  "u_10001": "50099",
  "t_50099": "Other — please specify: My custom answer"
}
            
arrow_rightExample — Rank Order
application/json

{
  "r_60001": "1",
  "r_60002": "3",
  "r_60003": "2"
}
            
arrow_rightExample — Constant Sum
application/json

{
  "s_80001": "40",
  "s_80002": "35",
  "s_80003": "25"
}
            
arrow_rightExample — Date (day/month/year)
application/json

{
  "dt_day_90001":   "15",
  "dt_month_90001": "6",
  "dt_year_90001":  "2024"
}
            
arrow_rightExample — DateTime (date + time)
application/json

{
  "dt_day_90001":   "15",
  "dt_month_90001": "6",
  "dt_year_90001":  "2024",
  "dt_hr_90001":    "10",
  "dt_min_90001":   "30",
  "dt_ampm_90001":  "AM"
}
            
arrow_rightExample — Calendar
application/json

{
  "dt_cal_90002": "2024-06-15"
}
            
arrow_rightExample — Matrix UniChoice (one entry per row)
application/json

{
  "u_10010": "20001",
  "u_10011": "20003",
  "u_10012": "20002"
}
            
arrow_rightExample — Matrix MultiChoice (one entry per row)
application/json

{
  "m_10010": ["20001", "20002"],
  "m_10011": ["20003"]
}
            
arrow_rightExample — Multi-question page (mixed types)
application/json

{
  "u_10001":        "50002",
  "m_10002":        ["60001", "60003"],
  "t_70001":        "Additional comments here",
  "t_80001":        "My name",
  "t_80002":        "[email protected]",
  "r_60001":        "1",
  "r_60002":        "2",
  "s_80010":        "50",
  "s_80011":        "30",
  "s_80012":        "20",
  "dt_day_90001":   "15",
  "dt_month_90001": "6",
  "dt_year_90001":  "2024"
}
            

Example Code

arrow_rightcURL — UniChoice answer
Snippet copied successfully.
application/json

curl --location 'https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'api-key: {{api-key}}' \
  --header 'x-survey-token: {{x-survey-token}}' \
  --data '{
  "u_10001": "50002"
}'
            
arrow_rightcURL — MultiChoice answer
Snippet copied successfully.
application/json

curl --location 'https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'api-key: {{api-key}}' \
  --header 'x-survey-token: {{x-survey-token}}' \
  --data '{
  "m_10002": ["60001", "60003"]
}'
            
arrow_rightcURL — Text (open-ended) answer
Snippet copied successfully.
application/json

curl --location 'https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'api-key: {{api-key}}' \
  --header 'x-survey-token: {{x-survey-token}}' \
  --data '{
  "t_70001": "This is my open-ended response"
}'
            
arrow_rightcURL — Multi-question page (mixed types)
Snippet copied successfully.
application/json

curl --location 'https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'api-key: {{api-key}}' \
  --header 'x-survey-token: {{x-survey-token}}' \
  --data '{
  "u_10001": "50002",
  "m_10002": ["60001", "60003"],
  "t_70001": "Additional comments here",
  "t_80001": "My name",
  "t_80002": "[email protected]"
}'
            
arrow_rightcURL — UniChoice with Other option
Snippet copied successfully.
application/json

curl --location 'https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'api-key: {{api-key}}' \
  --header 'x-survey-token: {{x-survey-token}}' \
  --data '{
  "u_10001": "50099",
  "t_50099": "Other — please specify: My custom answer"
}'
            
arrow_rightcURL — DateTime answer
Snippet copied successfully.
application/json

curl --location 'https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'api-key: {{api-key}}' \
  --header 'x-survey-token: {{x-survey-token}}' \
  --data '{
  "dt_day_90001":   "15",
  "dt_month_90001": "6",
  "dt_year_90001":  "2024",
  "dt_hr_90001":    "10",
  "dt_min_90001":   "30",
  "dt_ampm_90001":  "AM"
}'
            
arrow_rightcURL — Rank Order answer
Snippet copied successfully.
application/json

curl --location 'https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'api-key: {{api-key}}' \
  --header 'x-survey-token: {{x-survey-token}}' \
  --data '{
  "r_60001": "1",
  "r_60002": "3",
  "r_60003": "2"
}'
            
arrow_rightPython
Snippet copied successfully.
application/json

import requests

url = "https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page"

headers = {
    "Content-Type": "application/json",
    "Accept":        "application/json",
    "api-key":       "{{api-key}}",
    "x-survey-token": session_token  #  token from the GET /take response header
}

#  Flat param object — keys come from formParam metadata in the GET /take response
payload = {
    "u_10001": "50002",         #  UniChoice: u_{questionId} = {answerId}
    "t_70001": "Great service!" #  Text:      t_{answerId}  = free text
}

response = requests.post(url, json=payload, headers=headers)
data = response.json()

#  Refresh the token from the response header — use on next call
session_token = response.headers.get("x-survey-token")
            
arrow_rightPHP - cURL
Snippet copied successfully.
application/json

<?php

$payload = json_encode([
    "u_10001" => "50002",
    "t_70001"  => "Great service!"
]);

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL            => 'https://api.questionpro.{{env}}/a/api/v2/surveys/{{survey-id}}/submit-page',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER         => true,
    CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST  => 'POST',
    CURLOPT_POSTFIELDS     => $payload,
    CURLOPT_HTTPHEADER     => array(
        'Content-Type: application/json',
        'Accept: application/json',
        'api-key: {{api-key}}',
        'x-survey-token: ' . $sessionToken
    ),
));

$response   = curl_exec($curl);
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$headersRaw = substr($response, 0, $headerSize);
$body       = substr($response, $headerSize);
curl_close($curl);

// Refresh the session token for the next request
preg_match('/x-survey-token:\s*(\S+)/i', $headersRaw, $m);
$sessionToken = $m[1] ?? null;

echo $body;
            

Responses

arrow_right200 OK — Next page loaded (success)
application/json

// Response header returned by the server (echo this back on the next request):
// x-survey-token: eyJ1dWlkIjoiYWJjMTIzIiwicnMiOjEyMzQ1NiwiaW5zIjoiIiwic2VjIjpbXX0.HMAC_SIGNATURE

{
  "response": {
    "status": "success",
    "meta": {
      "isFinalPage": false,
      "progressPercentage": 50
    },
    "navigation": {
      "previousPageUrl": "/a/api/v2/surveys/123456/previous-page",
      "nextPageSubmitUrl": "/a/api/v2/surveys/123456/submit-page"
    },
    "themeConfig": {
      "cssUrls": ["https://cdn.questionpro.com/themes/corporate.css"],
      "jsUrls": []
    },
    "questions": [
      {
        "html": "<div class='qstn-row'>...rendered HTML...</div>",
        "json": {
          "id": 10002,
          "type": "M",
          "text": "Which features do you use?",
          "answers": [
            { "id": 60001, "text": "Dashboard" },
            { "id": 60002, "text": "Reports" },
            { "id": 60003, "text": "Integrations" }
          ],
          "formParam": {
            "paramPrefix": "m_",
            "paramIdType": "questionId"
          }
        }
      }
    ]
  },
  "requestID": "9023abcd-f9df-59bf-c900-7r6df398098b"
}
                
arrow_right200 OK — Validation errors (same page re-shown)
application/json

{
  "response": {
    "status": "validation_errors",
    "meta": {
      "isFinalPage": false,
      "progressPercentage": 0
    },
    "navigation": {
      "previousPageUrl": null,
      "nextPageSubmitUrl": "/a/api/v2/surveys/123456/submit-page"
    },
    "themeConfig": {
      "cssUrls": ["https://cdn.questionpro.com/themes/corporate.css"],
      "jsUrls": []
    },
    "questions": [
      {
        "html": "<div class='qstn-row'>...rendered HTML...</div>",
        "json": {
          "id": 10001,
          "type": "U",
          "text": "How satisfied are you?",
          "answers": [],
          "formParam": {
            "paramPrefix": "u_",
            "paramIdType": "questionId"
          }
        }
      }
    ],
    "validationErrors": [
      {
        "questionId": 10001,
        "message": "This question is required.",
        "answerErrors": null
      }
    ]
  },
  "requestID": "9023abcd-f9df-59bf-c900-7r6df398098b"
}
                
arrow_right200 OK — Final page (isFinalPage=true)
application/json

{
  "response": {
    "status": "success",
    "meta": {
      "isFinalPage": true,
      "progressPercentage": 90
    },
    "navigation": {
      "previousPageUrl": "/a/api/v2/surveys/123456/previous-page",
      "nextPageSubmitUrl": "/a/api/v2/surveys/123456/submit-page"
    },
    "themeConfig": {
      "cssUrls": [],
      "jsUrls": []
    },
    "questions": [
      {
        "html": "<div class='qstn-row'>...last page question HTML...</div>",
        "json": {
          "id": 10099,
          "type": "T",
          "text": "Any final comments?",
          "answers": [{ "id": 99001 }],
          "formParam": {
            "paramPrefix": "t_",
            "paramIdType": "answerId"
          }
        }
      }
    ]
  },
  "requestID": "9023abcd-f9df-59bf-c900-7r6df398098b"
}
                
arrow_right200 OK — Survey complete (no redirect)
application/json

{
  "response": {
    "status": "survey_complete"
  },
  "requestID": "9023abcd-f9df-59bf-c900-7r6df398098b"
}
                
arrow_right200 OK — Survey complete with redirect (chain survey or panel)
application/json

{
  "response": {
    "status": "survey_complete",
    "redirectUrl": "https://www.questionpro.com/a/TakeSurvey?tt=abc123"
  },
  "requestID": "9023abcd-f9df-59bf-c900-7r6df398098b"
}
                
arrow_right200 OK — Terminated (data quality or screener)
application/json

{
  "response": {
    "status": "terminated"
  },
  "requestID": "9023abcd-f9df-59bf-c900-7r6df398098b"
}
                
arrow_right200 OK — Terminated with redirect (panel redirect)
application/json

{
  "response": {
    "status": "terminated",
    "redirectUrl": "https://panel.example.com/complete?status=disqualified&ref=456"
  },
  "requestID": "9023abcd-f9df-59bf-c900-7r6df398098b"
}
                
arrow_rightSchema
application/json

// Response header on every call:
// x-survey-token: <signed-token>  — always present; echo back verbatim on the next request

{
  "response": {
    "status": "string — one of: success | validation_errors | survey_complete | terminated |
               authentication_required | already_completed | quota_full |
               survey_closed | survey_paused | survey_suspended |
               language_selection_required | survey_opt_out | redirect | error",
    "redirectUrl": "string | null — present when status is survey_complete, terminated,
                   or redirect; URL to navigate the respondent to (chain survey,
                   panel redirect, or thank-you page)",
    "meta": {
      "isFinalPage": "boolean — true when this is the last page of the survey",
      "progressPercentage": "integer (0–100) — completion progress"
    },
    "navigation": {
      "previousPageUrl": "string | null — null on the first page",
      "nextPageSubmitUrl": "string — URL to POST the next set of answers to"
    },
    "themeConfig": {
      "cssUrls": "array of string — stylesheet URLs for the survey theme",
      "jsUrls": "array of string — JavaScript URLs for the survey theme"
    },
    "questions": [
      {
        "html": "string | null — pre-rendered HTML for the question row",
        "json": "string — JSON-encoded section object with question details and formParam metadata"
      }
    ],
    "validationErrors": [
      {
        "questionId": "integer — ID of the question that failed validation",
        "message": "string — human-readable error message",
        "answerErrors": "object | null — per-answer error map for matrix/battery questions; keys are answerId strings"
      }
    ]
  },
  "requestID": "string — unique request identifier"
}
                
arrow_right400 — Session expired or missing body
application/json

{
    "response": {
     "error": {
         "docs": www.questionpro.com/api/error-codes.html
         "name": "BAD_REQUEST",
         "httpStatusCode": 400,
         "id" : "1000",
         "message": "Invalid URL parameters",
         "resourceUrl":"resource_url"
        }
    }
}
                                
arrow_rightSchema
application/json

{
  "$schema": "http://json-schema.org/draft-06/schema#                                      ",
  "type": "object",
  "properties": {
    "response": {
      "type": "object",
      "properties": {
        "error": {
          "type": "object",
          "properties": {
            "docs": {
              "type": "string"
            },
            "resourceUrl": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "message": {
              "type": "string"
            },
            "httpStatusCode": {
              "type": "integer"
            }
          },
          "additionalProperties": false,
          "required": [
            "docs",
            "resourceUrl",
            "name",
            "id",
            "message",
            "httpStatusCode"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "error"
      ]
    }
  },
  "additionalProperties": false,
  "required": [
    "response"
  ]
}
                                
arrow_right400 Bad Request Example
application/json

{
  "error": {
    "code": 1002,
    "message": "Session expired. Please load the survey page before submitting."
  },
  "requestID": "9023abcd-f9df-59bf-c900-7r6df398098b"
}
                
arrow_right400 example
application/json

{
    "response": {
     "error": {
         "docs": www.questionpro.com/api/error-codes.html
         "name": "BAD_REQUEST",
         "httpStatusCode": 400,
         "id" : "1000",
         "message": "Invalid URL parameters",
         "resourceUrl":"resource_url"
        }
    }
}
                                
arrow_rightSchema
application/json

{
  "$schema": "http://json-schema.org/draft-06/schema#                                      ",
  "type": "object",
  "properties": {
    "response": {
      "type": "object",
      "properties": {
        "error": {
          "type": "object",
          "properties": {
            "docs": {
              "type": "string"
            },
            "resourceUrl": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "message": {
              "type": "string"
            },
            "httpStatusCode": {
              "type": "integer"
            }
          },
          "additionalProperties": false,
          "required": [
            "docs",
            "resourceUrl",
            "name",
            "id",
            "message",
            "httpStatusCode"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "error"
      ]
    }
  },
  "additionalProperties": false,
  "required": [
    "response"
  ]
}
                                
arrow_right401 example
application/json

{
    "response": {
     "error": {
         "docs": www.questionpro.com/api/error-codes.html
         "name": "UNAUTHORIZED",
         "httpStatusCode": 401,
         "id" : "1010",
         "message": "Incorrect API Key",
         "resourceUrl":"resource_url"
        }
    }
}
						
							
arrow_rightSchema
application/json

{
  "$schema": "http://json-schema.org/draft-06/schema#                                      ",
  "type": "object",
  "properties": {
    "response": {
      "type": "object",
      "properties": {
        "error": {
          "type": "object",
          "properties": {
            "docs": {
              "type": "string"
            },
            "resourceUrl": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "message": {
              "type": "string"
            },
            "httpStatusCode": {
              "type": "integer"
            }
          },
          "additionalProperties": false,
          "required": [
            "docs",
            "resourceUrl",
            "name",
            "id",
            "message",
            "httpStatusCode"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "error"
      ]
    }
  },
  "additionalProperties": false,
  "required": [
    "response"
  ]
}
                                
arrow_right403 example
application/json

{
    "response": {
     "error": {
         "docs": www.questionpro.com/api/error-codes.html
         "name": "FORBIDDEN",
         "httpStatusCode": 403,
         "id" : "1013",
         "message": "The user does not have permission to access the resource",
         "resourceUrl":"resource_url"
        }
    }
}				
							
arrow_rightSchema
application/json

{
  "$schema": "http://json-schema.org/draft-06/schema#                                      ",
  "type": "object",
  "properties": {
    "response": {
      "type": "object",
      "properties": {
        "error": {
          "type": "object",
          "properties": {
            "docs": {
              "type": "string"
            },
            "resourceUrl": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "message": {
              "type": "string"
            },
            "httpStatusCode": {
              "type": "integer"
            }
          },
          "additionalProperties": false,
          "required": [
            "docs",
            "resourceUrl",
            "name",
            "id",
            "message",
            "httpStatusCode"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "error"
      ]
    }
  },
  "additionalProperties": false,
  "required": [
    "response"
  ]
}
                                
arrow_right404 example
application/json

{
    "response": {
     "error": {
         "docs": www.questionpro.com/api/error-codes.html
         "name": "NOT_FOUND",
         "httpStatusCode": 404,
         "id" : "1040",
         "message": "The resource that you're trying to access doesn't exist",
         "resourceUrl":"resource_url"
        }
    }
}
							
							
arrow_rightSchema
application/json

{
  "$schema": "http://json-schema.org/draft-06/schema#                                      ",
  "type": "object",
  "properties": {
    "response": {
      "type": "object",
      "properties": {
        "error": {
          "type": "object",
          "properties": {
            "docs": {
              "type": "string"
            },
            "resourceUrl": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "message": {
              "type": "string"
            },
            "httpStatusCode": {
              "type": "integer"
            }
          },
          "additionalProperties": false,
          "required": [
            "docs",
            "resourceUrl",
            "name",
            "id",
            "message",
            "httpStatusCode"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "error"
      ]
    }
  },
  "additionalProperties": false,
  "required": [
    "response"
  ]
}
                                
arrow_right500 example
application/json

{
    "response": {
     "error": {
         "docs": www.questionpro.com/api/error-codes.html
         "name": "INTERNAL_SERVER_ERROR",
         "httpStatusCode": 500,
         "id" : "1026",
         "message": "We are not able to process your request",
         "resourceUrl":"resource_url"
        }
    }
}
							
arrow_rightSchema
application/json

{
  "$schema": "http://json-schema.org/draft-06/schema#                                      ",
  "type": "object",
  "properties": {
    "response": {
      "type": "object",
      "properties": {
        "error": {
          "type": "object",
          "properties": {
            "docs": {
              "type": "string"
            },
            "resourceUrl": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "message": {
              "type": "string"
            },
            "httpStatusCode": {
              "type": "integer"
            }
          },
          "additionalProperties": false,
          "required": [
            "docs",
            "resourceUrl",
            "name",
            "id",
            "message",
            "httpStatusCode"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "error"
      ]
    }
  },
  "additionalProperties": false,
  "required": [
    "response"
  ]
}
                                

formParam Key Construction Guide

arrow_rightHow to build submit-page keys from GET /take response
Step 1: Call GET /surveys/{id}/take to get the page.
Step 2: For each question in questions[], parse the json field.
Step 3: Read formParam.paramPrefix and formParam.paramIdType.
Step 4: If paramIdType=questionId then key = paramPrefix + question.id
Step 5: If paramIdType=answerId then key = paramPrefix + answer.id (one key per answer row)
Step 6: For UniChoice, value = the selected answerId string.
Step 7: For MultiChoice, value = array of selected answerId strings.
Step 8: For Text, value = free-text string.
Step 9: If otherParamPrefix is present and Other option is selected, add t_{otherAnswerId}: other text.
arrow_rightQuick Reference — All Supported Question Types
U — UniChoice : u_{questionId} = {answerId}
M — MultiChoice : m_{questionId} = [{answerId}, ...]
T — Text/Open-ended : t_{answerId} = free text
CI — Contact Info : t_{answerId} = value per field
R — Rank Order : r_{answerId} = {rank integer}
S — Constant Sum : s_{answerId} = {numeric value}
DT — DateTime : dt_day_{aId}, dt_month_{aId}, dt_year_{aId} (+ dt_hr_, dt_min_, dt_ampm_ if time enabled)
CAL — Calendar : dt_cal_{answerId} = YYYY-MM-DD
SS — Slider Scale : u_{questionId} = {answerId}
SN — Slider Numeric : d_{questionId} = {numeric value}
NPS / CSAT / Star Rating : u_{questionId} = {answerId}
Matrix UniChoice : u_{rowQuestionId} = {columnAnswerId} (one per row)
Matrix MultiChoice : m_{rowQuestionId} = [{answerId}, ...] (one per row)
File Upload : l_{answerId} = file reference