User-scoped API for projects, workspaces, docs, scope data, models, milestones, requirements, teams, users, and work packages.
Base: /external/v2
Auth: API key
Format: JSON
Authentication
Every request must provide an external API key.
Keys are user-scoped and region-local. Create a separate key on each regional API host you need to call.
Keys include CoreRead by default. Add higher-level read scopes when a key needs access to docs, scope, or verify data. Write endpoints require explicit write scopes.
EU servers:https://api.eu.plannerly.com/external/v2
The examples on this page use the current docs host:
https://api.plannerly.com/external/v2
Includes
The include query parameter lets you expand related resources in the same response.
Use comma-separated values when an endpoint supports multiple includes.
Syntax: ?include=value_a,value_b
If an endpoint does not support include values, omit the parameter.
Unsupported include values return 400 INVALID_INCLUDE.
Example: /projects/:project_id/milestone-groups?include=milestones expands milestone data within each milestone group response.
Some collection endpoints support filtering with the filter query parameter.
Multiple filters are combined with AND. Multiple values for a single filter are treated as OR.
Syntax: ?filter[field_name]=value
Multiple values can be passed as a comma-separated list: ?filter[field_name]=value_a,value_b
Add account user: Invites one or more users to the account by email. Requires TeamWrite and account user-management access. If an email is not already a user, the request creates a pending user before adding the account membership.
Scope
TeamWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: users, an array of up to 30 objects. Each object requires email. Optional fields for new pending users: name, phone_number, and position_title. If name is omitted, the email name is used. Invite requests are limited to 10 per minute per key.
Remove account user: Removes a user from the account. Requires TeamWrite and account user-management access. The request is blocked when it would leave the account without any account members.
Scope
TeamWrite
This write endpoint requires the listed scope on the key.
Create workspace: Creates a workspace in an account. Requires ProjectWrite and account membership for the target account. Existing account members are added to the new workspace.
Scope
ProjectWrite
This write endpoint requires the listed scope on the key.
Add workspace user: Invites one or more users to the workspace by email. Requires TeamWrite and workspace user-management access. If an email is not already a user, the request creates a pending user before adding the workspace membership.
Scope
TeamWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: users, an array of up to 30 objects. Each object requires email. Optional fields for new pending users: name, phone_number, and position_title. If name is omitted, the email name is used. Invite requests are limited to 10 per minute per key.
Remove workspace user: Removes a user from the workspace. Requires TeamWrite and workspace user-management access. The request is blocked when it would leave the workspace without any workspace members.
Scope
TeamWrite
This write endpoint requires the listed scope on the key.
Create project: Creates a project in a workspace. Requires ProjectWrite and workspace membership for the target workspace. The authenticated user is added to the new project with manager access, and the project starts with an initial manager team.
Scope
ProjectWrite
This write endpoint requires the listed scope on the key.
Create project team: Creates a team on the project. Requires a key with the TeamWrite scope and a project permission that can manage teams.
Scope
TeamWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title. Optional fields: team_name, abbreviation, highlight_color, position. If omitted, team_name defaults to title, abbreviation defaults to the first three title characters, and highlight_color defaults to a random project team swatch color.
Delete project team: Deletes a project team. Requires TeamWrite plus project permission access to manage teams. Deletion is blocked while the team has users or is used by a work package.
Scope
TeamWrite
This write endpoint requires the listed scope on the key.
Update project user permission: Updates the user's project_permission_id for every project user entry that user has on the project. The user must belong to the target team. Requires TeamWrite plus project permission access to update users in that team and assign the supplied project_permission_id.
Scope
TeamWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: project_permission_id from /projects/:project_id/project-permissions.
Add user to project team: Invites one or more users to the team by email. Requires TeamWrite plus project permission access to invite users to the target team and assign the supplied project_permission_id. If an email is not already a user, the API creates a pending user. If the user is not already on the project, the API creates a project user entry with the supplied project_permission_id or the project viewer permission when omitted.
Scope
TeamWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: users, an array of up to 30 objects. Each object requires email. Optional fields on each object: project_permission_id from /projects/:project_id/project-permissions, plus name, phone_number, and position_title for new pending users. If name is omitted for a new pending user, the email name is used. If project_permission_id is omitted, the project viewer permission is used. Workspace admins must use the project manager permission. Invite requests are limited to 10 per minute per key.
Remove user from project team: Removes a user from the team. Requires TeamWrite plus project permission access to remove users from the target team; users can also remove themselves. If the user has no other teams on the project, the user is removed from the project.
Scope
TeamWrite
This write endpoint requires the listed scope on the key.
Create project permission: Creates a custom project permission. Requires PermissionWrite plus project permission access to manage permissions. New permissions start from the project Manager defaults and always disable can_manage_permissions. The named scope_task_access_policy is the v2 task-access contract: every view, edit, and delete audience is required, matching audiences are ORed, and edit/delete must be subsets of view. Do not combine it with the legacy scope task access or management fields.
Scope
PermissionWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: name. Optional objects: modules, capabilities, access, and scope_task_access_policy. Omitted fields keep the Manager default.
Allowed Values
scope_task_access_policy.version
Must be 2.
scope_task_access_policy.view
Required booleans for direct_self, own_team, other_person, other_team, and unassigned. A task is visible when any matching audience is true.
scope_task_access_policy.edit
Required five-audience boolean map. Every enabled edit audience must also be enabled in view.
scope_task_access_policy.delete
Required five-audience boolean map. Every enabled delete audience must also be enabled in view.
scope_task_access_policy.view_empty_slots
Whether empty Scope cells are visible. Existing unassigned tasks are controlled separately by view.unassigned. Creating Scope tasks forces this true.
expected_lock_version
Optional update CAS token copied from lock_version. A mismatch returns 409 Conflict.
expected_updated_at
Optional update CAS token copied from updated_at. A mismatch returns 409 Conflict.
Which task status changes the permission can make.
all_statusesall_but_verifiedno_statuses
access.model_status_updates
Which model status changes the permission can make.
share_and_publish_modelshare_modelno_models
access.team_invite_access
Which teams the permission can invite users to.
any_teamown_teamno_teams
access.permission_assignment_access
Which permissions can be assigned when inviting or updating users.
equal_or_lowerviewers
access.team_member_visibility
Which team members the permission can see.
all_membersmanagers_and_ownno_members
access.team_visibility
Which teams the permission can see.
all_teamsall_but_prospectiveown_and_managers
access.scope_task_visibility
Legacy task-view field. Do not send it with scope_task_access_policy. Responses use no_scope_tasks as a fail-closed projection when a granular view mask has no exact legacy representation.
Update project permission: Updates a custom project permission. Requires PermissionWrite plus project permission access to manage permissions. Default Manager, Viewer, and Prospective permissions cannot be updated. Custom permissions always keep can_manage_permissions disabled. Send expected_lock_version and/or expected_updated_at from the last response to detect concurrent changes; stale tokens return 409 Conflict. The named task policy cannot be mixed with legacy task-access fields.
Scope
PermissionWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Optional fields: name, modules, capabilities, access, and scope_task_access_policy. At least one change field is required. expected_lock_version and expected_updated_at are conflict tokens, not changes.
Allowed Values
scope_task_access_policy.version
Must be 2.
scope_task_access_policy.view
Required booleans for direct_self, own_team, other_person, other_team, and unassigned. A task is visible when any matching audience is true.
scope_task_access_policy.edit
Required five-audience boolean map. Every enabled edit audience must also be enabled in view.
scope_task_access_policy.delete
Required five-audience boolean map. Every enabled delete audience must also be enabled in view.
scope_task_access_policy.view_empty_slots
Whether empty Scope cells are visible. Existing unassigned tasks are controlled separately by view.unassigned. Creating Scope tasks forces this true.
expected_lock_version
Optional update CAS token copied from lock_version. A mismatch returns 409 Conflict.
expected_updated_at
Optional update CAS token copied from updated_at. A mismatch returns 409 Conflict.
Which task status changes the permission can make.
all_statusesall_but_verifiedno_statuses
access.model_status_updates
Which model status changes the permission can make.
share_and_publish_modelshare_modelno_models
access.team_invite_access
Which teams the permission can invite users to.
any_teamown_teamno_teams
access.permission_assignment_access
Which permissions can be assigned when inviting or updating users.
equal_or_lowerviewers
access.team_member_visibility
Which team members the permission can see.
all_membersmanagers_and_ownno_members
access.team_visibility
Which teams the permission can see.
all_teamsall_but_prospectiveown_and_managers
access.scope_task_visibility
Legacy task-view field. Do not send it with scope_task_access_policy. Responses use no_scope_tasks as a fail-closed projection when a granular view mask has no exact legacy representation.
Delete project permission: Deletes a custom project permission. Requires PermissionWrite plus project permission access to manage permissions. Default Manager, Viewer, and Prospective permissions cannot be deleted. Deletion is blocked while users still have that permission. Optional expected_lock_version and expected_updated_at query parameters return 409 Conflict when the permission changed.
Scope
PermissionWrite
This write endpoint requires the listed scope on the key.
Required Params
expected_lock_version
Integer lock_version from the last project-permission response.
OR
expected_updated_at
ISO 8601 updated_at from the last project-permission response.
Manage docs, doc categories, doc sections, and their document tree.
Docs
GET
/external/v2/projects/:project_id/docs
List docs: Project docs. Positions are normalized to integers starting at 1, accessible_project_team_ids lists the teams that can access each doc, and comment_count fields sum root section comments across the doc.
Create doc: Creates a doc on the project. Requires DocsWrite plus project permission access to manage docs. Positions are 1-based and match the normalized positions returned by List docs; omitted position appends the new doc to the end.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title. Optional fields: description, position, and accessible_project_team_ids. If accessible_project_team_ids is omitted or null, the doc is accessible to all project teams. Every provided project team ID must belong to the project.
Update doc: Updates a project doc. Requires DocsWrite plus project permission access to manage docs. Positions are 1-based and match the normalized positions returned by List docs.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Optional fields: title, description, position, and accessible_project_team_ids. If title is provided, it cannot be blank. If accessible_project_team_ids is null, the doc becomes accessible to all project teams.
Delete doc: Deletes a project doc. Requires DocsWrite plus project permission access to manage docs. The doc must not have any sections; delete all sections first.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Create doc category: Creates a category within a project doc. Requires DocsWrite plus project permission access to manage doc categories. The doc must be visible to the authenticated user. Positions are 1-based within the category's parent; omitted position appends the category to the end.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title. Optional fields: description, parent_id, position, and unnumbered. If parent_id is omitted or null, the category is created at the doc root. If provided, parent_id must be another category in the same doc.
Update doc category: Updates a category within a project doc. Requires DocsWrite plus project permission access to manage doc categories. Positions are 1-based within the category's parent.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Optional fields: title, description, parent_id, position, and unnumbered. If title is provided, it cannot be blank. If parent_id is null, the category moves to the doc root. If provided, parent_id must be another category in the same doc and cannot be this category or one of its descendants.
Delete doc category: Deletes a doc category. Requires DocsWrite plus project permission access to manage doc categories. The category must not have child categories or sections; delete child doc items first.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
List doc sections: Sections within a project doc. Sections include assigned_user_ids, comment_count, and unresolved_comment_count. content_html is null for PDF and chart sections. Section filters accept one value only.
Create doc section: Creates a section within a project doc. Requires DocsWrite plus project permission access to create doc sections. The doc must be visible to the authenticated user. Positions are 1-based within the section's parent; omitted position appends the section to the end.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title. Optional fields: description, parent_id, content_html, position, status_id, section_type_id, and assigned_user_ids. If parent_id is omitted or null, the section is created at the doc root. If provided, parent_id must be a category or section in the same doc. Every assigned_user_ids value must be a project user who can access the doc. HTML content is sanitized before saving. To insert an existing project SmartField, include <smartfield data-key="Client"></smartfield> in content_html. Use the field key, not its ID, and HTML-escape attribute values. The Client sample requires that field to exist first. Custom and system fields can be referenced; display text comes from Plannerly, not the tag contents. Only data-key is accepted on the tag. Missing, blank, unknown or ambiguous keys return 422 INVALID_REQUEST without saving the section. References are project-scoped and participate in normal SmartField value propagation and section history. Use the SmartFields endpoints to create fields or change custom values; including a tag never creates or edits a field.
Update doc section: Updates a section within a project doc. Requires DocsWrite. Content, title, description, type, parent, and position changes require section edit access. Status changes require status permission. Assignment changes require assignment permission.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Optional fields: title, description, parent_id, content_html, position, status_id, section_type_id, and assigned_user_ids. If title is provided, it cannot be blank. If parent_id is null, the section moves to the doc root. If assigned_user_ids is provided, it replaces the current assignment list. HTML content is sanitized before saving. Providing content_html replaces the full section body, not just its SmartFields; omit it to preserve the body. Removing a tag removes that occurrence, not the project field. To insert an existing project SmartField, include <smartfield data-key="Client"></smartfield> in content_html. Use the field key, not its ID, and HTML-escape attribute values. The Client sample requires that field to exist first. Custom and system fields can be referenced; display text comes from Plannerly, not the tag contents. Only data-key is accepted on the tag. Missing, blank, unknown or ambiguous keys return 422 INVALID_REQUEST without saving the section. References are project-scoped and participate in normal SmartField value propagation and section history. Use the SmartFields endpoints to create fields or change custom values; including a tag never creates or edits a field.
Delete doc section: Deletes a doc section. Requires DocsWrite plus project permission access to create or delete doc sections. The section must not have child categories or sections; delete child doc items first.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Create scope row: Creates a folder, task, or group scope row. Requires ScopeWrite plus project permission access to manage scope rows. Positions are 1-based within the parent; omitted position appends the new scope row to the end. Send code as the non-prefixed code; full_code is generated and returned by the API.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: row_type. Optional fields for all row types: title, parent_id, position, and code. Optional fields for task and group rows only: subtitle and entity_type. row_type must be folder, task, or group. If title is omitted, a default title is used. full_code is response-only and cannot be sent.
Update scope row: Updates a scope row. Requires ScopeWrite plus project permission access to manage scope rows. Positions are 1-based within the parent; moving a row without a position appends it to the end of the new parent.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Optional fields: title, parent_id, position, code, subtitle, and entity_type. At least one field is required. parent_id cannot be the scope row or one of its descendants. subtitle and entity_type are allowed only for task and group rows. row_type and full_code are response-only for updates.
Delete scope row: Deletes a scope row. Requires ScopeWrite plus project permission access to manage scope rows. Descendant rows and dependent records are cleaned up.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
List scope tasks: List scope tasks for project. Geometry and accuracy are returned as direct scope task values, or null when geometry is not active for the task. Included information requirements contain is_checked for their assignment to each scope task.
Create scope task: Creates one scope task for a task or group scope row at one milestone. Requires ScopeWrite plus project permission access to manage scope tasks.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: scope_row_id, milestone_id. Optional fields: project_team_id, user_id, task_status_id, start_date, end_date, geometry, and accuracy. scope_row_id must be a task or group scope row. If either date is provided, both start_date and end_date are required, and end_date must be on or after start_date. geometry and accuracy are integer values from 1 to 4 and can be sent together or independently.
Get scope task: Fetch single scope task. Geometry and accuracy are returned as direct scope task values, or null when geometry is not active for the task. Included information requirements contain is_checked for their assignment to this scope task.
Update scope task: Updates a scope task. Requires ScopeWrite plus project permission access for the fields being updated. Assignment fields require permission to manage scope task assignees. Status changes also honor task status update permissions. Updating a group scope task can also update the affected child tasks.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
At least one field is required. Optional fields: milestone_id, project_team_id, user_id, task_status_id, start_date, end_date, geometry, and accuracy. Send project_team_id or user_id as null to clear the assignment. If either date is provided, both start_date and end_date are required; send both as null to clear the dates. geometry and accuracy can be sent together or independently; the missing value is kept from the task's current geometry/accuracy stage. scope_row_id, parent_id, and is_verified are response-only.
Delete scope task: Deletes a scope task. Requires ScopeWrite plus project permission access to manage scope tasks. If deleting a group task also deletes child tasks, the response includes the deleted group and child tasks.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
List a scope task's comments: Read comments and replies from a task card. By default, only comments from the Scope module are returned, not Verify comments. Use filter[module]=verify to read Verify comments instead. Requires ScopeRead and Scope module access; Verify comments additionally require VerifyRead and Verify module access. The key owner's project and task access also applies.
Filters
filter[module] (scope or verify; default: scope)Reference
Optional filters supported on this collection endpoint.
Task ID, matching the scope-tasks endpoint. This is not a scope-row ID.
parent_id
string or null
ID of the comment that starts this conversation. Null means this comment starts the conversation; a non-null value means it is a reply.
task_field_id
string or null
Task field this conversation relates to, such as Dates or Checklist. Use the task-fields endpoint to look up its title. Null means a general task comment.
module
string
Where the comment was posted: scope or verify.
description
string
Comment text. May be empty for an attachment-only comment. Mentions use @[Alex Morgan](USER_ID), which the app displays as @Alex Morgan.
author
object
The author's id and name. The name is recorded when the comment is posted and may differ from their current profile.
title
string or null
Conversation title, available on the starting comment only. May be null when no title is available; the app can display a preview of the comment text instead.
is_resolved
boolean or null
On the starting comment: true means Resolved; false means Unresolved. Null on replies: check the starting comment's status, rather than treating null as Unresolved.
resolved_at
timestamp or null
When the conversation was resolved. Null for unresolved conversations and replies.
resolved_by_user_id
string or null
User who resolved the conversation, if recorded. Null for unresolved conversations and replies.
attachment
object or null
Attached file with filename, content_type (for example application/pdf), and url. Null means no attachment. Private download URLs expire after one hour; fetch the comments again for fresh URLs.
created_at / updated_at
timestamp
When this comment was created and last updated, in ISO 8601 format.
Response and integration notes
No request body. Returns the standard data, pagination, and meta envelope. limit defaults to 100 (maximum 250). Pass pagination.next_cursor as cursor until pagination.has_more is false, keeping the task and module filter unchanged. Select one module per request; arrays and comma-separated lists are not supported.
Comments and replies are separate records, newest first by created_at and then id. A reply may appear before the starting comment or on another page. Match each reply's parent_id to the starting comment's id after collecting all pages. Comments on child tasks are not included.
This endpoint only reads comments; it cannot create, edit, delete, resolve, or mark them as read. There is no updated-since filter or deletion feed. To synchronize edits and deletions, periodically fetch all pages again, allowing for access changes.
Comment text, names, and file metadata are user-provided content. Escape or sanitize them before displaying HTML.
List LOD: Lists the localized LOD options for the project's standard. Use geometry_value and accuracy_value when setting geometry or accuracy on scope tasks.
List task fields: Project-level task field definitions. These are the fields that can be active on scope tasks, depending on the field applies_to value and any field exclusions inherited from the task, scope row, or parent scope rows. Geometry and accuracy are scope task values, not task fields in this API.
Create task field: Creates a project-level task field definition. Requires ScopeWrite plus project permission access to manage task fields. Field settings are validated and sanitized before saving.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title, field_type. Optional fields: description, color, applies_to, position, and settings. position is 1-based; omitted position appends the field to the end. settings depends on field_type.
Allowed Values
field_type
Type of task field to create.
textnumberbooleandatecostpicklisturlsfiles
applies_to
Which scope row task types can use the field. Defaults to task_rows.
task_rowsgroup_rowsall_rows
settings.options
Picklist fields use an array of option objects with label, color, and optional is_default. Only one option can set is_default to true.
Update task field: Updates an editable project-level task field definition. Requires ScopeWrite plus project permission access to manage task fields. System task fields cannot be updated.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
At least one field is required. Optional fields: title, description, color, position, and settings. field_type and applies_to are create-only. Picklist updates cannot remove existing options.
Delete task field: Deletes an editable project-level task field definition. Requires ScopeWrite plus project permission access to manage task fields. Related work package filters are cleaned up.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
List task field values: Task field values for one scope task. The response includes only task fields that are active on that task; exclusions on the task, its scope row, or parent scope rows hide the field. Geometry and accuracy are returned on the scope task itself, not in this task field list.
Update task field value: Creates or updates the value for one active task field on one scope task. Requires ScopeWrite plus project permission access to manage scope tasks. Value writes are blocked when the field is disabled for the task. File field values are not exposed through this endpoint yet.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: value. Send values using the matching JSON type: text/date values as strings, number/cost values as numbers, boolean values as booleans, picklists as an object with integer option_index, and URLs as an array of objects with string label and url. For range dates, send value as an object with string start and end. Send null to clear a value.
Delete task field value: Clears an existing task field value from one scope task. Requires ScopeWrite plus project permission access to manage scope tasks. The task field must still be active on the task.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
List checklist tasks: Lists reusable checklist tasks in the project. Requires ScopeRead and Scope module access. Supports standard cursor pagination. Each resource includes scope_task_ids as an array (empty when unassigned), containing only scope tasks visible to the key owner. These are scope-task IDs, not scope-row IDs. Checked state and target date (due_date) belong to each assignment and are available through the nested scope-task endpoints, not this shared catalog.
Get checklist task: Fetches one checklist task in the project, including scope_task_ids, always an array of visible assigned scope-task IDs. Requires ScopeRead and Scope module access.
Create or assign checklist task: Creates or reuses a checklist task by description and assigns it to the specified scope tasks. Requires ScopeWrite, Scope module access, and edit access to every target (or account-level project access). Every target must exist in this project and have checklists enabled. The whole request succeeds or fails together. Returns 201 when a definition or assignment is added; 200 if already assigned. Repeating the request does not duplicate assignments or reset checked state or target dates.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: description (nonblank string) and scope_task_ids (one UUID string or an array of 1–100 UUID strings). Optional due_date sets the target date on new assignments only: a valid calendar date in YYYY-MM-DD format (year 0001–9999), or null. No timezone conversion is applied. Duplicate IDs are ignored. Surrounding description whitespace is trimmed; matching is case-sensitive and reuses the existing task within this project. New assignments start unchecked. Only these fields are accepted inside data.
Update checklist task: Renames a checklist task everywhere it is used, without changing assignment or checked state. Requires ScopeWrite, Scope module access, permission to manage and edit scope tasks, and edit access to every scope task using it (or account-level project access). Returns 200. Conflicts never merge or reassign existing tasks.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required field: description, a nonblank string, trimmed and case-sensitive. Keeping the current description is allowed; renaming to another task's description returns 409 DUPLICATE_CHECKLIST_TASK. Assignment IDs and checked states are unchanged. Do not pass scope_task_ids here.
Example Request Body
{
"data": {
"description": "Confirm model coordinates"
}
}
Remove checklist task assignments: Removes only the selected assignments, preserving all other assignments and checked states. Requires ScopeWrite and edit access to every target. Validates the whole batch before any changes. Returns 200 with the checklist task's remaining visible scope_task_ids and meta.removed_scope_task_ids. An already absent assignment is a no-op while the checklist task still exists. Normal cleanup removes the checklist task after its last assignment is removed; subsequent requests for that ID return 404. Omitting IDs never means delete everywhere.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required field: scope_task_ids, one UUID string or an array of 1–100 UUID strings. No additional fields are accepted inside data.
List a scope task's checklist tasks: Lists checklist tasks assigned to this scope task, with cursor pagination and ScopeRead access. Adds is_checked and due_date (target date as YYYY-MM-DD, or null when unset) for this assignment to each resource. Resource id is the checklist task ID, not an internal assignment ID. scope_task_ids remains an array of all visible scope tasks using that checklist task. Different assignments of the same checklist task can have different dates.
Create or assign to one scope task: Single-task shortcut for create-or-assign. Uses the scope task in the path; the same validation, reuse, permissions and idempotency rules apply. Returns 201 when something is added, otherwise 200. Includes is_checked and due_date for this task.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required field: description. Optional due_date: YYYY-MM-DD calendar date or null; only used for a new assignment. Do not pass scope_task_ids; the path identifies the target. To change an existing assignment's date, use PATCH.
Update checklist checked state or target date: Changes checked state and/or target date only on this scope task. Requires ScopeWrite, edit access to the scope task, an existing assignment and an active checklist field. Returns 200, including is_checked and due_date. Never renames shared text or changes another assignment.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Provide at least one of is_checked (JSON boolean) or due_date (valid YYYY-MM-DD calendar date, year 0001–9999). Set due_date to null to clear it; omitted fields remain unchanged. No timezone conversion is applied. No additional fields are accepted inside data.
Remove checklist task from one scope task: Single-task shortcut for removing an assignment. Requires ScopeWrite and edit access to the scope task. No request body is needed. Leaves other tasks unchanged; normal final-assignment cleanup still applies. Returns 200 with remaining visible scope_task_ids, is_checked and due_date null (no longer assigned here), and meta.removed_scope_task_ids. A missing checklist task returns 404.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Task information requirements: Requirements linked to task. Each requirement includes read-only is_checked: true when its assignment has a completed task status, false otherwise (including a missing status). This is the task-card checkbox, not the automated model-verification result. The same requirement can be checked on one scope task and unchecked on another. Also returned with include=information_requirements on scope-task list and detail reads; omitted from project-level requirement definitions.
Assign information requirement to task: Assigns one existing project information requirement to one scope task. Requires ScopeWrite plus project permission access to manage information requirement assignments. If the requirement row does not already exist under the related scope row, it is created before the task assignment is added.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: information_requirement_id. The target scope task must be a task row, not a group or requirement assignment row. Re-sending an already assigned requirement is safe and returns the existing assignment.
Remove information requirement from task: Unassigns one information requirement from one scope task. Requires ScopeWrite plus project permission access to manage information requirement assignments. The project-level information requirement and requirement scope row are not deleted.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Task model status: Model-based status summary for a task. Response <code>data</code> is <code>null</code> when no model status exists for the selected model or model version, including when the task has no linked elements for it.
Required Params
model_id
Use the id returned by /projects/:project_id/models to select the latest indexed version for a model.
OR
model_version_id
Use the id returned by /projects/:project_id/models/:model_id/model_versions to target one specific indexed model version.
Create task status: Creates a task status. Requires ScopeWrite plus project permission access to manage task statuses. Positions are 1-based in the full task status list; backlog and verified keep their fixed positions, so created statuses are placed between them.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title. Optional fields: color and position. Omitted color defaults to the Plannerly default gray. Omitted position appends before the verified status.
Update task status: Updates a task status. Requires ScopeWrite plus project permission access to manage task statuses. Regular statuses can update title, color, and position. Backlog can update title and color, but cannot move. Verified cannot be updated.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
At least one field is required. Optional fields: title, color, and position. Positions are normalized after updates.
Delete task status: Deletes a regular task status. Requires ScopeWrite plus project permission access to manage task statuses. Backlog and verified cannot be deleted. Deletion is blocked while tasks or work packages still use the status.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Create milestone group: Creates a milestone group. Requires ScopeWrite plus project permission access to manage milestones. Positions are 1-based and normalized after create.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title. Optional fields: description and position. Omitted position appends the group to the end.
Update milestone group: Updates a milestone group. Requires ScopeWrite plus project permission access to manage milestones. Positions are 1-based and normalized after update.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
At least one field is required. Optional fields: title, description, and position.
Delete milestone group: Deletes a milestone group. Requires ScopeWrite plus project permission access to manage milestones. Related milestones move to the nearest remaining group, or become ungrouped when the final group is deleted.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Create milestone: Creates a milestone. Requires ScopeWrite plus project permission access to manage milestones. Positions are 1-based inside the milestone group and normalized after create.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title. Optional fields: description, milestone_group_id, start_date, end_date, and position. If one date is sent, both start_date and end_date are required. Dates can also both be null or omitted.
Update milestone: Updates a milestone. Requires ScopeWrite plus project permission access to manage milestones. Moving to a different milestone group without a position appends the milestone to the end of the new group.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
At least one field is required. Optional fields: title, description, milestone_group_id, start_date, end_date, and position. If one date is sent, both start_date and end_date are required. Send both dates as null to clear milestone dates.
Delete milestone: Deletes a milestone. Requires ScopeWrite plus project permission access to manage milestones. Related scope tasks are cleaned up, and deletion is blocked while saved work package filters still require the milestone.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Manage requirement units, tags, and information requirement definitions.
Requirement Units
GET
/external/v2/requirement-units
List requirement units: Global requirement units available for information requirements and number task fields. Use the returned id as unit_id on write requests.
Create requirement tag: Creates a project-level requirement tag. Requires ScopeWrite plus project permission access to manage information requirements.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title, color. color must be a hex color like #ef4444.
Update requirement tag: Updates a project-level requirement tag. Requires ScopeWrite plus project permission access to manage information requirements.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
At least one field is required. Optional fields: title, color. color must be a hex color like #ef4444.
Delete requirement tag: Deletes a project-level requirement tag. Requires ScopeWrite plus project permission access to manage information requirements. Deletion is blocked while the tag is used by a work package.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Create information requirement: Creates a project-level information requirement. Requires ScopeWrite plus project permission access to manage information requirements. Optional requirement_tag_ids link the new requirement to existing requirement tags.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Required fields: title. Optional fields: description, type, data_type, value, property_category, unit_id, and requirement_tag_ids. Omitted type defaults to ifc; omitted data_type defaults to any. For boolean, send JSON true or false for an exact value; omit value or send null to allow either true or false. Use /external/v2/requirement-units to find valid unit IDs.
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
-d '{"data":{"title":"Curtain Wall Fire Rating","description":"Provide tested fire rating for the selected assembly","type":"classification","data_type":"number_between","value":{"min":1,"max":3},"property_category":"Performance","unit_id":42,"requirement_tag_ids":["4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a"]}}' \
https://api.plannerly.com/external/v2/projects/PROJECT_ID/information-requirements
Update information requirement: Updates a project-level information requirement. Requires ScopeWrite plus project permission access to manage information requirements. If requirement_tag_ids is provided, it replaces the requirement's current tag list. Related model checks are refreshed after the update.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Optional fields: title, description, type, data_type, value, property_category, unit_id, and requirement_tag_ids. At least one field is required. If data_type changes without value, the previous value is cleared; for boolean, it defaults to allowing either true or false.
Delete information requirement: Deletes a project-level information requirement. Requires ScopeWrite plus project permission access to manage information requirements. Related task assignments, requirement scope rows, tag links, and model verification data are cleaned up.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Work with saved work package filters and model/version data used by Verify workflows.
Work Packages
GET
/external/v2/projects/:project_id/work-packages
List work packages: Project work packages. Responses include the saved filter properties: dates, milestones, project teams, users, task statuses, excluded scope rows, requirement tags, task fields, and visible model IDs.
Update work package: Updates a work package and its saved filter properties. Requires ScopeWrite plus project permission access to manage work packages. Updating model_ids also requires VerifyRead plus verify visibility.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
Body
application/json
At least one field is required. Optional fields: title, description, compact_view, include_unscoped_tasks, and filters. Optional filter fields: date_range, milestone_ids, project_team_ids, user_ids, task_status_ids, excluded_scope_row_ids, requirement_tag_ids, requirement_tag_match, task_field_ids, and model_ids. Send date_range as null to clear dates. requirement_tag_match must be any or all.
Delete work package: Deletes a work package. Requires ScopeWrite plus project permission access to manage work packages. Related model filters and chart metric filters are cleaned up.
Scope
ScopeWrite
This write endpoint requires the listed scope on the key.
List SmartFields: Lists project-level SmartFields, with standard cursor pagination. Requires DocsRead and Docs module access. Values are strings or null; formatted values are sanitized HTML. read_only identifies system-calculated fields, not the key owner's permissions. Smart References have field_type system, system_field_type section_ref, reference_plan_item_id (the target section/category ID) and reference_doc_id (its document ID). Reference IDs are null for other fields. References to hidden, deleted or foreign targets are omitted; requesting one by ID returns 404. No section contents or assignment IDs are included.
Get SmartField: Fetches one field and its current canonical value. Requires DocsRead. During a background update, propagation contains id, status, processed_count and total_count. Poll this endpoint until propagation is null and value matches the requested value. A failed status requires review/retry in the Plannerly SmartFields editor; do not treat 202 as completed.
Create SmartField: Creates a custom project SmartField or a Smart Reference. Requires DocsWrite, Docs module access and a project membership with Manage SmartFields permission. Returns 201 for creation, or 200 when reusing a Smart Reference to the same target; custom duplicate keys or ambiguous reference keys return 409 DUPLICATE_SMART_FIELD. Creating a field does not insert it into document sections. Insert references using content_html on the existing Create/Update doc section endpoints, as documented under Doc Sections.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Body
application/json
For a custom field, required: key, nonblank text up to 255 bytes without markup, double quotes or control characters; surrounding whitespace is trimmed. Optional: field_type (defaults to short_text), value (string or null, maximum 64 KB), and link_url (hyperlink fields only, string or null, maximum 64 KB). Values use the existing SmartField text representation, including date and boolean fields; do not send objects, arrays or JSON booleans. For a Smart Reference, send only field_type: system, system_field_type: section_ref and reference_plan_item_id: TARGET_UUID inside data. The target must be an accessible, active section or category in this project; unavailable targets return 404. Plannerly generates the key and display value. Other system types and supplied keys/values are rejected. Use the returned key in the smartfield tag; target IDs in HTML cannot override it. Smart References remain read-only: rename/reorder the target through normal Docs operations, not PATCH SmartField. Retargeting is not supported; create/reuse another reference and replace the tag instead.
Allowed Values
field_type
Custom type, or system only with system_field_type section_ref; fixed after creation through this API.
Update SmartField value: Updates a custom field using the normal document permission, version-history and published-to-shared behavior. Requires DocsWrite and Manage SmartFields. Every referenced active section must be visible and its document unlocked; at least one must be editable. System-calculated fields are read-only: update their underlying project/team/milestone instead. Key renames, type changes and deletion are not supported here.
Scope
DocsWrite
This write endpoint requires the listed scope on the key.
Body
application/json
Provide value and/or link_url using the create field formats. Omitted fields stay unchanged; value null clears the value. Returns 200 for synchronous/no-op writes. Changes affecting more than 100 sections return 202 and use background propagation; the canonical value stays unchanged until completion. Repeating the same pending write returns its existing progress, while a different write returns 409 SMART_FIELD_PROPAGATION_CONFLICT. GET requires DocsRead to poll progress.
409 checklist rename conflict: DUPLICATE_CHECKLIST_TASK. No records are merged or removed on a conflict. Checklist creation reuses a matching description instead.
422 invalid request body or field value.
Quick Start
Typical sequence: list projects, choose a project id, then query project-scoped resources.
# 1) list projects
curl -H "Authorization: Bearer plly_user_xxx" \
https://api.plannerly.com/external/v2/projects
# 2) list milestone groups for one project
curl -H "Authorization: Bearer plly_user_xxx" \
https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestone-groups
# 3) list scope tasks for one project
curl -H "Authorization: Bearer plly_user_xxx" \
https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks