Report and Questionnaire Results
Use the Responsible Sourcing & Compliance (RSC) APIs to retrieve a list of reports, individual report summaries, CAPA data, and complete questionnaire results.
Precondition​
Generate an API key for your organization and use it to authenticate your requests.
Choose the right endpoint​
- List Reports V2 lists reports with report and CAPA metadata.
- Get Report V2 returns a lightweight section/category summary. It does not contain questionnaire questions or answers.
- Get Assessment is the recommended single-call export for an assessment and its questionnaire answers.
- Get Step Execution returns the questionnaire definition and answers for one step execution.
Questions are leaf nodes attached to sections at any depth. Do not interpret a question as an additional section level. For example, both a Level 1 section and a Level 2 section can contain questions directly.
Export a complete assessment​
Request Get Assessment with include_step_questions=true:
GET /api/v1/assessments/{assessment_id}?include_step_questions=true
Add include_question_comments=true only when comments are required:
GET /api/v1/assessments/{assessment_id}?include_step_questions=true&include_question_comments=true
include_question_comments=true requires include_step_questions=true; other combinations return 422. Comments are excluded by default to avoid a potentially large payload increase.
Stable hierarchy joins​
Use identifiers—not array positions—to reconstruct the result:
result.sections[].parentIdidentifies the parent section. A null value indicates a root section.result.sections[].pathcontains the section ancestry.questionAnswers[].sectionIdidentifies the effective containing section.questionAnswers[].questionIdidentifies the question.parentQuestionIdandparentChoiceIddescribe subquestion nesting.indexis display order only; it is not an identifier or score.
Enabling include_step_questions=true expands result.sections with any answer-referenced questionnaire-only sections that are absent from the scored report summary, such as an AP Test applicability-test section. Existing consumers using this flag may therefore receive additional section objects. This is intentional and additive; existing scored sections are unchanged.
Questionnaire-only sections have null score, maxScore, rating, and customFields values. Every non-null questionAnswers[].sectionId resolves within the same step execution's result.sections collection; inconsistent legacy linkage is returned as null rather than as a dangling identifier.
Subquestions inherit the containing section of their parent question. They remain nested under choices[].subQuestionAnswers and must not be converted into synthetic sections.
The following example builds the section tree and attaches every direct question to its effective section, regardless of section depth:
function reconstructQuestionnaire(stepExecution) {
const sections = stepExecution.result?.sections ?? [];
const sectionById = new Map(
sections.map(section => [section.id, { ...section, sections: [], questions: [], applicabilityTests: [] }]),
);
const roots = [];
const unlinkedQuestions = [];
for (const section of sectionById.values()) {
const parent = section.parentId ? sectionById.get(section.parentId) : null;
if (parent) parent.sections.push(section);
else roots.push(section);
}
for (const answer of stepExecution.questionAnswers ?? []) {
for (const choice of answer.choices ?? []) {
for (const subAnswer of choice.subQuestionAnswers ?? []) {
if (subAnswer.sectionId !== answer.sectionId) {
throw new Error("A subquestion must inherit its parent question's section");
}
}
}
if (answer.sectionId === null) {
unlinkedQuestions.push(answer);
continue;
}
const section = sectionById.get(answer.sectionId);
if (!section) throw new Error(`Unknown sectionId ${answer.sectionId}`);
section.questions.push(answer);
}
for (const result of stepExecution.appTestResults ?? []) {
sectionById.get(result.sectionId)?.applicabilityTests.push(result);
}
return { sections: roots, unlinkedQuestions };
}
unlinkedQuestions preserves answers from legacy records whose effective section cannot be resolved. A non-null sectionId that is absent from result.sections still indicates an invalid response and causes the example to throw.
Application-test rows are returned separately in appTestResults; join them to sections with sectionId.
Answer scores​
Each top-level and nested answer can contain numeric, nullable score, maxScore, and scoreInPercentage fields:
- Accumulation with points:
scoreis the answer's point contribution. - Accumulation with percentage weights:
scoreis the weighted contribution tomaxScore. - Deduction with points:
scoreis the additive deduction contribution;maxScoreandscoreInPercentageare null. - Not applicable:
scoreandmaxScoreare0;scoreInPercentageis null. - Uncalculated or non-scoreable answers: all three fields are null.
All score fields are also null when report-result visibility or the questionnaire's score-display configuration does not allow the requesting organization to view scores.
Attachments and comments​
Assessment attachments use the same shape everywhere:
{
"id": "attachment-id",
"name": "evidence.pdf",
"signedUrl": "https://temporary-download-url"
}
Attachments can occur in four distinct locations:
questionAnswer.filesfor direct-answer filesquestionAnswer.choices[].filesfor choice filesquestionAnswer.tableValues[].filesfor table-cell filesquestionAnswer.comments[].attachmentsfor comment files
Comment attachments are not merged into questionAnswer.files. When comments are requested, comment author and organization details are returned subject to the existing assessment-access and organization-confidentiality rules.
Use Get Step Execution​
Get Step Execution exposes the questionnaire definition in questionnaire.flattenSections alongside questionAnswers. Its hierarchy and score fields use the same semantics as Get Assessment.
Be precise when reading its legacy parentId fields:
flattenSections[].parentIdis a parent section identifier.flattenSections[].questions[].parentIdis a parent question identifier.questionAnswers[].parentIdis a legacy parent answer-choice identifier. UseparentChoiceIdin new integrations.
Question definitions also expose sectionId. Answer definitions expose sectionId, parentQuestionId, parentChoiceId, and the score trio at both the top level and within subQuestionAnswers.