NutritionQuest FFQ API
Introduction
The FFQ API is a web API that enables the creation and management of users and sessions, the analysis of session answers, retrieval of results, and importing and exporting batch sessions and results.
Protocol
You can access the FFQ API via standard "REST" style HTTP protocols. Authentication requires an API key that is assigned to your group, sent as an "Authorization" header. Your API key determines the group.
Authorization
header (not X-API-Key). The header name is case-insensitive.
Authentication Levels
Access Level | Authentication | Capabilities |
---|---|---|
Standard API Access | API Key only | Create/read/update users and sessions, analyze data, export results |
NutritionQuest Admin Access | API Key + Admin Password | All standard functions plus delete users/sessions and reset group |
Demo Mode | API Key (demo group) | All NutritionQuest admin functions available (delete/reset enabled) |
Structure
The group is associated with one questionnaire, and has zero or more users. Each user has zero or more sessions, which include their answers and the various types of analysis results. Sessions contain various bulk data like JSON answers, JSON results, CSV file spreadsheets, HTML pages, etc, which can be read and optionally written by corresponding API calls.
Session Management Model
- Allowable Sessions: Each user has a maximum number of sessions they're permitted to create
- Default Limit: When a user is created, they're assigned the group's default per-user limit
- Actual Sessions: Created when questionnaire data is submitted
Features
User Management
Create and delete users individually with customizable passwords and session limits
Session Control
Create, delete, analyze, update, and query sessions individually
Template System
Apply HTML templates to partial or full results for interstitial feedback
Batch Operations
Bulk import users and answers, batch export results by ID or session cookies
Configuration
Setting | Value |
---|---|
Base Server URL | https://www.nutritionquest.com |
Authentication | NutritionQuest will assign you one or more FFQ API keys for each questionnaire you want to use. Send in Authorization header. |
Data Types
Basic Types
Type | Description |
---|---|
authorization secret |
A secret string FFQ API key sent in the HTTP Authorization header, used to authenticate and select the group to operate on. Each group will be assigned its own unique API key by NutritionQuest. If the group is in "demo" mode, all requests have NutritionQuest admin access to delete users and sessions and reset the group. |
user cookie |
A long hex string used in API paths to identify an existing user. |
session cookie |
A long hex string identifying a session. This is what the API uses to identify sessions. |
completion date |
A date string in the format "MMDDYYYY" if a session is complete, or "" if not complete |
session timestamp |
A time and date string in the format "YYYY-MM-DD HH:MM:SS" or "" if undefined |
File Types
Type | Description |
---|---|
CSV file |
A text comma separated values spreadsheet file of analysis data, the first row of which contains headers with names for the columns |
HTML file |
A text HTML file with human readable analysis results |
ZIP file |
A binary compressed archive containing other types of files |
JSON file |
A file in JavaScript Object Notation containing JSON objects, JSON arrays, etc |
Key JSON Objects
JSON confirmation object
{
"success": boolean, // success flag
"message": string // error or success message
}
JSON group object
{
"success": boolean,
"ffq_name": string, // name of the group's FFQ
"title": string, // title of the group
"user_count": number, // number of users in the group
"session_count": number, // number of sessions in the group
"nutrients_per_food": boolean // true if analysis results include nutrients-per-food tables
}
JSON user object
{
"success": boolean,
"user_id": string, // User ID in the group's admin interface, represents the user's unique Respondent ID number
"user_cookie": string, // User Cookie (unique identifier for API lookups)
"user_screen_name": string, // User Screen Name in the group's admin interface, the name that a user logs in with
"sessions_per_user": number, // Maximum number of sessions this user is permitted to create
"session_count_total": number,
"session_count_complete": number,
"session_count_incomplete": number,
"sessions": [
{
"session_cookie": string, // Session Cookie (unique identifier for API lookups)
"complete": boolean,
"start": string, // Date in "YYYY-MM-DD" format
"finish": string // Date in "YYYY-MM-DD" format or null
}
]
}
JSON user initialization object
{
"user_id": string, // Required: User's unique Respondent ID number (must be unique in group)
"user_screen_name": string, // Optional: User Screen Name (the name that a user logs in with), defaults to user_id
"user_password": string // Optional: User's password, generates random if not provided
}
sessions_per_user
field cannot be set during user creation. Users are automatically assigned the group's default per-user session limit.
JSON user update object
{
"user_name": string, // Optional: New user ID (must be unique in group)
"user_screen_name": string, // Optional: New user screen name (the name that a user logs in with)
"user_password": string, // Optional: New user password
"sessions_per_user": number // Optional: Number of sessions permitted (cannot exceed group's per-user default)
}
JSON session object
{
"session_cookie": string, // Session Cookie (unique identifier for API lookups)
"complete": boolean, // session complete flag
"start": string, // session timestamp start time
"finish": string // session timestamp finish time
}
JSON session initialization object
{
"app_values": {}, // JSON application values object (questionnaire screen progress tracking)
"answers": {}, // JSON answers object (the user's answers to the FFQ)
"environment": {} // JSON environment object (browser information)
}
JSON answers object
{
// An object representing the user's answers to an FFQ
// Structure varies by questionnaire
// Example:
"answer_1": "1",
"answer_2": "2",
"answer_3": "3"
}
JSON application values object
{
// An object containing the number of the questionnaire screen the user was last on
// Used to track user progress through the questionnaire
// Example:
"screen": 15
}
JSON environment object
{
// An object containing information about the browser the user was using
// Example:
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"browser": "Chrome",
"platform": "Windows"
}
JSON results object
{
// An object representing the analysis results
// Contains nutritional analysis, calculations, and derived values
// Structure includes fields like:
"STATIC_ROOT": "https://www.nutritionquest.com",
"RESPONDENTID": "user_id",
"FINISHED": boolean,
"TODAYSDATE": "MMDDYYYY",
// ... plus many nutrition-specific fields
}
JSON batch import description object
{
"complete_flag": boolean, // true if session complete
"date_completed": string, // completion date as "MMDDYYYY" if complete, or "" if not
"user_id": string, // User's unique Respondent ID number
"answers": {} // JSON answers object
}
JSON batch import confirmation object
{
"successes": [], // JSON array of success message strings
"warnings": [], // JSON array of warning message strings
"errors": [], // JSON array of error message strings
"batch_number": number, // batch number of import, used to export results
"session_cookies": [], // JSON array of session cookies processed
"records": [] // JSON array of JSON batch import record confirmation objects
}
JSON batch import record confirmation object
{
"success": boolean,
"user_id": string, // User's unique Respondent ID number
"user_created": boolean, // true if user was created, false if already existed
"ffq_name": string,
"session_created": boolean, // true if session was created, false if already existed
"complete_flag": boolean,
"date_completed": string, // completion date as "MMDDYYYY" if complete, or "" if not
"user_cookie": string, // user cookie identifying user (internal identifier)
"session_cookie": string // session cookie identifying session
}
JSON batch export description object
{
"batch_number": number, // batch number to export (optional)
"session_cookies": [] // array of session cookies to export (optional)
}
JSON batch export confirmation object
{
"success": boolean,
"url": string // url of ZIP file of exports to download
}
API Methods
Group Management
User Management
Create new user in group
Get user by user cookie
Update user by user cookie
Session Management
Create a new session for a user
Get session by user cookie and session cookie
Session Data Management
Get answers from session
Update answers in session
→ See exampleGet app values from session
Update app values in session
Get environment from session
Update environment in session
Analysis and Results
Get JSON results from session
Get HTML results from session
Get nutrients CSV (if enabled)
Get cases CSV
Apply template to results
Analyze answers without finishing
Analyze answers and finish session
Batch Operations
Batch import users and answers
Batch export analysis results as ZIP
Examples
xyzzy
represents your group's authorization key, and USER_COOKIE
and SESSION_COOKIE
are placeholders for actual user and session cookies (long hex strings). The curl -s
parameter operates in quiet mode (not printing unnecessary output). The jq .
command pretty-prints JSON output.
Authorization
header, not X-API-Key
as shown in older documentation.
Create a New User with Password
curl -s \
-H "Authorization: xyzzy" \
-H "Content-Type: application/json" \
-X POST \
-d '{"user_id":"123_1", "user_screen_name": "John_Doe", "user_password": "mypassword123"}' \
https://www.nutritionquest.com/ffqapi/user \
| jq .
Response:
{
"success": true,
"user_id": "123_1",
"user_cookie": "1bb43d659f52ca986b2f360c0bb7025d",
"user_screen_name": "John_Doe",
"sessions_per_user": 10, // Automatically set to group's default
"session_count_total": 0,
"session_count_complete": 0,
"session_count_incomplete": 0,
"sessions": []
}
Get Group Information
curl -s \
-H "Authorization: xyzzy" \
-X GET \
https://www.nutritionquest.com/ffqapi/group \
| jq .
Response:
{
"success": true,
"ffq_name": "Block_2014_FFQ",
"title": "UniversityX_studyNameY",
"user_count": 0,
"session_count": 0,
"nutrients_per_food": false
}
Create a New Session
curl -s \
-H "Authorization: xyzzy" \
-H "Content-Type: application/json" \
-X POST \
-d '{}' \
https://www.nutritionquest.com/ffqapi/user/1bb43d659f52ca986b2f360c0bb7025d/session \
| jq .
Response:
{
"session_cookie": "cbd42f733e4c8f65f8f98c52a4fea5fd",
"complete": false,
"start": "2024-03-03 00:00:00",
"finish": "0000-01-01 00:00:00"
}
sessions_per_user
limit or if the group has reached its total session limit.
Get All Users and Sessions
curl -s \
-H "Authorization: xyzzy" \
-X GET \
https://www.nutritionquest.com/ffqapi/user \
| jq .
Response:
{
"success": true,
"users": [
{
"success": true,
"user_id": "123_1",
"user_cookie": "1bb43d659f52ca986b2f360c0bb7025d",
"user_screen_name": "John_Doe",
"sessions_per_user": 10,
"session_count_total": 1,
"session_count_complete": 0,
"session_count_incomplete": 1,
"sessions": [
{
"session_cookie": "cbd42f733e4c8f65f8f98c52a4fea5fd",
"complete": false,
"start": "2024-03-03 00:00:00",
"finish": "0000-01-01 00:00:00"
}
]
}
]
}
Update Session Answers
curl -s \
-H "Authorization: xyzzy" \
-H "Content-Type: application/json" \
-X PUT \
-d '{"answer_1":true,"answer_2":false}' \
https://www.nutritionquest.com/ffqapi/user/1bb43d659f52ca986b2f360c0bb7025d/session/cbd42f733e4c8f65f8f98c52a4fea5fd/answers \
| jq .
Response:
{
"success": true,
"message": "Updated session answers."
}
Finish Session Analysis
curl -s \
-H "Authorization: xyzzy" \
-X POST \
https://www.nutritionquest.com/ffqapi/user/1bb43d659f52ca986b2f360c0bb7025d/session/cbd42f733e4c8f65f8f98c52a4fea5fd/finish \
| jq .
Response:
{
"success": true,
"message": "Analyzed session."
}
Get JSON Results
curl -s \
-H "Authorization: xyzzy" \
-X GET \
https://www.nutritionquest.com/ffqapi/user/1bb43d659f52ca986b2f360c0bb7025d/session/cbd42f733e4c8f65f8f98c52a4fea5fd/results \
| jq .
Response:
{
"STATIC_ROOT": "https://www.nutritionquest.com",
"ANSWER_1": true,
"ANSWER_2": false,
"RESPONDENTID": "123_1",
"FINISHED": true,
"TODAYSDATE": "02282024",
"AGE": 40,
"YOGURTQUAN": "3",
"PLANTYOGURTQUAN": "2"
}
Get HTML Results
curl -s \
-H "Authorization: xyzzy" \
-X GET \
https://www.nutritionquest.com/ffqapi/user/1bb43d659f52ca986b2f360c0bb7025d/session/cbd42f733e4c8f65f8f98c52a4fea5fd/results_html
Response:
<div>
<div class="row">
<div class="col m12">
...
</div>
</div>
</div>
Batch Import Records
curl -s \
-H "Authorization: xyzzy" \
-H "Content-Type: application/json" \
-X POST \
-d '[
{
"complete_flag": true,
"date_completed": "01012024",
"user_id": "0000000052",
"answers": {
"RespondID": "0000000052",
"answer_1": "1",
"answer_2": "2",
"answer_3": "3"
}
}
]' \
https://www.nutritionquest.com/ffqapi/import \
| jq .
Export by Session Cookies
curl -s \
-H "Authorization: xyzzy" \
-H "Content-Type: application/json" \
-X POST \
-d '{"session_cookies": ["c4becc52184869a8675f03acc4383670"]}' \
https://www.nutritionquest.com/ffqapi/export \
| jq .
Response:
{
"success": true,
"url": "https://www.nutritionquest.com/login/downloads/data-2024-03-24-19-35-56-rand-3429.zip"
}
Update User Password and Session Limit
curl -s \
-H "Authorization: xyzzy" \
-H "Content-Type: application/json" \
-X PUT \
-d '{"user_password": "newpassword123", "sessions_per_user": 5}' \
https://www.nutritionquest.com/ffqapi/user/USER_COOKIE \
| jq .
Response:
{
"success": true,
"message": "Updated user."
}
sessions_per_user
value cannot exceed the group's default per-user limit. Attempting to set a higher value will result in an error.