Scopes and Projects
Scope is the asset type behind what the UI calls a Project. Scopes form
a tree, every work item belongs to exactly one, and they are the boundary for
permissions and the primary dimension for reporting.
Key Attributes
| Attribute | Type | Notes |
|---|---|---|
Name | Text | Required |
Parent | Relation | Required — the containing scope |
BeginDate | Date | Required |
Scheme | Relation | Required — controls available list values and roles; shown in the UI as Project Workspace |
EndDate | Date | Optional — and exclusive: the stored date is the day after the last day |
Description | LongText | |
Status | Relation | Descriptive list value — not the lifecycle (see below) |
Owner | Relation | A Member |
Members | Relation (multi) | Members with access — see roles and permissions |
Schedule | Relation | Where the scope's Timeboxes come from |
Children, Workitems | Relation (multi, read-only) | System-maintained rollups |
ParentMeAndUp, ChildrenMeAndDown | Relation (multi, read-only) | Self-plus-ancestors / self-plus-descendants — the subtree workhorses |
The Tree and Its Root
Every instance has a single root scope — Scope:0, "System (All
Projects)", whose Parent is null. Everything else hangs beneath it:
Scope:0 System (All Projects)
└─ Scope:1308 Release 1.0
└─ …
Walk the Tree Without Recursion
The rollup relations answer ancestry questions in one query — never write a
recursive loop over Parent:
{
"from": "Scope",
"where": { "ID": "Scope:1308" },
"select": ["Name", "Parent.Name", "ParentMeAndUp.Name", "ChildrenMeAndDown.Name"]
}
And the single most useful filter in Agility — work in this project or any project beneath it:
{
"from": "Story",
"filter": ["Scope.ParentMeAndUp='Scope:1308'"],
"select": ["Number", "Name", "Scope.Name"],
"page": { "size": 50, "start": 0 }
}
See Relations for why that filter reads backwards and still means "subtree".
Creating a Scope
Four attributes are required: Name, Parent, BeginDate and Scheme.
The simplest correct pattern copies the parent's scheme:
[
{
"AssetType": "Scope",
"Name": "API Gateway Project",
"Parent": "Scope:1308",
"BeginDate": "2026-09-01",
"Scheme": "Scheme:1001"
}
]
(Read the parent's Scheme first:
{"from": "Scope", "where": {"ID": "Scope:1308"}, "select": ["Scheme"]}.)
Lifecycle
- Closing a project is an operation, not a status change:
?op=InactivatesetsAssetStateto Closed (the UI calls closed scopes Inactive).Reactivatereopens. TheStatusattribute is a descriptive list value and does not drive the lifecycle. EndDateis exclusive — a project that ends December 31 stores January 1. See date conventions before doing arithmetic.Delete/Undeletebehave as everywhere: soft delete, recoverable.- Two scope-specific operations worth knowing exist:
AssignMemberWithRole(grant a member a role on the scope — the API-friendly way to provision access; see roles and permissions) andConvertToTeam.
Scope Vs Timebox
Both group work, on different axes:
- Scope answers "where does this work live?" — organizational, hierarchical, permission-bearing, long-lived.
- Timebox answers "when is it planned?" — sequential sprints/iterations that work moves through.
They meet through Schedule: a scope points at a Schedule, and the
Timeboxes on that schedule are the sprints available to work in that scope.
Scopes sharing a Schedule share sprint cadence.
Querying by Scope
// exactly this project
{ "from": "Story", "where": { "Scope": "Scope:1308" },
"select": ["Number", "Name"], "page": { "size": 50, "start": 0 } }
// this project and everything beneath it
{ "from": "Story", "filter": ["Scope.ParentMeAndUp='Scope:1308'"],
"select": ["Number", "Name"], "page": { "size": 50, "start": 0 } }
// across all projects, in one paged sweep — filter later, not never
{ "from": "PrimaryWorkitem", "filter": ["AssetState!='Dead'"],
"select": ["Number", "Name", "Scope.Name"], "page": { "size": 200, "start": 0 } }
Moving Work Between Scopes
Set the work item's Scope; its Tasks and Tests follow automatically —
Task.Scope is read-only and derives from the parent:
{ "from": "Story:1207", "update": { "Scope": "Scope:1400" } }
Permissions
A member's access is granted per scope, through roles — the scope tree is the permission tree. The details (Rights vs Privileges, the thirteen roles, why display names lie) live in Roles and permissions; the read-only view of assignments is api/ProjectRoles.
Related Topics
- Relations — rollup relations and the subtree idiom
- Date conventions — exclusive EndDate
- Roles and permissions
- Query size and performance