Combining structure and rounds to analyse results
Structure and rounds are the two Attest API endpoints. Learn how they connect, what the key concepts mean, and how to join them to resolve respondent answers to question titles and labels.
When you call the Attest API, results are split across two endpoints: structure and rounds. To work with the data meaningfully, you need both.
- Structure describes the study: what questions were asked, what the answer options were, and how the survey was organised across waves.
- Rounds contains the responses: one record per respondent, with the answers they gave.
Neither endpoint is fully useful on its own. Structure tells you what the questions and answers mean. Rounds tells you what people said. You join them together using IDs.
How they connect
Everything in the Attest API is identified by a UUID. The same IDs appear in both endpoints, which is how you link a respondent's answer back to the question it belongs to.
The join works like this:
- Each answer option in
structurehas anid - Each respondent record in
roundscontains acardsobject, where each card holds the answer option IDs the respondent selected - By matching answer option IDs across both endpoints, you can resolve each response to its question title and answer label
Key concepts
Nodes
A node is a question. The nodes[] array in the structure response contains one object per question, with its title, type, and answer options.
Fields and answer options
Each node has a fields.items[] array containing its answer options. Each option has an id and a text label. These IDs are what appear as keys in a respondent's answers.
Cards
A card represents one respondent's answers to one question. Cards are returned inside each round object, in a cards object keyed by card ID. Card IDs match node IDs directly, so you can join them to the corresponding question in structure without needing to match through answer IDs. See GET Study Structure and GET Study Rounds for the full field reference.
Skipped questions
If a respondent skips a question, the card will contain a single answer keyed "skipped" with no corresponding entry in structure. This is expected — skipped is a system value, not an answer option. When building a join, filter out any answer ID of "skipped" before looking up in structure.
Waves
A study can run across multiple waves: repeated rounds of the same survey sent to an audience at different points in time. Each wave has a waveIndex and a publishedAt timestamp. Wave indexes are stable across API calls. Use positive indexes to count from the oldest wave (0 is the first), or negative indexes to count from the newest (-1 is the most recent).
Subjects (grid questions only)
Grid questions have both fields.items[] (the scale, e.g. 0–10) and subjects.items[] (the rows, e.g. "brush your teeth", "floss"). Each subject has its own set of answerIds, which are composite IDs that encode both the subject and the scale value. These are what appear in the rounds data for grid responses.
Question types
The type field on a node determines how to interpret the answers in rounds data.
| Type | Description | Answer shape |
|---|---|---|
single_choice | One answer selected | One answer ID |
multiple_choice | One or more answers selected | Multiple answer IDs |
nps | 0–10 scale | One answer ID corresponding to the selected value |
ranked | Options ranked in order | Multiple answer IDs, each with an order field indicating rank position |
free_text | Open text response | Answer contains a text field and optionally a sentiment field |
grid | Scale applied across multiple row items | Composite answer IDs that encode both the subject and scale value |
max_diff | Best/worst scaling | Answer contains a maxDiff object keyed by answer ID, each with a label field indicating best or worst |
Example: resolving an answer
Given this answer option in structure:
{
"id": "{answerId}",
"text": "Daily"
}And this card in a round:
{
"answers": {
"{answerId}": {
"text": "Daily"
}
}
}The {answerId} appears in both objects, telling you this respondent selected Daily as their answer.