Skip to main content

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[].parentId identifies the parent section. A null value indicates a root section.
  • result.sections[].path contains the section ancestry.
  • questionAnswers[].sectionId identifies the effective containing section.
  • questionAnswers[].questionId identifies the question.
  • parentQuestionId and parentChoiceId describe subquestion nesting.
  • index is display order only; it is not an identifier or score.
Compatibility note

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: score is the answer's point contribution.
  • Accumulation with percentage weights: score is the weighted contribution to maxScore.
  • Deduction with points: score is the additive deduction contribution; maxScore and scoreInPercentage are null.
  • Not applicable: score and maxScore are 0; scoreInPercentage is 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.files for direct-answer files
  • questionAnswer.choices[].files for choice files
  • questionAnswer.tableValues[].files for table-cell files
  • questionAnswer.comments[].attachments for 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[].parentId is a parent section identifier.
  • flattenSections[].questions[].parentId is a parent question identifier.
  • questionAnswers[].parentId is a legacy parent answer-choice identifier. Use parentChoiceId in 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.