A story represents a piece of planned work in Atono. It typically includes a user story statement written from the user's perspective, acceptance criteria (ACs), and optional context to guide implementation or review.
Story attributes
The table below lists the fields available on stories, including those you can specify when creating or updating a story, as well as fields returned in API responses.
The Usage column shows which endpoints accept values for that field. If the Usage column is blank, the field is read-only—it's returned in responses but can't be manually specified in any request.
Field | Type | Description | Usage |
---|---|---|---|
title | string | The title of the story. | POST, PATCH |
handle | string | A unique identifier for the story, shown in the Atono application as the item ID (e.g., STORY-123 ). | |
position | integer | The story’s vertical order within its current workflow step, where 0 is the topmost item. Position is relative to the step and team backlog. | |
content | array of content chunks | Displayed at the top of the story and represents the user story statement ("As a... I want... so that..."). The array may include TEXT , PERSONA , and DISPLAY_HTML chunks. Use DISPLAY_HTML when you want to include HTML formatting. If you include a PERSONA chunk, its value appears in the Atono web app as a selectable persona for future suggestions. | POST, PATCH |
additionalContent | array of content chunks | Optional context shown below the acceptance criteria. Often used for background info, technical notes, or decisions. Supports DISPLAY_HTML and TEXT content chunks. | POST, PATCH |
cycleTimeMode | string | Indicates whether the story is marked as an OUTLIER (excluded) or remains NORMAL (included) in average cycle time calculations, reports, and staleness indicators. | |
stalenessIndicatorSnoozeUntil | datetime (ISO 8601) | The date and time until which the staleness indicator is hidden for this story in its current step and team backlog. Once the date passes, the indicator is shown again if the story is still stale. | |
createdAt | datetime (ISO 8601) | The date and time the story was created. | |
updatedAt | datetime (ISO 8601) | The date and time the story was last updated. | |
doneAt | datetime (ISO 8601) | The date and time when the story was completed. | |
deleted | boolean | Whether the story has been deleted. |
Story relationships
Stories can be assigned to a user or team, include acceptance criteria, and be associated with a feature flag. They also record the user who created the story.
When requesting a story, only the type
and id
of each related resource are returned by default. To include full details in the response, use the ?include={relationship}
query parameter.
Field | Type | Description |
---|---|---|
acceptanceCriteria | array of acceptance_criterion | The list of acceptance criteria linked to the story. Use ?include=acceptanceCriteria to retrieve full details. |
assignee | user | The user assigned to the story. Use ?include=assignee to retrieve full details. |
team | team | The team backlog the story is assigned to. Use ?include=team to retrieve full details. |
featureFlag | flag | The feature flag associated with the story. Use ?include=featureFlag to retrieve full details. |
creator | user | The user who created the story. Use ?include=creator to retrieve full details. |
Creating or updating a story
You can specify the assignee
, team
, and acceptanceCriteria
in the relationships
object when creating or updating a story.
The creator
is automatically set to the user making the creation request and cannot be modified. Feature flags cannot currently be added to a story via the API.
Story relationship objects
The examples below show how to structure the relationship objects when creating or updating a story. You can reference existing resources (like users and teams) or define new acceptance criteria inline.
assignee
Reference an existing user by id
. To find valid user ids
, use the Get users endpoint.
"assignee": {
"data": {
"type": "user",
"id": "d73f1297-825d-4f9a-9529-51ab0f8b0cfe"
}
}
team
Reference an existing team by id
. To find valid team ids
, use the Get teams endpoint.
"team": {
"data": {
"type": "team",
"id": "0cd0c8b8-734f-4c17-a07c-e993b04af480"
}
}
To unassign a user or remove a story from a team's backlog, set the value to null:
"assignee": { "data": null },
"team": { "data": null }
acceptanceCriteria
To define acceptance criteria inline, provide an array of objects. Each object must include a type
and attributes
with a description
. You can also set position
and level
to control ordering and hierarchy.
"acceptanceCriteria": {
"data": [
{
"type": "acceptance_criterion",
"attributes": {
"description": "The user can select a waveform from the dropdown.",
"position": 0,
"level": 0
}
},
{
"type": "acceptance_criterion",
"attributes": {
"description": "The selected waveform is applied immediately.",
"position": 1,
"level": 0
}
}
]
}
Field | Type | Description |
---|---|---|
description | string | A short statement describing the expected behavior. |
position | integer ≥ 0 | The order of the criterion within the list. |
level | integer 0–10 | The nesting level of the criterion. Level 0 is top-level; higher values represent subcriteria. |
When you include the acceptanceCriteria
relationship in a request, you are replacing the entire set of acceptance criteria. To retain existing criteria, you must include them in your update. Partial updates (for example, adding or editing a single criterion) are not currently supported.
Example: Get a story
This example shows a GET
response for a single story, including its attributes, relationships, and related resources in the included
array.
{
"data": {
"type": "story",
"id": "55fff8eb-1370-4cd5-b716-d019d94f8da9",
"attributes": {
"title": "Sync virtual instruments to external MIDI Clock",
"handle": "STORY-134",
"position": 6,
"content": [
{
"type": "DISPLAY_HTML",
"value": "<p>As a performer using Virtual Vintage live, I want to sync virtual instruments to an external MIDI clock so that loops and effects stay in time with the rest of my gear.</p>"
},
{
"type": "TEXT",
"value": "As a "
},
{
"type": "PERSONA",
"value": "performer using Virtual Vintage live"
},
{
"type": "TEXT",
"value": ", I want to"
},
{
"type": "TEXT",
"value": " sync virtual instruments to an external MIDI clock"
},
{
"type": "TEXT",
"value": " so that "
},
{
"type": "TEXT",
"value": "loops and effects stay in time with the rest of my gear."
}
],
"additionalContent": [
{
"type": "DISPLAY_HTML",
"value": "<p>This helps maintain tempo consistency during live sets, even if the external signal is interrupted.</p>"
}
],
"cycleTimeMode": "NORMAL",
"createdAt": "2025-08-01T17:38:33Z",
"updatedAt": "2025-08-01T18:36:51Z",
"deleted": false
},
"relationships": {
"acceptanceCriteria": {
"data": [
{
"type": "acceptance_criterion",
"id": "fdfbb9fb-9a69-4894-a05c-7b68affab074"
},
{
"type": "acceptance_criterion",
"id": "8f997cc6-ef8c-4ebb-9e88-509eb5989c0c"
},
{
"type": "acceptance_criterion",
"id": "fccfbcfb-8ced-4556-8cd5-6ac8c64d9744"
}
],
"meta": {
"count": 3
}
},
"assignee": {
"links": {
"related": "/api/v1/users/b1c51488-9bcd-495c-bb90-e718f384b32c"
},
"data": {
"type": "user",
"id": "b1c51488-9bcd-495c-bb90-e718f384b32c"
}
},
"team": {
"links": {
"related": "/api/v1/teams/409bb1af-3498-406b-9df0-d2ac7eb83aab"
},
"data": {
"type": "team",
"id": "409bb1af-3498-406b-9df0-d2ac7eb83aab"
}
},
"featureFlag": {
"links": {
"related": "/api/v1/flags/7efd5b19-75be-4d88-81dc-38ab17c05923"
},
"data": {
"type": "flag",
"id": "7efd5b19-75be-4d88-81dc-38ab17c05923"
}
},
"creator": {
"links": {
"related": "/api/v1/users/bf60edfc-be09-4fea-8597-33c5b333ce05"
},
"data": {
"type": "user",
"id": "bf60edfc-be09-4fea-8597-33c5b333ce05"
}
}
}
},
"included": [
{
"type": "acceptance_criterion",
"id": "fdfbb9fb-9a69-4894-a05c-7b68affab074",
"attributes": {
"description": "Users can enable MIDI Clock sync in instrument settings.",
"position": 0,
"level": 0
}
},
{
"type": "user",
"id": "bf60edfc-be09-4fea-8597-33c5b333ce05",
"attributes": {
"createdAt": "2024-04-29T16:45:22Z",
"updatedAt": "2025-05-08T20:52:56Z",
"invitedAt": "2025-01-23T22:58:21Z",
"email": "[email protected]",
"fullName": "Max Harmon",
"deleted": false
}
},
{
"type": "acceptance_criterion",
"id": "8f997cc6-ef8c-4ebb-9e88-509eb5989c0c",
"attributes": {
"description": "When enabled, Virtual Vintage follows incoming MIDI Clock tempo.",
"position": 1,
"level": 0
}
},
{
"type": "team",
"id": "409bb1af-3498-406b-9df0-d2ac7eb83aab",
"attributes": {
"name": "Frequency Finders",
"description": "Focuses on search an navigation, ensuring customers can easily find the perfect vintage audio gear on the website.",
"createdAt": "2024-12-05T22:41:27Z",
"updatedAt": "2025-02-06T23:39:04Z",
"isPublic": true,
"backlogManagementByOwners": true
},
"relationships": {
"members": {
"links": {
"self": "/api/v1/teams/409bb1af-3498-406b-9df0-d2ac7eb83aab/relationships/members"
},
"data": [],
"meta": {
"count": 0
}
}
}
},
{
"type": "user",
"id": "b1c51488-9bcd-495c-bb90-e718f384b32c",
"attributes": {
"createdAt": "2024-12-11T00:12:16Z",
"updatedAt": "2025-06-03T23:32:20Z",
"invitedAt": "2025-01-23T22:58:21Z",
"email": "[email protected]",
"fullName": "Belle Tinker",
"deleted": false
}
},
{
"type": "acceptance_criterion",
"id": "fccfbcfb-8ced-4556-8cd5-6ac8c64d9744",
"attributes": {
"description": "If MIDI Clock is lost, a fallback tempo is used and a warning is shown.",
"position": 2,
"level": 0
}
},
{
"type": "flag",
"id": "7efd5b19-75be-4d88-81dc-38ab17c05923",
"attributes": {
"key": "sync_virtual_instruments_to_external_midi_clock",
"variants": {
"on": true,
"off": false
},
"createdAt": "2025-08-01T18:36:51Z",
"updatedAt": "2025-08-01T18:36:51Z"
}
}
]
}
Example: Create a story
This example shows a POST
request for creating a new story with a structured user story statement and multi-level acceptance criteria.
The id
values for user
and team
must reference existing resources in your workspace. You can retrieve them using the Get users and Get teams endpoints.
{
"data": {
"type": "story",
"attributes": {
"title": "Add support for MIDI Clock sync in virtual instruments",
"content": [
{ "type": "TEXT", "value": "As a " },
{ "type": "PERSONA", "value": "performer " },
{
"type": "TEXT",
"value": "using Virtual Vintage’s soundboards in a live setup, I want the virtual instruments to sync with an external MIDI clock, so that tempo-dependent effects and loops stay in time with the rest of my gear."
}
]
},
"relationships": {
"acceptanceCriteria": {
"data": [
{
"type": "acceptance_criterion",
"attributes": {
"description": "Enable external MIDI Clock sync",
"position": 0,
"level": 0
}
},
{
"type": "acceptance_criterion",
"attributes": {
"description": "Users can toggle MIDI Clock sync on/off in the instrument settings.",
"position": 0,
"level": 1
}
},
{
"type": "acceptance_criterion",
"attributes": {
"description": "When enabled, Virtual Vintage follows the incoming MIDI Clock tempo and start/stop commands.",
"position": 0,
"level": 1
}
},
{
"type": "acceptance_criterion",
"attributes": {
"description": "Fall back to internal tempo",
"position": 1,
"level": 0
}
},
{
"type": "acceptance_criterion",
"attributes": {
"description": "If MIDI Clock is enabled but not received, a fallback tempo is used and a warning is shown in the interface.",
"position": 1,
"level": 1
}
}
]
},
"assignee": {
"data": { "type": "user", "id": "d73f1297-825d-4f9a-9529-51ab0f8b0cfe" }
},
"team": {
"data": { "type": "team", "id": "0cd0c8b8-734f-4c17-a07c-e993b04af480" }
}
}
}
}