Plannerly External API

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.

  • Required: Authorization: Bearer <api_key>.
  • Read scopes: CoreRead, DocsRead, ScopeRead, VerifyRead.
  • Write scopes: TeamWrite, PermissionWrite, ProjectWrite, DocsWrite, ScopeWrite.
  • Write limits: 30 write requests per minute per key. Invite requests are separately limited to 10 requests per minute per key.
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects

Base URL

Use the API host that matches where your Plannerly account is hosted. All endpoint paths below are relative to one of these base URLs:

  • Default: https://api.plannerly.com/external/v2
  • Canada servers: https://api.ca.plannerly.com/external/v2
  • 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.
  • Example: /projects/:project_id/scope-tasks?include=information_requirements,fields,scope_row expands supported scope task relationships.

Filters

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
  • Unsupported filter names return 400 INVALID_FILTER.
  • Example: /projects/:project_id/scope-tasks?filter[task_status_id]=TASK_STATUS_ID&filter[milestone_id]=MILESTONE_ID
  • Example: /projects/:project_id/information-requirements?filter[requirement_tag_id]=REQUIREMENT_TAG_ID

Endpoints

Complete route list for currently exposed external/v2 endpoints.

Project Setup

Create and find the accounts, workspaces, and projects that contain the rest of the API resources.

Accounts
GET
/external/v2/accounts

List accounts: Returns accounts where the authenticated user can see at least one non-archived project. Accounts expose only id and name.

Example Response
{
  "data": [
    {
      "id": "87ed1511-fba8-4afd-b77f-044dd64f65f8",
      "name": "Acme Design Group"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/accounts
GET
/external/v2/accounts/:id

Get account: Single account visible to the authenticated user. Accounts expose only id and name.

Example Response
{
  "data": {
    "id": "87ed1511-fba8-4afd-b77f-044dd64f65f8",
    "name": "Acme Design Group"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/accounts/ID
GET
/external/v2/accounts/:account_id/users

List account users: Returns people who are members of the account. The account must be visible to the authenticated user.

Example Response
{
  "data": [
    {
      "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "name": "Alex Morgan",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/accounts/ACCOUNT_ID/users
POST
/external/v2/accounts/:account_id/users

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.
Example Request Body
{
  "data": {
    "users": [
      {
        "email": "[email protected]",
        "name": "Avery Nguyen",
        "phone_number": "+1 555 0100",
        "position_title": "Design Lead"
      },
      {
        "email": "[email protected]"
      }
    ]
  }
}
Example Response Body
{
  "data": [
    {
      "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "name": "Alex Morgan",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "id": "8d57fb0a-f45e-4203-ae7c-ad4ca9582958",
      "name": "Jordan Lee",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8",
    "invited_count": 2,
    "created_count": 2,
    "existing_count": 0
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"users":[{"email":"[email protected]","name":"Avery Nguyen","phone_number":"+1 555 0100","position_title":"Design Lead"},{"email":"[email protected]"}]}}' \
  https://api.plannerly.com/external/v2/accounts/ACCOUNT_ID/users
DELETE
/external/v2/accounts/:account_id/users

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.
  • Body
    application/json
    Required fields: user_id.
Example Request Body
{
  "data": {
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
  }
}
Example Response Body
{
  "data": {
    "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "name": "Alex Morgan",
    "email": "[email protected]",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"user_id":"fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"}}' \
  https://api.plannerly.com/external/v2/accounts/ACCOUNT_ID/users
Workspaces
GET
/external/v2/workspaces

List workspaces: Returns workspaces visible to the authenticated user in this region.

Example Response
{
  "data": [
    {
      "id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd",
      "title": "Architecture Workspace",
      "project_count": 6,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/workspaces
POST
/external/v2/workspaces

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.
  • Body
    application/json
    Required fields: account_id, title.
Example Request Body
{
  "data": {
    "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8",
    "title": "Architecture Workspace"
  }
}
Example Response Body
{
  "data": {
    "id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd",
    "title": "Architecture Workspace",
    "project_count": 0,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8",
    "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"account_id":"87ed1511-fba8-4afd-b77f-044dd64f65f8","title":"Architecture Workspace"}}' \
  https://api.plannerly.com/external/v2/workspaces
GET
/external/v2/workspaces/:id

Get workspace: Single workspace visible to the authenticated user in this region.

Example Response
{
  "data": {
    "id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd",
    "title": "Architecture Workspace",
    "project_count": 6,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/workspaces/ID
GET
/external/v2/workspaces/:workspace_id/users

List workspace users: Returns users who are members of the workspace. The workspace must be visible to the authenticated user.

Example Response
{
  "data": [
    {
      "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "name": "Alex Morgan",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/workspaces/WORKSPACE_ID/users
POST
/external/v2/workspaces/:workspace_id/users

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.
Example Request Body
{
  "data": {
    "users": [
      {
        "email": "[email protected]",
        "name": "Avery Nguyen",
        "phone_number": "+1 555 0100",
        "position_title": "Design Lead"
      },
      {
        "email": "[email protected]"
      }
    ]
  }
}
Example Response Body
{
  "data": [
    {
      "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "name": "Alex Morgan",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "id": "8d57fb0a-f45e-4203-ae7c-ad4ca9582958",
      "name": "Jordan Lee",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd",
    "invited_count": 2,
    "created_count": 2,
    "existing_count": 0
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"users":[{"email":"[email protected]","name":"Avery Nguyen","phone_number":"+1 555 0100","position_title":"Design Lead"},{"email":"[email protected]"}]}}' \
  https://api.plannerly.com/external/v2/workspaces/WORKSPACE_ID/users
DELETE
/external/v2/workspaces/:workspace_id/users

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.
  • Body
    application/json
    Required fields: user_id.
Example Request Body
{
  "data": {
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
  }
}
Example Response Body
{
  "data": {
    "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "name": "Alex Morgan",
    "email": "[email protected]",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"user_id":"fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"}}' \
  https://api.plannerly.com/external/v2/workspaces/WORKSPACE_ID/users
Projects
GET
/external/v2/projects

List projects: Returns non-archived projects visible to the authenticated user in this region.

Example Response
{
  "data": [
    {
      "id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
      "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8",
      "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd",
      "title": "Healthcare Tower - Phase 1",
      "archived": false,
      "address": "100 Main St, Austin, TX",
      "description": "Design coordination and delivery scope for core and shell",
      "standard": "LOD US AIA",
      "timezone": "America/Chicago",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects
POST
/external/v2/projects

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.
  • Body
    application/json
    Required fields: workspace_id, title. Optional fields: description.
Example Request Body
{
  "data": {
    "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd",
    "title": "Healthcare Tower - Phase 1",
    "description": "Design coordination and delivery scope for core and shell"
  }
}
Example Response Body
{
  "data": {
    "id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8",
    "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd",
    "title": "Healthcare Tower - Phase 1",
    "archived": false,
    "address": "100 Main St, Austin, TX",
    "description": "Design coordination and delivery scope for core and shell",
    "standard": "LOD US AIA",
    "timezone": "America/Chicago",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"workspace_id":"e8a7f55b-c27f-4558-a5fa-a387a8ba95fd","title":"Healthcare Tower - Phase 1","description":"Design coordination and delivery scope for core and shell"}}' \
  https://api.plannerly.com/external/v2/projects
GET
/external/v2/projects/:id

Get project: Single non-archived project visible to the authenticated user in this region.

Example Response
{
  "data": {
    "id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8",
    "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd",
    "title": "Healthcare Tower - Phase 1",
    "archived": false,
    "address": "100 Main St, Austin, TX",
    "description": "Design coordination and delivery scope for core and shell",
    "standard": "LOD US AIA",
    "timezone": "America/Chicago",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/ID
PATCH
/external/v2/projects/:id

Update project: Updates project title and description. Requires ProjectWrite plus project permission access to manage the project.

  • Scope
    ProjectWrite
    This write endpoint requires the listed scope on the key.
  • Body
    application/json
    At least one field is required. Allowed fields: title, description.
Example Request Body
{
  "data": {
    "title": "Healthcare Tower - Phase 1",
    "description": "Updated design coordination and delivery scope"
  }
}
Example Response Body
{
  "data": {
    "id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "account_id": "87ed1511-fba8-4afd-b77f-044dd64f65f8",
    "workspace_id": "e8a7f55b-c27f-4558-a5fa-a387a8ba95fd",
    "title": "Healthcare Tower - Phase 1",
    "archived": false,
    "address": "100 Main St, Austin, TX",
    "description": "Design coordination and delivery scope for core and shell",
    "standard": "LOD US AIA",
    "timezone": "America/Chicago",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Healthcare Tower - Phase 1","description":"Updated design coordination and delivery scope"}}' \
  https://api.plannerly.com/external/v2/projects/ID

Project Access

Manage the people, teams, and permission templates that control project access.

Project Teams
GET
/external/v2/projects/:project_id/project-teams

List project teams: Teams configured for the project.

  • Includes
    include=users Reference
    Use these values to expand related resources in the same response.
Example Response
{
  "data": [
    {
      "id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
      "title": "Architect of Record",
      "team_name": "AOR",
      "abbreviation": "AOR",
      "highlight_color": "#1d4ed8",
      "image_url": "https://files.example.com/teams/aor.png",
      "position": 1,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-teams
POST
/external/v2/projects/:project_id/project-teams

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.
Example Request Body
{
  "data": {
    "title": "Architect of Record",
    "team_name": "AOR",
    "abbreviation": "AOR",
    "highlight_color": "#1d4ed8",
    "position": 1
  }
}
Example Response Body
{
  "data": {
    "id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
    "title": "Architect of Record",
    "team_name": "AOR",
    "abbreviation": "AOR",
    "highlight_color": "#1d4ed8",
    "image_url": "https://files.example.com/teams/aor.png",
    "position": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Architect of Record","team_name":"AOR","abbreviation":"AOR","highlight_color":"#1d4ed8","position":1}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-teams
GET
/external/v2/projects/:project_id/project-teams/:id

Get project team: Single project team.

  • Includes
    include=users Reference
    Use these values to expand related resources in the same response.
Example Response
{
  "data": {
    "id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
    "title": "Architect of Record",
    "team_name": "AOR",
    "abbreviation": "AOR",
    "highlight_color": "#1d4ed8",
    "image_url": "https://files.example.com/teams/aor.png",
    "position": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-teams/ID
PATCH
/external/v2/projects/:project_id/project-teams/:id

Update project team: Updates a project team. Requires TeamWrite plus project permission access to manage teams.

  • Scope
    TeamWrite
    This write endpoint requires the listed scope on the key.
  • Body
    application/json
    Optional fields: title, team_name, abbreviation, highlight_color, position. At least one field is required.
Example Request Body
{
  "data": {
    "title": "Architect of Record",
    "team_name": "AOR",
    "abbreviation": "AOR",
    "highlight_color": "#1d4ed8",
    "position": 2
  }
}
Example Response Body
{
  "data": {
    "id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
    "title": "Architect of Record",
    "team_name": "AOR",
    "abbreviation": "AOR",
    "highlight_color": "#1d4ed8",
    "image_url": "https://files.example.com/teams/aor.png",
    "position": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Architect of Record","team_name":"AOR","abbreviation":"AOR","highlight_color":"#1d4ed8","position":2}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-teams/ID
DELETE
/external/v2/projects/:project_id/project-teams/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
    "title": "Architect of Record",
    "team_name": "AOR",
    "abbreviation": "AOR",
    "highlight_color": "#1d4ed8",
    "image_url": "https://files.example.com/teams/aor.png",
    "position": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-teams/ID
Project Team Users
GET
/external/v2/projects/:project_id/project-teams/:id/users

Users in project team: Users belonging to the team.

Example Response
{
  "data": [
    {
      "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "project_permission_id": "7d47f312-238d-44ac-b677-457b4498f931",
      "name": "Avery Nguyen",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-teams/ID/users
PATCH
/external/v2/projects/:project_id/project-teams/:id/users/:user_id

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.
Example Request Body
{
  "data": {
    "project_permission_id": "7d47f312-238d-44ac-b677-457b4498f931"
  }
}
Example Response Body
{
  "data": {
    "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_permission_id": "7d47f312-238d-44ac-b677-457b4498f931",
    "name": "Avery Nguyen",
    "email": "[email protected]",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"project_permission_id":"7d47f312-238d-44ac-b677-457b4498f931"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-teams/ID/users/:user_id
POST
/external/v2/projects/:project_id/project-teams/:id/users

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.
Example Request Body
{
  "data": {
    "users": [
      {
        "email": "[email protected]",
        "name": "Avery Nguyen",
        "phone_number": "+1 555 0100",
        "position_title": "Design Lead",
        "project_permission_id": "7d47f312-238d-44ac-b677-457b4498f931"
      },
      {
        "email": "[email protected]",
        "project_permission_id": "2d6f98d1-016b-45dc-870c-4832952497f1"
      }
    ]
  }
}
Example Response Body
{
  "data": [
    {
      "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "project_permission_id": "7d47f312-238d-44ac-b677-457b4498f931",
      "name": "Avery Nguyen",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "id": "8d57fb0a-f45e-4203-ae7c-ad4ca9582958",
      "project_permission_id": "7d47f312-238d-44ac-b677-457b4498f931",
      "name": "Jordan Lee",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "invited_count": 2,
    "added_count": 2,
    "existing_count": 0
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"users":[{"email":"[email protected]","name":"Avery Nguyen","phone_number":"+1 555 0100","position_title":"Design Lead","project_permission_id":"7d47f312-238d-44ac-b677-457b4498f931"},{"email":"[email protected]","project_permission_id":"2d6f98d1-016b-45dc-870c-4832952497f1"}]}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-teams/ID/users
DELETE
/external/v2/projects/:project_id/project-teams/:id/users

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.
  • Body
    application/json
    Required fields: user_id.
Example Request Body
{
  "data": {
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
  }
}
Example Response Body
{
  "data": {
    "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_permission_id": "7d47f312-238d-44ac-b677-457b4498f931",
    "name": "Avery Nguyen",
    "email": "[email protected]",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"user_id":"fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-teams/ID/users
Project Users
GET
/external/v2/projects/:project_id/users

List project users: Users associated with the project. project_permission_id is from the first project user entry for that user on the project.

Example Response
{
  "data": [
    {
      "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "project_permission_id": "7d47f312-238d-44ac-b677-457b4498f931",
      "name": "Avery Nguyen",
      "email": "[email protected]",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/users
GET
/external/v2/projects/:project_id/users/:id

Get project user: Single user in project context. project_permission_id is from the first project user entry for that user on the project.

Example Response
{
  "data": {
    "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_permission_id": "7d47f312-238d-44ac-b677-457b4498f931",
    "name": "Avery Nguyen",
    "email": "[email protected]",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/users/ID
Project Permissions
GET
/external/v2/projects/:project_id/project-permissions

List project permissions: Permissions available on the project. Use these ids as optional project_permission_id values when adding a user to a team.

Example Response
{
  "data": [
    {
      "id": "0ccaa48b-2b65-47f0-ae22-31f3901d00f3",
      "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
      "name": "Manager",
      "permission_type": "manager",
      "modules": {
        "scope": true,
        "docs": true,
        "files": true,
        "verify": true
      },
      "capabilities": {
        "can_manage_project": true,
        "can_manage_teams": true,
        "can_manage_permissions": true,
        "can_create_or_delete_doc_sections": true,
        "can_manage_doc_categories": true,
        "can_assign_doc_sections": true,
        "can_view_in_progress_doc_sections": true,
        "can_view_in_progress_doc_comments": true,
        "can_manage_smart_fields": true,
        "can_manage_docs": true,
        "can_manage_information_requirements": true,
        "can_manage_scope_rows": true,
        "can_manage_scope_tasks": true,
        "can_manage_scope_task_assignees": true,
        "can_manage_task_fields": true,
        "can_manage_milestones": true,
        "can_manage_scope_row_linking_rules": true,
        "can_manage_information_requirement_assignments": true,
        "can_manage_task_statuses": true,
        "can_manage_work_packages": true,
        "can_manage_work_package_filters": true,
        "can_manage_work_package_models": true,
        "can_manage_work_package_mapping_rules": true,
        "can_manage_models": true,
        "can_view_in_progress_models": true,
        "can_manage_model_linking_rules": true,
        "can_manage_files": true,
        "can_add_file_signatories": true,
        "can_resolve_doc_comments": true
      },
      "access": {
        "docs_visibility": "all_docs",
        "files_visibility": "all_files",
        "doc_section_editing": "all_sections",
        "doc_status_management": "share_and_publish",
        "task_status_updates": "all_statuses",
        "model_status_updates": "share_and_publish_model",
        "team_invite_access": "any_team",
        "permission_assignment_access": "equal_or_lower",
        "team_member_visibility": "all_members",
        "team_visibility": "all_teams"
      },
      "scope_task_access_policy": {
        "version": 2,
        "view": {
          "direct_self": true,
          "own_team": true,
          "other_person": false,
          "other_team": false,
          "unassigned": true
        },
        "edit": {
          "direct_self": true,
          "own_team": true,
          "other_person": false,
          "other_team": false,
          "unassigned": true
        },
        "delete": {
          "direct_self": true,
          "own_team": true,
          "other_person": false,
          "other_team": false,
          "unassigned": false
        },
        "view_empty_slots": true
      },
      "lock_version": 4,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-permissions
GET
/external/v2/projects/:project_id/project-permissions/:id

Get project permission: Single project permission by id. The permission must belong to the project.

Example Response
{
  "data": [
    {
      "id": "0ccaa48b-2b65-47f0-ae22-31f3901d00f3",
      "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
      "name": "Manager",
      "permission_type": "manager",
      "modules": {
        "scope": true,
        "docs": true,
        "files": true,
        "verify": true
      },
      "capabilities": {
        "can_manage_project": true,
        "can_manage_teams": true,
        "can_manage_permissions": true,
        "can_create_or_delete_doc_sections": true,
        "can_manage_doc_categories": true,
        "can_assign_doc_sections": true,
        "can_view_in_progress_doc_sections": true,
        "can_view_in_progress_doc_comments": true,
        "can_manage_smart_fields": true,
        "can_manage_docs": true,
        "can_manage_information_requirements": true,
        "can_manage_scope_rows": true,
        "can_manage_scope_tasks": true,
        "can_manage_scope_task_assignees": true,
        "can_manage_task_fields": true,
        "can_manage_milestones": true,
        "can_manage_scope_row_linking_rules": true,
        "can_manage_information_requirement_assignments": true,
        "can_manage_task_statuses": true,
        "can_manage_work_packages": true,
        "can_manage_work_package_filters": true,
        "can_manage_work_package_models": true,
        "can_manage_work_package_mapping_rules": true,
        "can_manage_models": true,
        "can_view_in_progress_models": true,
        "can_manage_model_linking_rules": true,
        "can_manage_files": true,
        "can_add_file_signatories": true,
        "can_resolve_doc_comments": true
      },
      "access": {
        "docs_visibility": "all_docs",
        "files_visibility": "all_files",
        "doc_section_editing": "all_sections",
        "doc_status_management": "share_and_publish",
        "task_status_updates": "all_statuses",
        "model_status_updates": "share_and_publish_model",
        "team_invite_access": "any_team",
        "permission_assignment_access": "equal_or_lower",
        "team_member_visibility": "all_members",
        "team_visibility": "all_teams"
      },
      "scope_task_access_policy": {
        "version": 2,
        "view": {
          "direct_self": true,
          "own_team": true,
          "other_person": false,
          "other_team": false,
          "unassigned": true
        },
        "edit": {
          "direct_self": true,
          "own_team": true,
          "other_person": false,
          "other_team": false,
          "unassigned": true
        },
        "delete": {
          "direct_self": true,
          "own_team": true,
          "other_person": false,
          "other_team": false,
          "unassigned": false
        },
        "view_empty_slots": true
      },
      "lock_version": 4,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-permissions/ID
POST
/external/v2/projects/:project_id/project-permissions

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.
    • access.docs_visibility
      Which docs the permission can see.
      all_docs team_assigned_docs
    • access.files_visibility
      Which files the permission can see.
      all_files team_assigned_files
    • access.doc_section_editing
      Which doc sections the permission can edit.
      all_sections assigned_and_unassigned_sections assigned_sections no_sections
    • access.doc_status_management
      Which doc status changes the permission can make.
      share_and_publish share not_allowed
    • access.task_status_updates
      Which task status changes the permission can make.
      all_statuses all_but_verified no_statuses
    • access.model_status_updates
      Which model status changes the permission can make.
      share_and_publish_model share_model no_models
    • access.team_invite_access
      Which teams the permission can invite users to.
      any_team own_team no_teams
    • access.permission_assignment_access
      Which permissions can be assigned when inviting or updating users.
      equal_or_lower viewers
    • access.team_member_visibility
      Which team members the permission can see.
      all_members managers_and_own no_members
    • access.team_visibility
      Which teams the permission can see.
      all_teams all_but_prospective own_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.
      all_scope_tasks assigned_and_unassigned_scope_tasks assigned_scope_tasks no_scope_tasks
    • access.scope_task_editing
      Legacy task-edit field. Do not send it with scope_task_access_policy; non-representable granular masks project conservatively without adding access.
      edit_all_scope_tasks edit_assigned_and_unassigned_scope_tasks edit_assigned_scope_tasks edit_no_scope_tasks
    • access.scope_task_deletion
      Legacy task-delete field. Do not send it with scope_task_access_policy; non-representable granular masks project conservatively without adding access.
      delete_all_scope_tasks delete_assigned_scope_tasks delete_unassigned_scope_tasks delete_no_scope_tasks delete_assigned_and_unassigned_scope_tasks
Example Request Body
{
  "data": {
    "name": "Coordinator",
    "modules": {
      "scope": true,
      "docs": true,
      "files": true,
      "verify": true
    },
    "capabilities": {
      "can_manage_project": true,
      "can_manage_teams": true,
      "can_manage_permissions": false,
      "can_create_or_delete_doc_sections": true,
      "can_manage_doc_categories": true,
      "can_assign_doc_sections": true,
      "can_view_in_progress_doc_sections": true,
      "can_view_in_progress_doc_comments": true,
      "can_manage_smart_fields": true,
      "can_manage_docs": true,
      "can_manage_information_requirements": true,
      "can_manage_scope_rows": true,
      "can_manage_scope_task_assignees": true,
      "can_manage_task_fields": true,
      "can_manage_milestones": true,
      "can_manage_scope_row_linking_rules": true,
      "can_manage_information_requirement_assignments": true,
      "can_manage_task_statuses": true,
      "can_manage_work_packages": true,
      "can_manage_work_package_filters": true,
      "can_manage_work_package_models": true,
      "can_manage_work_package_mapping_rules": true,
      "can_manage_models": true,
      "can_view_in_progress_models": true,
      "can_manage_model_linking_rules": true,
      "can_manage_files": true,
      "can_add_file_signatories": true,
      "can_resolve_doc_comments": true
    },
    "access": {
      "docs_visibility": "all_docs",
      "files_visibility": "all_files",
      "doc_section_editing": "all_sections",
      "doc_status_management": "share_and_publish",
      "task_status_updates": "all_statuses",
      "model_status_updates": "share_and_publish_model",
      "team_invite_access": "any_team",
      "permission_assignment_access": "equal_or_lower",
      "team_member_visibility": "all_members",
      "team_visibility": "all_teams"
    },
    "scope_task_access_policy": {
      "version": 2,
      "view": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "edit": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "delete": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": false
      },
      "view_empty_slots": true
    }
  }
}
Example Response Body
{
  "data": {
    "id": "0ccaa48b-2b65-47f0-ae22-31f3901d00f3",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "name": "Coordinator",
    "permission_type": "custom",
    "modules": {
      "scope": true,
      "docs": true,
      "files": true,
      "verify": true
    },
    "capabilities": {
      "can_manage_project": true,
      "can_manage_teams": true,
      "can_manage_permissions": false,
      "can_create_or_delete_doc_sections": true,
      "can_manage_doc_categories": true,
      "can_assign_doc_sections": true,
      "can_view_in_progress_doc_sections": true,
      "can_view_in_progress_doc_comments": true,
      "can_manage_smart_fields": true,
      "can_manage_docs": true,
      "can_manage_information_requirements": true,
      "can_manage_scope_rows": true,
      "can_manage_scope_tasks": true,
      "can_manage_scope_task_assignees": true,
      "can_manage_task_fields": true,
      "can_manage_milestones": true,
      "can_manage_scope_row_linking_rules": true,
      "can_manage_information_requirement_assignments": true,
      "can_manage_task_statuses": true,
      "can_manage_work_packages": true,
      "can_manage_work_package_filters": true,
      "can_manage_work_package_models": true,
      "can_manage_work_package_mapping_rules": true,
      "can_manage_models": true,
      "can_view_in_progress_models": true,
      "can_manage_model_linking_rules": true,
      "can_manage_files": true,
      "can_add_file_signatories": true,
      "can_resolve_doc_comments": true
    },
    "access": {
      "docs_visibility": "all_docs",
      "files_visibility": "all_files",
      "doc_section_editing": "all_sections",
      "doc_status_management": "share_and_publish",
      "task_status_updates": "all_statuses",
      "model_status_updates": "share_and_publish_model",
      "team_invite_access": "any_team",
      "permission_assignment_access": "equal_or_lower",
      "team_member_visibility": "all_members",
      "team_visibility": "all_teams"
    },
    "scope_task_access_policy": {
      "version": 2,
      "view": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "edit": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "delete": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": false
      },
      "view_empty_slots": true
    },
    "lock_version": 4,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"name":"Coordinator","modules":{"scope":true,"docs":true,"files":true,"verify":true},"capabilities":{"can_manage_project":true,"can_manage_teams":true,"can_manage_permissions":false,"can_create_or_delete_doc_sections":true,"can_manage_doc_categories":true,"can_assign_doc_sections":true,"can_view_in_progress_doc_sections":true,"can_view_in_progress_doc_comments":true,"can_manage_smart_fields":true,"can_manage_docs":true,"can_manage_information_requirements":true,"can_manage_scope_rows":true,"can_manage_scope_task_assignees":true,"can_manage_task_fields":true,"can_manage_milestones":true,"can_manage_scope_row_linking_rules":true,"can_manage_information_requirement_assignments":true,"can_manage_task_statuses":true,"can_manage_work_packages":true,"can_manage_work_package_filters":true,"can_manage_work_package_models":true,"can_manage_work_package_mapping_rules":true,"can_manage_models":true,"can_view_in_progress_models":true,"can_manage_model_linking_rules":true,"can_manage_files":true,"can_add_file_signatories":true,"can_resolve_doc_comments":true},"access":{"docs_visibility":"all_docs","files_visibility":"all_files","doc_section_editing":"all_sections","doc_status_management":"share_and_publish","task_status_updates":"all_statuses","model_status_updates":"share_and_publish_model","team_invite_access":"any_team","permission_assignment_access":"equal_or_lower","team_member_visibility":"all_members","team_visibility":"all_teams"},"scope_task_access_policy":{"version":2,"view":{"direct_self":true,"own_team":true,"other_person":false,"other_team":false,"unassigned":true},"edit":{"direct_self":true,"own_team":true,"other_person":false,"other_team":false,"unassigned":true},"delete":{"direct_self":true,"own_team":true,"other_person":false,"other_team":false,"unassigned":false},"view_empty_slots":true}}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-permissions
PATCH
/external/v2/projects/:project_id/project-permissions/:id

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.
    • access.docs_visibility
      Which docs the permission can see.
      all_docs team_assigned_docs
    • access.files_visibility
      Which files the permission can see.
      all_files team_assigned_files
    • access.doc_section_editing
      Which doc sections the permission can edit.
      all_sections assigned_and_unassigned_sections assigned_sections no_sections
    • access.doc_status_management
      Which doc status changes the permission can make.
      share_and_publish share not_allowed
    • access.task_status_updates
      Which task status changes the permission can make.
      all_statuses all_but_verified no_statuses
    • access.model_status_updates
      Which model status changes the permission can make.
      share_and_publish_model share_model no_models
    • access.team_invite_access
      Which teams the permission can invite users to.
      any_team own_team no_teams
    • access.permission_assignment_access
      Which permissions can be assigned when inviting or updating users.
      equal_or_lower viewers
    • access.team_member_visibility
      Which team members the permission can see.
      all_members managers_and_own no_members
    • access.team_visibility
      Which teams the permission can see.
      all_teams all_but_prospective own_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.
      all_scope_tasks assigned_and_unassigned_scope_tasks assigned_scope_tasks no_scope_tasks
    • access.scope_task_editing
      Legacy task-edit field. Do not send it with scope_task_access_policy; non-representable granular masks project conservatively without adding access.
      edit_all_scope_tasks edit_assigned_and_unassigned_scope_tasks edit_assigned_scope_tasks edit_no_scope_tasks
    • access.scope_task_deletion
      Legacy task-delete field. Do not send it with scope_task_access_policy; non-representable granular masks project conservatively without adding access.
      delete_all_scope_tasks delete_assigned_scope_tasks delete_unassigned_scope_tasks delete_no_scope_tasks delete_assigned_and_unassigned_scope_tasks
Example Request Body
{
  "data": {
    "name": "Reviewer",
    "modules": {
      "scope": true,
      "docs": true,
      "files": true,
      "verify": false
    },
    "capabilities": {
      "can_manage_project": false,
      "can_manage_teams": true,
      "can_manage_permissions": false,
      "can_create_or_delete_doc_sections": true,
      "can_manage_doc_categories": true,
      "can_assign_doc_sections": true,
      "can_view_in_progress_doc_sections": true,
      "can_view_in_progress_doc_comments": true,
      "can_manage_smart_fields": true,
      "can_manage_docs": true,
      "can_manage_information_requirements": true,
      "can_manage_scope_rows": true,
      "can_manage_scope_task_assignees": true,
      "can_manage_task_fields": true,
      "can_manage_milestones": true,
      "can_manage_scope_row_linking_rules": true,
      "can_manage_information_requirement_assignments": true,
      "can_manage_task_statuses": true,
      "can_manage_work_packages": true,
      "can_manage_work_package_filters": true,
      "can_manage_work_package_models": true,
      "can_manage_work_package_mapping_rules": true,
      "can_manage_models": true,
      "can_view_in_progress_models": true,
      "can_manage_model_linking_rules": true,
      "can_manage_files": true,
      "can_add_file_signatories": true,
      "can_resolve_doc_comments": true
    },
    "access": {
      "docs_visibility": "team_assigned_docs",
      "files_visibility": "team_assigned_files",
      "doc_section_editing": "all_sections",
      "doc_status_management": "share_and_publish",
      "task_status_updates": "all_statuses",
      "model_status_updates": "share_and_publish_model",
      "team_invite_access": "any_team",
      "permission_assignment_access": "equal_or_lower",
      "team_member_visibility": "all_members",
      "team_visibility": "own_and_managers"
    },
    "scope_task_access_policy": {
      "version": 2,
      "view": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "edit": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "delete": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": false
      },
      "view_empty_slots": true
    },
    "expected_lock_version": 4,
    "expected_updated_at": "2026-04-15T11:30:00.000000Z"
  }
}
Example Response Body
{
  "data": {
    "id": "0ccaa48b-2b65-47f0-ae22-31f3901d00f3",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "name": "Reviewer",
    "permission_type": "custom",
    "modules": {
      "scope": true,
      "docs": true,
      "files": true,
      "verify": true
    },
    "capabilities": {
      "can_manage_project": true,
      "can_manage_teams": true,
      "can_manage_permissions": false,
      "can_create_or_delete_doc_sections": true,
      "can_manage_doc_categories": true,
      "can_assign_doc_sections": true,
      "can_view_in_progress_doc_sections": true,
      "can_view_in_progress_doc_comments": true,
      "can_manage_smart_fields": true,
      "can_manage_docs": true,
      "can_manage_information_requirements": true,
      "can_manage_scope_rows": true,
      "can_manage_scope_tasks": true,
      "can_manage_scope_task_assignees": true,
      "can_manage_task_fields": true,
      "can_manage_milestones": true,
      "can_manage_scope_row_linking_rules": true,
      "can_manage_information_requirement_assignments": true,
      "can_manage_task_statuses": true,
      "can_manage_work_packages": true,
      "can_manage_work_package_filters": true,
      "can_manage_work_package_models": true,
      "can_manage_work_package_mapping_rules": true,
      "can_manage_models": true,
      "can_view_in_progress_models": true,
      "can_manage_model_linking_rules": true,
      "can_manage_files": true,
      "can_add_file_signatories": true,
      "can_resolve_doc_comments": true
    },
    "access": {
      "docs_visibility": "all_docs",
      "files_visibility": "all_files",
      "doc_section_editing": "all_sections",
      "doc_status_management": "share_and_publish",
      "task_status_updates": "all_statuses",
      "model_status_updates": "share_and_publish_model",
      "team_invite_access": "any_team",
      "permission_assignment_access": "equal_or_lower",
      "team_member_visibility": "all_members",
      "team_visibility": "all_teams"
    },
    "scope_task_access_policy": {
      "version": 2,
      "view": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "edit": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "delete": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": false
      },
      "view_empty_slots": true
    },
    "lock_version": 4,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"name":"Reviewer","modules":{"scope":true,"docs":true,"files":true,"verify":false},"capabilities":{"can_manage_project":false,"can_manage_teams":true,"can_manage_permissions":false,"can_create_or_delete_doc_sections":true,"can_manage_doc_categories":true,"can_assign_doc_sections":true,"can_view_in_progress_doc_sections":true,"can_view_in_progress_doc_comments":true,"can_manage_smart_fields":true,"can_manage_docs":true,"can_manage_information_requirements":true,"can_manage_scope_rows":true,"can_manage_scope_task_assignees":true,"can_manage_task_fields":true,"can_manage_milestones":true,"can_manage_scope_row_linking_rules":true,"can_manage_information_requirement_assignments":true,"can_manage_task_statuses":true,"can_manage_work_packages":true,"can_manage_work_package_filters":true,"can_manage_work_package_models":true,"can_manage_work_package_mapping_rules":true,"can_manage_models":true,"can_view_in_progress_models":true,"can_manage_model_linking_rules":true,"can_manage_files":true,"can_add_file_signatories":true,"can_resolve_doc_comments":true},"access":{"docs_visibility":"team_assigned_docs","files_visibility":"team_assigned_files","doc_section_editing":"all_sections","doc_status_management":"share_and_publish","task_status_updates":"all_statuses","model_status_updates":"share_and_publish_model","team_invite_access":"any_team","permission_assignment_access":"equal_or_lower","team_member_visibility":"all_members","team_visibility":"own_and_managers"},"scope_task_access_policy":{"version":2,"view":{"direct_self":true,"own_team":true,"other_person":false,"other_team":false,"unassigned":true},"edit":{"direct_self":true,"own_team":true,"other_person":false,"other_team":false,"unassigned":true},"delete":{"direct_self":true,"own_team":true,"other_person":false,"other_team":false,"unassigned":false},"view_empty_slots":true},"expected_lock_version":4,"expected_updated_at":"2026-04-15T11:30:00.000000Z"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-permissions/ID
DELETE
/external/v2/projects/:project_id/project-permissions/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "0ccaa48b-2b65-47f0-ae22-31f3901d00f3",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "name": "Coordinator",
    "permission_type": "custom",
    "modules": {
      "scope": true,
      "docs": true,
      "files": true,
      "verify": true
    },
    "capabilities": {
      "can_manage_project": true,
      "can_manage_teams": true,
      "can_manage_permissions": false,
      "can_create_or_delete_doc_sections": true,
      "can_manage_doc_categories": true,
      "can_assign_doc_sections": true,
      "can_view_in_progress_doc_sections": true,
      "can_view_in_progress_doc_comments": true,
      "can_manage_smart_fields": true,
      "can_manage_docs": true,
      "can_manage_information_requirements": true,
      "can_manage_scope_rows": true,
      "can_manage_scope_tasks": true,
      "can_manage_scope_task_assignees": true,
      "can_manage_task_fields": true,
      "can_manage_milestones": true,
      "can_manage_scope_row_linking_rules": true,
      "can_manage_information_requirement_assignments": true,
      "can_manage_task_statuses": true,
      "can_manage_work_packages": true,
      "can_manage_work_package_filters": true,
      "can_manage_work_package_models": true,
      "can_manage_work_package_mapping_rules": true,
      "can_manage_models": true,
      "can_view_in_progress_models": true,
      "can_manage_model_linking_rules": true,
      "can_manage_files": true,
      "can_add_file_signatories": true,
      "can_resolve_doc_comments": true
    },
    "access": {
      "docs_visibility": "all_docs",
      "files_visibility": "all_files",
      "doc_section_editing": "all_sections",
      "doc_status_management": "share_and_publish",
      "task_status_updates": "all_statuses",
      "model_status_updates": "share_and_publish_model",
      "team_invite_access": "any_team",
      "permission_assignment_access": "equal_or_lower",
      "team_member_visibility": "all_members",
      "team_visibility": "all_teams"
    },
    "scope_task_access_policy": {
      "version": 2,
      "view": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "edit": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": true
      },
      "delete": {
        "direct_self": true,
        "own_team": true,
        "other_person": false,
        "other_team": false,
        "unassigned": false
      },
      "view_empty_slots": true
    },
    "lock_version": 4,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/project-permissions/ID

Docs

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.

Example Response
{
  "data": [
    {
      "id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
      "title": "BIM Coordination Doc",
      "description": "Project delivery document",
      "position": 1,
      "accessible_project_team_ids": [
        "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
      ],
      "comment_count": 2,
      "unresolved_comment_count": 1,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs
POST
/external/v2/projects/:project_id/docs

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.
Example Request Body
{
  "data": {
    "title": "BIM Coordination Doc",
    "description": "Project delivery document",
    "position": 1,
    "accessible_project_team_ids": [
      "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
    ]
  }
}
Example Response Body
{
  "data": {
    "id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "title": "BIM Coordination Doc",
    "description": "Project delivery document",
    "position": 1,
    "accessible_project_team_ids": [
      "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
    ],
    "comment_count": 0,
    "unresolved_comment_count": 0,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"BIM Coordination Doc","description":"Project delivery document","position":1,"accessible_project_team_ids":["2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"]}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs
GET
/external/v2/projects/:project_id/docs/tree

Docs tree: Nested doc, category, and section tree. Each node contains id, type, title, and children; type is doc, category, or section.

Example Response
{
  "data": [
    {
      "id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
      "type": "doc",
      "title": "BIM Coordination Doc",
      "children": [
        {
          "id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
          "type": "category",
          "title": "Information Management",
          "children": [
            {
              "id": "3f5d5efd-8f46-4605-a5f5-160a419517f7",
              "type": "section",
              "title": "Exchange Requirements",
              "children": []
            }
          ]
        }
      ]
    }
  ],
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/tree
GET
/external/v2/projects/:project_id/docs/:id

Get doc: Single project doc with normalized position, accessible_project_team_ids, comment_count, and unresolved_comment_count.

Example Response
{
  "data": {
    "id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "title": "BIM Coordination Doc",
    "description": "Project delivery document",
    "position": 1,
    "accessible_project_team_ids": [
      "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
    ],
    "comment_count": 2,
    "unresolved_comment_count": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/ID
PATCH
/external/v2/projects/:project_id/docs/:id

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.
Example Request Body
{
  "data": {
    "title": "BIM Coordination Doc",
    "description": "Updated project delivery document",
    "position": 1,
    "accessible_project_team_ids": [
      "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
    ]
  }
}
Example Response Body
{
  "data": {
    "id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "title": "BIM Coordination Doc",
    "description": "Project delivery document",
    "position": 1,
    "accessible_project_team_ids": [
      "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
    ],
    "comment_count": 2,
    "unresolved_comment_count": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"BIM Coordination Doc","description":"Updated project delivery document","position":1,"accessible_project_team_ids":["2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"]}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/ID
DELETE
/external/v2/projects/:project_id/docs/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "title": "BIM Coordination Doc",
    "description": "Project delivery document",
    "position": 1,
    "accessible_project_team_ids": [
      "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
    ],
    "comment_count": 2,
    "unresolved_comment_count": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/ID
Doc Categories
GET
/external/v2/projects/:project_id/docs/:doc_id/doc-categories

List doc categories: Categories within a project doc. Categories have type category and use parent_id for hierarchy.

Example Response
{
  "data": [
    {
      "id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
      "type": "category",
      "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
      "parent_id": null,
      "title": "Information Management",
      "description": "Project information management topics",
      "position": 1,
      "unnumbered": false,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-categories
POST
/external/v2/projects/:project_id/docs/:doc_id/doc-categories

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.
Example Request Body
{
  "data": {
    "title": "Information Management",
    "description": "Project information management topics",
    "parent_id": null,
    "position": 1,
    "unnumbered": false
  }
}
Example Response Body
{
  "data": {
    "id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "type": "category",
    "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "parent_id": null,
    "title": "Information Management",
    "description": "Project information management topics",
    "position": 1,
    "unnumbered": false,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Information Management","description":"Project information management topics","parent_id":null,"position":1,"unnumbered":false}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-categories
GET
/external/v2/projects/:project_id/docs/:doc_id/doc-categories/:id

Get doc category: Single category within a project doc.

Example Response
{
  "data": {
    "id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "type": "category",
    "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "parent_id": null,
    "title": "Information Management",
    "description": "Project information management topics",
    "position": 1,
    "unnumbered": false,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-categories/ID
PATCH
/external/v2/projects/:project_id/docs/:doc_id/doc-categories/:id

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.
Example Request Body
{
  "data": {
    "title": "Information Management",
    "description": "Updated project information management topics",
    "parent_id": null,
    "position": 1,
    "unnumbered": false
  }
}
Example Response Body
{
  "data": {
    "id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "type": "category",
    "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "parent_id": null,
    "title": "Information Management",
    "description": "Project information management topics",
    "position": 1,
    "unnumbered": false,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Information Management","description":"Updated project information management topics","parent_id":null,"position":1,"unnumbered":false}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-categories/ID
DELETE
/external/v2/projects/:project_id/docs/:doc_id/doc-categories/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "type": "category",
    "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "parent_id": null,
    "title": "Information Management",
    "description": "Project information management topics",
    "position": 1,
    "unnumbered": false,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-categories/ID
GET
/external/v2/projects/:project_id/docs/:doc_id/doc-categories/:id/children

Doc category children: Direct child categories and sections for one doc category. Use type to distinguish mixed child records.

Example Response
{
  "data": [
    {
      "id": "3f5d5efd-8f46-4605-a5f5-160a419517f7",
      "type": "section",
      "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
      "parent_id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
      "title": "Exchange Requirements",
      "description": "Model exchange requirements and delivery notes",
      "content_html": "<p>Coordinate model exchanges before each milestone.</p>",
      "position": 1,
      "status": "Shared",
      "status_id": 2,
      "section_type": "Standard",
      "section_type_id": 3,
      "assigned_user_ids": [
        "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
      ],
      "comment_count": 2,
      "unresolved_comment_count": 1,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-categories/ID/children
Doc Sections
GET
/external/v2/projects/:project_id/docs/:doc_id/doc-sections

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.

  • Filters
    filter[status], filter[user_id] Reference
    Optional filters supported on this collection endpoint.
Example Response
{
  "data": [
    {
      "id": "3f5d5efd-8f46-4605-a5f5-160a419517f7",
      "type": "section",
      "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
      "parent_id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
      "title": "Exchange Requirements",
      "description": "Model exchange requirements and delivery notes",
      "content_html": "<p>Client: <smartfield data-key=\"Client\"></smartfield></p>",
      "position": 1,
      "status": "Shared",
      "status_id": 2,
      "section_type": "Standard",
      "section_type_id": 3,
      "assigned_user_ids": [
        "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
      ],
      "comment_count": 2,
      "unresolved_comment_count": 1,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-sections
POST
/external/v2/projects/:project_id/docs/:doc_id/doc-sections

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.
Example Request Body
{
  "data": {
    "title": "Exchange Requirements",
    "description": "Model exchange requirements and delivery notes",
    "parent_id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "content_html": "<p>Client: <smartfield data-key=\"Client\"></smartfield></p>",
    "position": 1,
    "status_id": 2,
    "section_type_id": 3,
    "assigned_user_ids": [
      "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
    ]
  }
}
Example Response Body
{
  "data": {
    "id": "3f5d5efd-8f46-4605-a5f5-160a419517f7",
    "type": "section",
    "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "parent_id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "title": "Exchange Requirements",
    "description": "Model exchange requirements and delivery notes",
    "content_html": "<p>Client: <smartfield data-key=\"Client\"></smartfield></p>",
    "position": 1,
    "status": "Shared",
    "status_id": 2,
    "section_type": "Standard",
    "section_type_id": 3,
    "assigned_user_ids": [
      "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
    ],
    "comment_count": 2,
    "unresolved_comment_count": 2,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Exchange Requirements","description":"Model exchange requirements and delivery notes","parent_id":"76ef9d9a-7d37-44dc-8d1d-89c7d54d3315","content_html":"<p>Client: <smartfield data-key=\"Client\"></smartfield></p>","position":1,"status_id":2,"section_type_id":3,"assigned_user_ids":["fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"]}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-sections
GET
/external/v2/projects/:project_id/docs/:doc_id/doc-sections/:id

Get doc section: Single section within a project doc, including assignment and comment summary fields.

Example Response
{
  "data": {
    "id": "3f5d5efd-8f46-4605-a5f5-160a419517f7",
    "type": "section",
    "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "parent_id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "title": "Exchange Requirements",
    "description": "Model exchange requirements and delivery notes",
    "content_html": "<p>Client: <smartfield data-key=\"Client\"></smartfield></p>",
    "position": 1,
    "status": "Shared",
    "status_id": 2,
    "section_type": "Standard",
    "section_type_id": 3,
    "assigned_user_ids": [
      "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
    ],
    "comment_count": 2,
    "unresolved_comment_count": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-sections/ID
PATCH
/external/v2/projects/:project_id/docs/:doc_id/doc-sections/:id

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.
Example Request Body
{
  "data": {
    "title": "Exchange Requirements",
    "description": "Updated model exchange requirements and delivery notes",
    "parent_id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "content_html": "<p>Client: <smartfield data-key=\"Client\"></smartfield></p>",
    "position": 1,
    "status_id": 2,
    "section_type_id": 3,
    "assigned_user_ids": [
      "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
    ]
  }
}
Example Response Body
{
  "data": {
    "id": "3f5d5efd-8f46-4605-a5f5-160a419517f7",
    "type": "section",
    "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "parent_id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "title": "Exchange Requirements",
    "description": "Model exchange requirements and delivery notes",
    "content_html": "<p>Client: <smartfield data-key=\"Client\"></smartfield></p>",
    "position": 1,
    "status": "Shared",
    "status_id": 2,
    "section_type": "Standard",
    "section_type_id": 3,
    "assigned_user_ids": [
      "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
    ],
    "comment_count": 2,
    "unresolved_comment_count": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Exchange Requirements","description":"Updated model exchange requirements and delivery notes","parent_id":"76ef9d9a-7d37-44dc-8d1d-89c7d54d3315","content_html":"<p>Client: <smartfield data-key=\"Client\"></smartfield></p>","position":1,"status_id":2,"section_type_id":3,"assigned_user_ids":["fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"]}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-sections/ID
DELETE
/external/v2/projects/:project_id/docs/:doc_id/doc-sections/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "3f5d5efd-8f46-4605-a5f5-160a419517f7",
    "type": "section",
    "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
    "parent_id": "76ef9d9a-7d37-44dc-8d1d-89c7d54d3315",
    "title": "Exchange Requirements",
    "description": "Model exchange requirements and delivery notes",
    "content_html": "<p>Client: <smartfield data-key=\"Client\"></smartfield></p>",
    "position": 1,
    "status": "Shared",
    "status_id": 2,
    "section_type": "Standard",
    "section_type_id": 3,
    "assigned_user_ids": [
      "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
    ],
    "comment_count": 2,
    "unresolved_comment_count": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-sections/ID
GET
/external/v2/projects/:project_id/docs/:doc_id/doc-sections/:id/children

Doc section children: Direct child categories and sections for one doc section. Use type to distinguish mixed child records.

Example Response
{
  "data": [
    {
      "id": "7bb3a8b5-e219-45a9-9911-8655f00d5212",
      "type": "section",
      "doc_id": "bbac9f67-9f11-46a0-b0f1-f1718dc1904a",
      "parent_id": "3f5d5efd-8f46-4605-a5f5-160a419517f7",
      "title": "Nested Section",
      "description": "Nested section details",
      "content_html": "<p>Nested section content.</p>",
      "position": 1,
      "status": "Shared",
      "status_id": 2,
      "section_type": "Standard",
      "section_type_id": 3,
      "assigned_user_ids": [],
      "comment_count": 0,
      "unresolved_comment_count": 0,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/docs/DOC_ID/doc-sections/ID/children

Scope & Schedule

Manage scope rows, scope tasks, task fields, task statuses, milestones, and schedule-related setup.

Scope Rows
GET
/external/v2/projects/:project_id/scope-rows

List scope rows: Scope rows for project.

Example Response
{
  "data": [
    {
      "id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
      "title": "Curtain Wall System",
      "row_type": "task",
      "parent_id": null,
      "position": 12,
      "code": "02-3000",
      "full_code": "A-02-3000",
      "subtitle": "North and east facade zones",
      "entity_type": "IfcCurtainWall",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-rows
POST
/external/v2/projects/:project_id/scope-rows

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.
  • Allowed Values
    • row_type
      The type of scope row to create.
      folder task group
Example Request Body
{
  "data": {
    "row_type": "task",
    "title": "Curtain Wall System",
    "parent_id": "89dfa977-91be-46f7-bd8a-c90316f75f53",
    "position": 1,
    "code": "02-3000",
    "subtitle": "North and east facade zones",
    "entity_type": "IfcCurtainWall"
  }
}
Example Response Body
{
  "data": {
    "id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
    "title": "Curtain Wall System",
    "row_type": "task",
    "parent_id": "89dfa977-91be-46f7-bd8a-c90316f75f53",
    "position": 1,
    "code": "02-3000",
    "full_code": "A-02-3000",
    "subtitle": "North and east facade zones",
    "entity_type": "IfcCurtainWall",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"row_type":"task","title":"Curtain Wall System","parent_id":"89dfa977-91be-46f7-bd8a-c90316f75f53","position":1,"code":"02-3000","subtitle":"North and east facade zones","entity_type":"IfcCurtainWall"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-rows
GET
/external/v2/projects/:project_id/scope-rows/:id

Get scope row: Single scope row.

Example Response
{
  "data": {
    "id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
    "title": "Curtain Wall System",
    "row_type": "task",
    "parent_id": null,
    "position": 12,
    "code": "02-3000",
    "full_code": "A-02-3000",
    "subtitle": "North and east facade zones",
    "entity_type": "IfcCurtainWall",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-rows/ID
PATCH
/external/v2/projects/:project_id/scope-rows/:id

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.
Example Request Body
{
  "data": {
    "title": "Curtain Wall System",
    "parent_id": "89dfa977-91be-46f7-bd8a-c90316f75f53",
    "position": 1,
    "code": "02-3000",
    "subtitle": "North and east facade zones",
    "entity_type": "IfcCurtainWall"
  }
}
Example Response Body
{
  "data": {
    "id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
    "title": "Curtain Wall System",
    "row_type": "task",
    "parent_id": null,
    "position": 12,
    "code": "02-3000",
    "full_code": "A-02-3000",
    "subtitle": "North and east facade zones",
    "entity_type": "IfcCurtainWall",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Curtain Wall System","parent_id":"89dfa977-91be-46f7-bd8a-c90316f75f53","position":1,"code":"02-3000","subtitle":"North and east facade zones","entity_type":"IfcCurtainWall"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-rows/ID
DELETE
/external/v2/projects/:project_id/scope-rows/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
    "title": "Curtain Wall System",
    "row_type": "task",
    "parent_id": null,
    "position": 12,
    "code": "02-3000",
    "full_code": "A-02-3000",
    "subtitle": "North and east facade zones",
    "entity_type": "IfcCurtainWall",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-rows/ID
Scope Tasks
GET
/external/v2/projects/:project_id/scope-tasks

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.

  • Includes
    include=information_requirements,fields,scope_row Reference
    Use these values to expand related resources in the same response.
  • Filters
    filter[project_team_id], filter[user_id], filter[scope_row_id], filter[milestone_id], filter[parent_id], filter[task_status_id], filter[requirement_tag_id], filter[work_package_id] Reference
    Optional filters supported on this collection endpoint.
Example Response
{
  "data": [
    {
      "id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
      "start_date": "2026-04-18",
      "end_date": "2026-05-14",
      "geometry": 3,
      "accuracy": 2,
      "project_team_id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
      "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "task_status_id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
      "is_verified": false,
      "scope_row_id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
      "milestone_id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
      "parent_id": null,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks
POST
/external/v2/projects/:project_id/scope-tasks

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.
Example Request Body
{
  "data": {
    "scope_row_id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
    "milestone_id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
    "project_team_id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "task_status_id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
    "start_date": "2026-04-18",
    "end_date": "2026-05-14",
    "geometry": 3,
    "accuracy": 2
  }
}
Example Response Body
{
  "data": {
    "id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
    "start_date": "2026-04-18",
    "end_date": "2026-05-14",
    "geometry": 3,
    "accuracy": 2,
    "project_team_id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "task_status_id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
    "is_verified": false,
    "scope_row_id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
    "milestone_id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
    "parent_id": null,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"scope_row_id":"c57ce097-abf7-4f60-b8d5-3f5ef71677df","milestone_id":"6a217d0f-692e-4987-a7d6-86c7247c5a74","project_team_id":"2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d","user_id":"fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6","task_status_id":"9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72","start_date":"2026-04-18","end_date":"2026-05-14","geometry":3,"accuracy":2}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks
GET
/external/v2/projects/:project_id/scope-tasks/:id

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.

  • Includes
    include=information_requirements,fields,scope_row Reference
    Use these values to expand related resources in the same response.
Example Response
{
  "data": {
    "id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
    "start_date": "2026-04-18",
    "end_date": "2026-05-14",
    "project_team_id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "task_status_id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
    "is_verified": false,
    "scope_row_id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
    "milestone_id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
    "parent_id": null,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/ID
PATCH
/external/v2/projects/:project_id/scope-tasks/:id

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.
Example Request Body
{
  "data": {
    "milestone_id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
    "project_team_id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "task_status_id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
    "start_date": "2026-04-18",
    "end_date": "2026-05-14",
    "geometry": 3,
    "accuracy": 2
  }
}
Example Response Body
{
  "data": {
    "id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
    "start_date": "2026-04-18",
    "end_date": "2026-05-14",
    "project_team_id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "task_status_id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
    "is_verified": false,
    "scope_row_id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
    "milestone_id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
    "parent_id": null,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"milestone_id":"6a217d0f-692e-4987-a7d6-86c7247c5a74","project_team_id":"2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d","user_id":"fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6","task_status_id":"9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72","start_date":"2026-04-18","end_date":"2026-05-14","geometry":3,"accuracy":2}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/ID
DELETE
/external/v2/projects/:project_id/scope-tasks/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": [
    {
      "id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
      "start_date": "2026-04-18",
      "end_date": "2026-05-14",
      "project_team_id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
      "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "task_status_id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
      "is_verified": false,
      "scope_row_id": "c57ce097-abf7-4f60-b8d5-3f5ef71677df",
      "milestone_id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
      "parent_id": null,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "id": "d7ac03b6-9a90-4490-8177-4c344d5d7113",
      "start_date": "2026-04-18",
      "end_date": "2026-05-14",
      "project_team_id": "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d",
      "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "task_status_id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
      "is_verified": false,
      "scope_row_id": "6d3f9271-59f3-4522-9e72-25c5c998654b",
      "milestone_id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
      "parent_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/ID
Task Comments
GET
/external/v2/projects/:project_id/scope-tasks/:scope_task_id/comments

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.
Example Requests (no body)

Scope comments (default)

curl --get -H "Authorization: Bearer plly_user_xxx" \
  "https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/SCOPE_TASK_ID/comments"

Verify comments

curl --get -H "Authorization: Bearer plly_user_xxx" \
  --data-urlencode 'filter[module]=verify' \
  "https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/SCOPE_TASK_ID/comments"
Response fields (each item in data)
FieldTypeMeaning in Plannerly
idstringUnique ID of this comment or reply.
scope_task_idstringTask ID, matching the scope-tasks endpoint. This is not a scope-row ID.
parent_idstring or nullID 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_idstring or nullTask 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.
modulestringWhere the comment was posted: scope or verify.
descriptionstringComment text. May be empty for an attachment-only comment. Mentions use @[Alex Morgan](USER_ID), which the app displays as @Alex Morgan.
authorobjectThe author's id and name. The name is recorded when the comment is posted and may differ from their current profile.
titlestring or nullConversation 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_resolvedboolean or nullOn 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_attimestamp or nullWhen the conversation was resolved. Null for unresolved conversations and replies.
resolved_by_user_idstring or nullUser who resolved the conversation, if recorded. Null for unresolved conversations and replies.
attachmentobject or nullAttached 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_attimestampWhen 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.
Example Response
{
  "data": [
    {
      "id": "6a85fdc1-a47c-44c2-a663-5248f31c3424",
      "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
      "parent_id": "e7c90ee6-d5ee-4e5e-9554-9d43a186438c",
      "task_field_id": null,
      "module": "scope",
      "description": "Coordinates checked against the agreed project origin.",
      "author": {
        "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
        "name": "Alex Morgan"
      },
      "title": null,
      "is_resolved": null,
      "resolved_at": null,
      "resolved_by_user_id": null,
      "attachment": {
        "filename": "coordinate-review.pdf",
        "content_type": "application/pdf",
        "url": "https://files.example.com/coordinate-review.pdf?temporary-signed-download"
      },
      "created_at": "2026-04-15T11:30:00.000000Z",
      "updated_at": "2026-04-15T11:30:00.000000Z"
    },
    {
      "id": "e7c90ee6-d5ee-4e5e-9554-9d43a186438c",
      "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
      "parent_id": null,
      "task_field_id": null,
      "module": "scope",
      "description": "Please confirm the model coordinates before handover.",
      "author": {
        "id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
        "name": "Alex Morgan"
      },
      "title": "Confirm model coordinates",
      "is_resolved": true,
      "resolved_at": "2026-04-15T11:30:00.000000Z",
      "resolved_by_user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
      "attachment": null,
      "created_at": "2026-01-09T09:00:00.000000Z",
      "updated_at": "2026-04-15T11:30:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
LOD
GET
/external/v2/projects/:project_id/lod

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.

Example Response
{
  "data": [
    {
      "name": "LOD 100",
      "geometry": "Symbolic",
      "accuracy": "Preliminary",
      "geometry_value": 1,
      "accuracy_value": 1
    },
    {
      "name": "LOD 300",
      "geometry": "Detailed",
      "accuracy": "Proposed",
      "geometry_value": 3,
      "accuracy_value": 2
    },
    {
      "name": "Special",
      "geometry": "Fabrication",
      "accuracy": "As-Built",
      "geometry_value": 4,
      "accuracy_value": 4
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/lod
Task Field Definitions
GET
/external/v2/projects/:project_id/task-fields

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.

Example Response
{
  "data": [
    {
      "id": "44aa6db8-4d0f-4b9d-9f3d-7a14b7f3cc61",
      "title": "Review Status",
      "description": "Internal review state",
      "field_type": "picklist",
      "color": "#0AA398",
      "applies_to": "task_rows",
      "position": 3,
      "settings": {
        "options": [
          {
            "index": 0,
            "label": "Not started",
            "color": "#e5e6e5",
            "is_default": true
          },
          {
            "index": 1,
            "label": "In review",
            "color": "#ffc8aa",
            "is_default": false
          }
        ]
      },
      "is_system": false,
      "values_supported": true,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-fields
POST
/external/v2/projects/:project_id/task-fields

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.
      text number boolean date cost picklist urls files
    • applies_to
      Which scope row task types can use the field. Defaults to task_rows.
      task_rows group_rows all_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.
      label color is_default
    • settings.allow_multiple
      URL and file fields accept true or false.
      true false
Example Request Body
{
  "data": {
    "title": "Review Status",
    "description": "Review state",
    "field_type": "picklist",
    "color": "#0AA398",
    "applies_to": "task_rows",
    "position": 3,
    "settings": {
      "options": [
        {
          "label": "Not started",
          "color": "#e5e6e5",
          "is_default": true
        },
        {
          "label": "In review",
          "color": "#ffc8aa",
          "is_default": false
        }
      ]
    }
  }
}
Example Response Body
{
  "data": {
    "id": "44aa6db8-4d0f-4b9d-9f3d-7a14b7f3cc61",
    "title": "Review Status",
    "description": "Internal review state",
    "field_type": "picklist",
    "color": "#0AA398",
    "applies_to": "task_rows",
    "position": 3,
    "settings": {
      "options": [
        {
          "index": 0,
          "label": "Not started",
          "color": "#e5e6e5",
          "is_default": true
        },
        {
          "index": 1,
          "label": "In review",
          "color": "#ffc8aa",
          "is_default": false
        }
      ]
    },
    "is_system": false,
    "values_supported": true,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Review Status","description":"Review state","field_type":"picklist","color":"#0AA398","applies_to":"task_rows","position":3,"settings":{"options":[{"label":"Not started","color":"#e5e6e5","is_default":true},{"label":"In review","color":"#ffc8aa","is_default":false}]}}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-fields
GET
/external/v2/projects/:project_id/task-fields/:id

Get task field: Single project-level task field definition.

Example Response
{
  "data": {
    "id": "44aa6db8-4d0f-4b9d-9f3d-7a14b7f3cc61",
    "title": "Review Status",
    "description": "Internal review state",
    "field_type": "picklist",
    "color": "#0AA398",
    "applies_to": "task_rows",
    "position": 3,
    "settings": {
      "options": [
        {
          "index": 0,
          "label": "Not started",
          "color": "#e5e6e5",
          "is_default": true
        },
        {
          "index": 1,
          "label": "In review",
          "color": "#ffc8aa",
          "is_default": false
        }
      ]
    },
    "is_system": false,
    "values_supported": true,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-fields/ID
PATCH
/external/v2/projects/:project_id/task-fields/:id

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.
Example Request Body
{
  "data": {
    "title": "Updated Review Status",
    "description": "Review state",
    "color": "#0AA398",
    "position": 3,
    "settings": {
      "options": [
        {
          "label": "Not started",
          "color": "#e5e6e5"
        },
        {
          "label": "In review",
          "color": "#ffc8aa"
        }
      ]
    }
  }
}
Example Response Body
{
  "data": {
    "id": "44aa6db8-4d0f-4b9d-9f3d-7a14b7f3cc61",
    "title": "Updated Review Status",
    "description": "Internal review state",
    "field_type": "picklist",
    "color": "#0AA398",
    "applies_to": "task_rows",
    "position": 3,
    "settings": {
      "options": [
        {
          "index": 0,
          "label": "Not started",
          "color": "#e5e6e5",
          "is_default": true
        },
        {
          "index": 1,
          "label": "In review",
          "color": "#ffc8aa",
          "is_default": false
        }
      ]
    },
    "is_system": false,
    "values_supported": true,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Updated Review Status","description":"Review state","color":"#0AA398","position":3,"settings":{"options":[{"label":"Not started","color":"#e5e6e5"},{"label":"In review","color":"#ffc8aa"}]}}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-fields/ID
DELETE
/external/v2/projects/:project_id/task-fields/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "44aa6db8-4d0f-4b9d-9f3d-7a14b7f3cc61",
    "title": "Review Status",
    "description": "Internal review state",
    "field_type": "picklist",
    "color": "#0AA398",
    "applies_to": "task_rows",
    "position": 3,
    "settings": {
      "options": [
        {
          "index": 0,
          "label": "Not started",
          "color": "#e5e6e5",
          "is_default": true
        },
        {
          "index": 1,
          "label": "In review",
          "color": "#ffc8aa",
          "is_default": false
        }
      ]
    },
    "is_system": false,
    "values_supported": true,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-fields/ID
Task Field Values
GET
/external/v2/projects/:project_id/scope-tasks/:scope_task_id/task-field-values

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.

Example Response
{
  "data": [
    {
      "task_field_id": "44aa6db8-4d0f-4b9d-9f3d-7a14b7f3cc61",
      "task_field_value_id": "914cf4c8-0d3c-48d2-b65f-7e40c8e8b27f",
      "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
      "title": "Review Status",
      "field_type": "picklist",
      "value": {
        "option_index": 1,
        "label": "In review",
        "color": "#ffc8aa"
      },
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "task_field_id": "2a642ec8-4e19-4114-bf83-75f15d235df1",
      "task_field_value_id": null,
      "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
      "title": "Notes",
      "field_type": "text",
      "value": null,
      "updated_at": null,
      "created_at": null
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/SCOPE_TASK_ID/task-field-values
PATCH
/external/v2/projects/:project_id/scope-tasks/:scope_task_id/task-field-values/:task_field_id

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.
Example Request Body
{
  "data": {
    "value": {
      "option_index": 1
    }
  }
}
Example Response Body
{
  "data": {
    "task_field_id": "44aa6db8-4d0f-4b9d-9f3d-7a14b7f3cc61",
    "task_field_value_id": "914cf4c8-0d3c-48d2-b65f-7e40c8e8b27f",
    "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
    "title": "Review Status",
    "field_type": "picklist",
    "value": {
      "option_index": 1,
      "label": "In review",
      "color": "#ffc8aa"
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"value":{"option_index":1}}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/SCOPE_TASK_ID/task-field-values/:task_field_id
DELETE
/external/v2/projects/:project_id/scope-tasks/:scope_task_id/task-field-values/:task_field_id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "task_field_id": "44aa6db8-4d0f-4b9d-9f3d-7a14b7f3cc61",
    "task_field_value_id": "914cf4c8-0d3c-48d2-b65f-7e40c8e8b27f",
    "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
    "title": "Review Status",
    "field_type": "picklist",
    "value": {
      "option_index": 1,
      "label": "In review",
      "color": "#ffc8aa"
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/SCOPE_TASK_ID/task-field-values/:task_field_id
Checklist Tasks
GET
/external/v2/projects/:project_id/checklist-tasks

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.

  • Filters
    filter[description] Reference
    Optional filters supported on this collection endpoint.
Example Response
{
  "data": [
    {
      "id": "d622725e-83ac-455a-b42d-ea13d1ccac36",
      "description": "Confirm model coordinates",
      "scope_task_ids": [
        "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
      ],
      "created_at": "2026-01-09T09:00:00.000000Z",
      "updated_at": "2026-04-15T11:30:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/checklist-tasks
GET
/external/v2/projects/:project_id/checklist-tasks/:id

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.

Example Response
{
  "data": {
    "id": "d622725e-83ac-455a-b42d-ea13d1ccac36",
    "description": "Confirm model coordinates",
    "scope_task_ids": [
      "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
    ],
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/checklist-tasks/ID
POST
/external/v2/projects/:project_id/checklist-tasks

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.
Example Request Body
{
  "data": {
    "description": "Confirm model coordinates",
    "scope_task_ids": [
      "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
    ]
  }
}
Example Response Body
{
  "data": {
    "id": "d622725e-83ac-455a-b42d-ea13d1ccac36",
    "description": "Confirm model coordinates",
    "scope_task_ids": [
      "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
    ],
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"description":"Confirm model coordinates","scope_task_ids":["7a4b1f07-b56b-4be5-b03b-f22487073ef8"]}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/checklist-tasks
PATCH
/external/v2/projects/:project_id/checklist-tasks/:id

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"
  }
}
Example Response Body
{
  "data": {
    "id": "d622725e-83ac-455a-b42d-ea13d1ccac36",
    "description": "Confirm model coordinates",
    "scope_task_ids": [
      "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
    ],
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"description":"Confirm model coordinates"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/checklist-tasks/ID
DELETE
/external/v2/projects/:project_id/checklist-tasks/:id/assignments

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.
Example Request Body
{
  "data": {
    "scope_task_ids": [
      "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
    ]
  }
}
Example Response Body
{
  "data": {
    "id": "d622725e-83ac-455a-b42d-ea13d1ccac36",
    "description": "Confirm model coordinates",
    "scope_task_ids": [],
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "removed_scope_task_ids": [
      "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
    ]
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"scope_task_ids":["7a4b1f07-b56b-4be5-b03b-f22487073ef8"]}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/checklist-tasks/ID/assignments
GET
/external/v2/projects/:project_id/scope-tasks/:scope_task_id/checklist-tasks

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.

Example Response
{
  "data": [
    {
      "id": "d622725e-83ac-455a-b42d-ea13d1ccac36",
      "description": "Confirm model coordinates",
      "scope_task_ids": [
        "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
      ],
      "created_at": "2026-01-09T09:00:00.000000Z",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "is_checked": false,
      "due_date": "2026-11-12"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/SCOPE_TASK_ID/checklist-tasks
POST
/external/v2/projects/:project_id/scope-tasks/:scope_task_id/checklist-tasks

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.
Example Request Body
{
  "data": {
    "description": "Confirm model coordinates",
    "due_date": "2026-11-12"
  }
}
Example Response Body
{
  "data": {
    "id": "d622725e-83ac-455a-b42d-ea13d1ccac36",
    "description": "Confirm model coordinates",
    "scope_task_ids": [
      "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
    ],
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "is_checked": false,
    "due_date": "2026-11-12"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"description":"Confirm model coordinates","due_date":"2026-11-12"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/SCOPE_TASK_ID/checklist-tasks
PATCH
/external/v2/projects/:project_id/scope-tasks/:scope_task_id/checklist-tasks/:id

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.
Example Request Body
{
  "data": {
    "is_checked": true,
    "due_date": "2026-11-12"
  }
}
Example Response Body
{
  "data": {
    "id": "d622725e-83ac-455a-b42d-ea13d1ccac36",
    "description": "Confirm model coordinates",
    "scope_task_ids": [
      "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
    ],
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "is_checked": true,
    "due_date": "2026-11-12"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"is_checked":true,"due_date":"2026-11-12"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/SCOPE_TASK_ID/checklist-tasks/ID
DELETE
/external/v2/projects/:project_id/scope-tasks/:scope_task_id/checklist-tasks/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "d622725e-83ac-455a-b42d-ea13d1ccac36",
    "description": "Confirm model coordinates",
    "scope_task_ids": [],
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "is_checked": null,
    "due_date": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "removed_scope_task_ids": [
      "7a4b1f07-b56b-4be5-b03b-f22487073ef8"
    ]
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/SCOPE_TASK_ID/checklist-tasks/ID
Task Information Requirements
GET
/external/v2/projects/:project_id/scope-tasks/:id/information-requirements

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.

Example Response
{
  "data": [
    {
      "id": "9a43f260-4388-45b9-ad46-6de67d1b3526",
      "title": "Curtain Wall Fire Rating",
      "description": "Provide tested fire rating for the selected assembly",
      "value": {
        "min": 1,
        "max": 3
      },
      "type": "Classification",
      "data_type": "Number between",
      "property_category": "Performance",
      "unit": {
        "id": 42,
        "title": "Hours",
        "abbreviation": "hr",
        "ids_measure": "TIME"
      },
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z",
      "requirement_tags": [
        {
          "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
          "title": "Fire/Life Safety",
          "color": "#ef4444"
        }
      ],
      "is_checked": false
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/ID/information-requirements
POST
/external/v2/projects/:project_id/scope-tasks/:id/information-requirements

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.
Example Request Body
{
  "data": {
    "information_requirement_id": "9a43f260-4388-45b9-ad46-6de67d1b3526"
  }
}
Example Response Body
{
  "data": {
    "id": "9a43f260-4388-45b9-ad46-6de67d1b3526",
    "title": "Curtain Wall Fire Rating",
    "description": "Provide tested fire rating for the selected assembly",
    "value": {
      "min": 1,
      "max": 3
    },
    "type": "Classification",
    "data_type": "Number between",
    "property_category": "Performance",
    "unit": {
      "id": 42,
      "title": "Hours",
      "abbreviation": "hr",
      "ids_measure": "TIME"
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z",
    "requirement_tags": [
      {
        "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
        "title": "Fire/Life Safety",
        "color": "#ef4444"
      }
    ]
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
    "requirement_scope_row_id": "e74fcd59-a2dd-4204-a2ff-75ecb2adbd7f",
    "requirement_scope_task_id": "534fe643-5732-4a25-b0f0-1f60da25535a8",
    "removed": false
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"information_requirement_id":"9a43f260-4388-45b9-ad46-6de67d1b3526"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/ID/information-requirements
DELETE
/external/v2/projects/:project_id/scope-tasks/:id/information-requirements/:information_requirement_id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "9a43f260-4388-45b9-ad46-6de67d1b3526",
    "title": "Curtain Wall Fire Rating",
    "description": "Provide tested fire rating for the selected assembly",
    "value": {
      "min": 1,
      "max": 3
    },
    "type": "Classification",
    "data_type": "Number between",
    "property_category": "Performance",
    "unit": {
      "id": 42,
      "title": "Hours",
      "abbreviation": "hr",
      "ids_measure": "TIME"
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z",
    "requirement_tags": [
      {
        "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
        "title": "Fire/Life Safety",
        "color": "#ef4444"
      }
    ]
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
    "requirement_scope_row_id": "e74fcd59-a2dd-4204-a2ff-75ecb2adbd7f",
    "requirement_scope_task_id": "534fe643-5732-4a25-b0f0-1f60da25535a8",
    "removed": true
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/ID/information-requirements/INFORMATION_REQUIREMENT_ID
Task Model Status
GET
/external/v2/projects/:project_id/scope-tasks/:id/model-status

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.
Example Response
{
  "data": {
    "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
    "model_version_id": "e078296b-54fd-4a52-aaf2-10245f5fe284",
    "requirements_recheck_needed": false,
    "percent_correct": 86.5,
    "total_linked_elements": 104,
    "total_linked_element_statuses": {
      "correct": 78,
      "incorrect": 12,
      "missing": 14
    },
    "information_requirements": [
      {
        "id": "9a43f260-4388-45b9-ad46-6de67d1b3526",
        "title": "Curtain Wall Fire Rating",
        "description": "Provide tested fire rating for the selected assembly",
        "value": {
          "min": 1,
          "max": 3
        },
        "type": "Classification",
        "data_type": "Number between",
        "property_category": "Performance",
        "unit": {
          "id": 42,
          "title": "Hours",
          "abbreviation": "hr",
          "ids_measure": "TIME"
        },
        "updated_at": "2026-04-15T11:30:00.000000Z",
        "created_at": "2026-01-09T09:00:00.000000Z",
        "requirement_tags": [
          {
            "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
            "title": "Fire/Life Safety",
            "color": "#ef4444"
          }
        ],
        "link_status_counts": {
          "correct": 1,
          "incorrect": 0,
          "missing": 0,
          "total": 1
        }
      }
    ],
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "model_id": "efb933d7-4154-4c2e-95f7-c53eb4cdf947",
    "model_version_id": "e078296b-54fd-4a52-aaf2-10245f5fe284"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/ID/model-status
GET
/external/v2/projects/:project_id/scope-tasks/:id/model-status/:information_requirement_id/elements

Task model-status elements: External IDs grouped by correct, incorrect, and missing for one information requirement on the task.

  • Required Params
    • model_id
      Use the id returned by /projects/:project_id/models to resolve against the latest indexed version of that model.
    • OR
    • model_version_id
      Use the id returned by /projects/:project_id/models/:model_id/model_versions when you need results for one exact model version.
Example Response
{
  "data": {
    "correct": [
      "2f4b5d1a-7e2f-4d3b-8f31-0a9d4f6c2b11",
      "9b18c4e7-2c6a-4d71-a7d1-4f2e8c6b9134"
    ],
    "incorrect": [
      "7d3c0a91-5b4f-4a0f-9f5d-12e7c9a4b221"
    ],
    "missing": [
      "c1e8a7d4-9f22-4d6e-b8a1-3e5f7c2d1049"
    ]
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc",
    "model_id": "efb933d7-4154-4c2e-95f7-c53eb4cdf947",
    "model_version_id": "e078296b-54fd-4a52-aaf2-10245f5fe284",
    "scope_task_id": "7a4b1f07-b56b-4be5-b03b-f22487073ef8",
    "information_requirement_id": "9a43f260-4388-45b9-ad46-6de67d1b3526"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/scope-tasks/ID/model-status/INFORMATION_REQUIREMENT_ID/elements
Task Statuses
GET
/external/v2/projects/:project_id/task-statuses

List task statuses: Task statuses configured for the project.

Example Response
{
  "data": [
    {
      "id": "f4e7f274-5434-4821-a4cf-38f4e1edf962",
      "title": "To Do",
      "position": 1,
      "color": "#94a3b8",
      "backlog_column": true,
      "verified_column": false,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
      "title": "In Review",
      "position": 2,
      "color": "#f59e0b",
      "backlog_column": false,
      "verified_column": false,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "id": "af5c9448-f47b-4fa5-a6b8-92d8ebfda426",
      "title": "Approved",
      "position": 3,
      "color": "#10b981",
      "backlog_column": false,
      "verified_column": true,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-statuses
POST
/external/v2/projects/:project_id/task-statuses

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.
Example Request Body
{
  "data": {
    "title": "Coordination",
    "color": "#0AA398",
    "position": 2
  }
}
Example Response Body
{
  "data": {
    "id": "7a7641e7-4247-4a24-b704-bacb500752a0",
    "title": "Coordination",
    "position": 2,
    "color": "#0AA398",
    "backlog_column": false,
    "verified_column": false,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Coordination","color":"#0AA398","position":2}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-statuses
GET
/external/v2/projects/:project_id/task-statuses/:id

Get task status: Single task status.

Example Response
{
  "data": {
    "id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
    "title": "In Review",
    "position": 2,
    "color": "#f59e0b",
    "backlog_column": false,
    "verified_column": false,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-statuses/ID
PATCH
/external/v2/projects/:project_id/task-statuses/:id

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.
Example Request Body
{
  "data": {
    "title": "Ready for Review",
    "color": "#59C7EB",
    "position": 2
  }
}
Example Response Body
{
  "data": {
    "id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
    "title": "In Review",
    "position": 2,
    "color": "#f59e0b",
    "backlog_column": false,
    "verified_column": false,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Ready for Review","color":"#59C7EB","position":2}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-statuses/ID
DELETE
/external/v2/projects/:project_id/task-statuses/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "9f2f5958-cb9e-41cc-bf7a-98d2b3bd7f72",
    "title": "In Review",
    "position": 2,
    "color": "#f59e0b",
    "backlog_column": false,
    "verified_column": false,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/task-statuses/ID
Milestone Groups
GET
/external/v2/projects/:project_id/milestone-groups

List milestone groups: Milestone groups.

  • Includes
    include=milestones Reference
    Use these values to expand related resources in the same response.
Example Response
{
  "data": [
    {
      "id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
      "title": "Design",
      "description": "Design delivery gates",
      "position": 1,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "id": "96507d77-42bc-4d6d-ab1a-68ff1f165f8b",
      "title": "Construction",
      "description": "Site and procurement gates",
      "position": 2,
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestone-groups
POST
/external/v2/projects/:project_id/milestone-groups

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.
Example Request Body
{
  "data": {
    "title": "Construction",
    "description": "Site and procurement gates",
    "position": 2
  }
}
Example Response Body
{
  "data": {
    "id": "f1ea2696-0ef7-4f0a-8d9e-a994c2ba38f5",
    "title": "Construction",
    "description": "Site and procurement gates",
    "position": 2,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Construction","description":"Site and procurement gates","position":2}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestone-groups
GET
/external/v2/projects/:project_id/milestone-groups/:id

Get milestone group: Single milestone group.

  • Includes
    include=milestones Reference
    Use these values to expand related resources in the same response.
Example Response
{
  "data": {
    "id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
    "title": "Design",
    "description": "Design delivery gates",
    "position": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestone-groups/ID
PATCH
/external/v2/projects/:project_id/milestone-groups/:id

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.
Example Request Body
{
  "data": {
    "title": "Construction",
    "description": "Site and procurement gates",
    "position": 2
  }
}
Example Response Body
{
  "data": {
    "id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
    "title": "Design",
    "description": "Design delivery gates",
    "position": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Construction","description":"Site and procurement gates","position":2}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestone-groups/ID
DELETE
/external/v2/projects/:project_id/milestone-groups/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
    "title": "Design",
    "description": "Design delivery gates",
    "position": 1,
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestone-groups/ID
Milestones
GET
/external/v2/projects/:project_id/milestones

List milestones: Project milestones.

  • Filters
    filter[milestone_group_id] Reference
    Optional filters supported on this collection endpoint.
Example Response
{
  "data": [
    {
      "id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
      "title": "60% Design Submission",
      "description": "Multi-discipline design package issue",
      "start_date": "2026-06-01",
      "end_date": "2026-06-10",
      "position": 1,
      "milestone_group": {
        "id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
        "title": "Design",
        "description": "Design delivery gates",
        "position": 1
      },
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestones
POST
/external/v2/projects/:project_id/milestones

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.
Example Request Body
{
  "data": {
    "title": "60% Design Submission",
    "description": "Multi-discipline design package issue",
    "milestone_group_id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
    "start_date": "2026-06-01",
    "end_date": "2026-06-10",
    "position": 1
  }
}
Example Response Body
{
  "data": {
    "id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
    "title": "60% Design Submission",
    "description": "Multi-discipline design package issue",
    "start_date": "2026-06-01",
    "end_date": "2026-06-10",
    "position": 1,
    "milestone_group": {
      "id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
      "title": "Design",
      "description": "Design delivery gates",
      "position": 1
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"60% Design Submission","description":"Multi-discipline design package issue","milestone_group_id":"53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d","start_date":"2026-06-01","end_date":"2026-06-10","position":1}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestones
GET
/external/v2/projects/:project_id/milestones/:id

Get milestone: Single milestone.

Example Response
{
  "data": {
    "id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
    "title": "60% Design Submission",
    "description": "Multi-discipline design package issue",
    "start_date": "2026-06-01",
    "end_date": "2026-06-10",
    "position": 1,
    "milestone_group": {
      "id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
      "title": "Design",
      "description": "Design delivery gates",
      "position": 1
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestones/ID
PATCH
/external/v2/projects/:project_id/milestones/:id

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.
Example Request Body
{
  "data": {
    "title": "60% Design Submission",
    "description": "Multi-discipline design package issue",
    "milestone_group_id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
    "start_date": "2026-06-01",
    "end_date": "2026-06-10",
    "position": 1
  }
}
Example Response Body
{
  "data": {
    "id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
    "title": "60% Design Submission",
    "description": "Multi-discipline design package issue",
    "start_date": "2026-06-01",
    "end_date": "2026-06-10",
    "position": 1,
    "milestone_group": {
      "id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
      "title": "Design",
      "description": "Design delivery gates",
      "position": 1
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"60% Design Submission","description":"Multi-discipline design package issue","milestone_group_id":"53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d","start_date":"2026-06-01","end_date":"2026-06-10","position":1}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestones/ID
DELETE
/external/v2/projects/:project_id/milestones/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "6a217d0f-692e-4987-a7d6-86c7247c5a74",
    "title": "60% Design Submission",
    "description": "Multi-discipline design package issue",
    "start_date": "2026-06-01",
    "end_date": "2026-06-10",
    "position": 1,
    "milestone_group": {
      "id": "53dd729d-67ad-46f6-87a3-0bd6e6a3cb8d",
      "title": "Design",
      "description": "Design delivery gates",
      "position": 1
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/milestones/ID

Information Requirements

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.

Example Response
{
  "data": [
    {
      "id": 42,
      "title": "Hours",
      "abbreviation": "hr",
      "ids_measure": "TIME",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "id": 43,
      "title": "Meters",
      "abbreviation": "m",
      "ids_measure": "LENGTHUNIT",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/requirement-units
Requirement Tags
GET
/external/v2/projects/:project_id/requirement-tags

List requirement tags: Requirement tags for project.

Example Response
{
  "data": [
    {
      "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
      "title": "Fire/Life Safety",
      "color": "#ef4444",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    },
    {
      "id": "f7629f1f-8711-4246-9b69-e005538a7030",
      "title": "Sustainability",
      "color": "#10b981",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/requirement-tags
POST
/external/v2/projects/:project_id/requirement-tags

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.
Example Request Body
{
  "data": {
    "title": "Fire/Life Safety",
    "color": "#ef4444"
  }
}
Example Response Body
{
  "data": {
    "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
    "title": "Fire/Life Safety",
    "color": "#ef4444",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Fire/Life Safety","color":"#ef4444"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/requirement-tags
GET
/external/v2/projects/:project_id/requirement-tags/:id

Get requirement tag: Single requirement tag.

Example Response
{
  "data": {
    "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
    "title": "Fire/Life Safety",
    "color": "#ef4444",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/requirement-tags/ID
PATCH
/external/v2/projects/:project_id/requirement-tags/:id

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.
Example Request Body
{
  "data": {
    "title": "Life Safety",
    "color": "#f97316"
  }
}
Example Response Body
{
  "data": {
    "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
    "title": "Life Safety",
    "color": "#f97316",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Life Safety","color":"#f97316"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/requirement-tags/ID
DELETE
/external/v2/projects/:project_id/requirement-tags/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
    "title": "Fire/Life Safety",
    "color": "#ef4444",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/requirement-tags/ID
Information Requirements
GET
/external/v2/projects/:project_id/information-requirements

List information requirements: Project information requirements.

  • Includes
    include=requirement_tags Reference
    Use these values to expand related resources in the same response.
  • Filters
    filter[requirement_tag_id] Reference
    Optional filters supported on this collection endpoint.
Example Response
{
  "data": [
    {
      "id": "9a43f260-4388-45b9-ad46-6de67d1b3526",
      "title": "Curtain Wall Fire Rating",
      "description": "Provide tested fire rating for the selected assembly",
      "value": {
        "min": 1,
        "max": 3
      },
      "type": "Classification",
      "data_type": "Number between",
      "property_category": "Performance",
      "unit": {
        "id": 42,
        "title": "Hours",
        "abbreviation": "hr",
        "ids_measure": "TIME"
      },
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/information-requirements
POST
/external/v2/projects/:project_id/information-requirements

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.
  • Allowed Values
    • type
      Stable information requirement type value.
      ifc identification quantification specification fabrication construction operation validation other classification cobie
    • data_type
      Verification rule value. Ranges use object values; pick lists use arrays of strings.
      any one_of one_of_comma boolean date date_exactly date_before date_after number number_between number_equals number_not_equal number_greater_than number_greater_than_or_equal number_less_than number_less_than_or_equal text text_exactly text_contains text_does_not_contain text_starts_with text_ends_with date_formatted date_between empty text_regex one_of_pipe
Example Request Body
{
  "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"
    ]
  }
}
Example Response Body
{
  "data": {
    "id": "9a43f260-4388-45b9-ad46-6de67d1b3526",
    "title": "Curtain Wall Fire Rating",
    "description": "Provide tested fire rating for the selected assembly",
    "value": {
      "min": 1,
      "max": 3
    },
    "type": "Classification",
    "data_type": "Number between",
    "property_category": "Performance",
    "unit": {
      "id": 42,
      "title": "Hours",
      "abbreviation": "hr",
      "ids_measure": "TIME"
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z",
    "requirement_tags": [
      {
        "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
        "title": "Fire/Life Safety",
        "color": "#ef4444"
      }
    ]
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
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
PATCH
/external/v2/projects/:project_id/information-requirements/:id

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.
  • Allowed Values
    • type
      Stable information requirement type value.
      ifc identification quantification specification fabrication construction operation validation other classification cobie
    • data_type
      Verification rule value. Ranges use object values; pick lists use arrays of strings.
      any one_of one_of_comma boolean date date_exactly date_before date_after number number_between number_equals number_not_equal number_greater_than number_greater_than_or_equal number_less_than number_less_than_or_equal text text_exactly text_contains text_does_not_contain text_starts_with text_ends_with date_formatted date_between empty text_regex one_of_pipe
Example Request Body
{
  "data": {
    "title": "Updated Curtain Wall Fire Rating",
    "description": "Provide updated tested fire rating for the selected assembly",
    "type": "classification",
    "data_type": "number_between",
    "value": {
      "min": 2,
      "max": 4
    },
    "property_category": "Performance",
    "unit_id": 42,
    "requirement_tag_ids": [
      "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a"
    ]
  }
}
Example Response Body
{
  "data": {
    "id": "9a43f260-4388-45b9-ad46-6de67d1b3526",
    "title": "Updated Curtain Wall Fire Rating",
    "description": "Provide tested fire rating for the selected assembly",
    "value": {
      "min": 2,
      "max": 4
    },
    "type": "Classification",
    "data_type": "Number between",
    "property_category": "Performance",
    "unit": {
      "id": 42,
      "title": "Hours",
      "abbreviation": "hr",
      "ids_measure": "TIME"
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z",
    "requirement_tags": [
      {
        "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
        "title": "Fire/Life Safety",
        "color": "#ef4444"
      }
    ]
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Updated Curtain Wall Fire Rating","description":"Provide updated tested fire rating for the selected assembly","type":"classification","data_type":"number_between","value":{"min":2,"max":4},"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/ID
DELETE
/external/v2/projects/:project_id/information-requirements/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "9a43f260-4388-45b9-ad46-6de67d1b3526",
    "title": "Curtain Wall Fire Rating",
    "description": "Provide tested fire rating for the selected assembly",
    "value": {
      "min": 1,
      "max": 3
    },
    "type": "Classification",
    "data_type": "Number between",
    "property_category": "Performance",
    "unit": {
      "id": 42,
      "title": "Hours",
      "abbreviation": "hr",
      "ids_measure": "TIME"
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/information-requirements/ID
GET
/external/v2/projects/:project_id/information-requirements/:id

Get information requirement: Single requirement.

  • Includes
    include=requirement_tags Reference
    Use these values to expand related resources in the same response.
Example Response
{
  "data": {
    "id": "9a43f260-4388-45b9-ad46-6de67d1b3526",
    "title": "Curtain Wall Fire Rating",
    "description": "Provide tested fire rating for the selected assembly",
    "value": {
      "min": 1,
      "max": 3
    },
    "type": "Classification",
    "data_type": "Number between",
    "property_category": "Performance",
    "unit": {
      "id": 42,
      "title": "Hours",
      "abbreviation": "hr",
      "ids_measure": "TIME"
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/information-requirements/ID
GET
/external/v2/projects/:project_id/information-requirements/:id/requirement-tags

Requirement tags for requirement: Nested tags related to a requirement.

Example Response
{
  "data": [
    {
      "id": "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a",
      "title": "Fire/Life Safety",
      "color": "#ef4444",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/information-requirements/ID/requirement-tags

Work Packages & Verify

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.

Example Response
{
  "data": [
    {
      "id": "ff3f25dd-9e1f-4be4-b213-81ad0606f4ac",
      "title": "Facade Package",
      "description": "Curtain wall, glazing, and external shading package",
      "compact_view": false,
      "include_unscoped_tasks": true,
      "filters": {
        "date_range": {
          "start_date": "2026-07-01T00:00:00.000Z",
          "end_date": "2026-08-01T00:00:00.000Z"
        },
        "milestone_ids": [
          "6a217d0f-692e-4987-a7d6-86c7247c5a74"
        ],
        "project_team_ids": [
          "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
        ],
        "user_ids": [
          "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
        ],
        "task_status_ids": [
          "1d83a077-4a4e-4f8f-94b0-2b2f8e4db8ce"
        ],
        "excluded_scope_row_ids": [
          "c57ce097-abf7-4f60-b8d5-3f5ef71677df"
        ],
        "requirement_tag_ids": [
          "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a"
        ],
        "requirement_tag_match": "any",
        "task_field_ids": [
          "f4f63698-6557-4c83-9dc9-3dbf7f1ea0d0"
        ],
        "model_ids": [
          "efb933d7-4154-4c2e-95f7-c53eb4cdf947"
        ]
      },
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/work-packages
GET
/external/v2/projects/:project_id/work-packages/:id

Get work package: Single work package with saved filter properties.

Example Response
{
  "data": {
    "id": "ff3f25dd-9e1f-4be4-b213-81ad0606f4ac",
    "title": "Facade Package",
    "description": "Curtain wall, glazing, and external shading package",
    "compact_view": false,
    "include_unscoped_tasks": true,
    "filters": {
      "date_range": {
        "start_date": "2026-07-01T00:00:00.000Z",
        "end_date": "2026-08-01T00:00:00.000Z"
      },
      "milestone_ids": [
        "6a217d0f-692e-4987-a7d6-86c7247c5a74"
      ],
      "project_team_ids": [
        "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
      ],
      "user_ids": [
        "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
      ],
      "task_status_ids": [
        "1d83a077-4a4e-4f8f-94b0-2b2f8e4db8ce"
      ],
      "excluded_scope_row_ids": [
        "c57ce097-abf7-4f60-b8d5-3f5ef71677df"
      ],
      "requirement_tag_ids": [
        "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a"
      ],
      "requirement_tag_match": "any",
      "task_field_ids": [
        "f4f63698-6557-4c83-9dc9-3dbf7f1ea0d0"
      ],
      "model_ids": [
        "efb933d7-4154-4c2e-95f7-c53eb4cdf947"
      ]
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/work-packages/ID
PATCH
/external/v2/projects/:project_id/work-packages/:id

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.
Example Request Body
{
  "data": {
    "title": "Facade Package",
    "description": "Curtain wall, glazing, and external shading package",
    "compact_view": false,
    "include_unscoped_tasks": true,
    "filters": {
      "date_range": {
        "start_date": "2026-07-01T00:00:00.000Z",
        "end_date": "2026-08-01T00:00:00.000Z"
      },
      "milestone_ids": [
        "6a217d0f-692e-4987-a7d6-86c7247c5a74"
      ],
      "project_team_ids": [
        "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
      ],
      "user_ids": [
        "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
      ],
      "task_status_ids": [
        "1d83a077-4a4e-4f8f-94b0-2b2f8e4db8ce"
      ],
      "excluded_scope_row_ids": [
        "c57ce097-abf7-4f60-b8d5-3f5ef71677df"
      ],
      "requirement_tag_ids": [
        "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a"
      ],
      "requirement_tag_match": "any",
      "task_field_ids": [
        "f4f63698-6557-4c83-9dc9-3dbf7f1ea0d0"
      ],
      "model_ids": [
        "efb933d7-4154-4c2e-95f7-c53eb4cdf947"
      ]
    }
  }
}
Example Response Body
{
  "data": {
    "id": "ff3f25dd-9e1f-4be4-b213-81ad0606f4ac",
    "title": "Facade Package",
    "description": "Curtain wall, glazing, and external shading package",
    "compact_view": false,
    "include_unscoped_tasks": true,
    "filters": {
      "date_range": {
        "start_date": "2026-07-01T00:00:00.000Z",
        "end_date": "2026-08-01T00:00:00.000Z"
      },
      "milestone_ids": [
        "6a217d0f-692e-4987-a7d6-86c7247c5a74"
      ],
      "project_team_ids": [
        "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
      ],
      "user_ids": [
        "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
      ],
      "task_status_ids": [
        "1d83a077-4a4e-4f8f-94b0-2b2f8e4db8ce"
      ],
      "excluded_scope_row_ids": [
        "c57ce097-abf7-4f60-b8d5-3f5ef71677df"
      ],
      "requirement_tag_ids": [
        "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a"
      ],
      "requirement_tag_match": "any",
      "task_field_ids": [
        "f4f63698-6557-4c83-9dc9-3dbf7f1ea0d0"
      ],
      "model_ids": [
        "efb933d7-4154-4c2e-95f7-c53eb4cdf947"
      ]
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"title":"Facade Package","description":"Curtain wall, glazing, and external shading package","compact_view":false,"include_unscoped_tasks":true,"filters":{"date_range":{"start_date":"2026-07-01T00:00:00.000Z","end_date":"2026-08-01T00:00:00.000Z"},"milestone_ids":["6a217d0f-692e-4987-a7d6-86c7247c5a74"],"project_team_ids":["2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"],"user_ids":["fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"],"task_status_ids":["1d83a077-4a4e-4f8f-94b0-2b2f8e4db8ce"],"excluded_scope_row_ids":["c57ce097-abf7-4f60-b8d5-3f5ef71677df"],"requirement_tag_ids":["4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a"],"requirement_tag_match":"any","task_field_ids":["f4f63698-6557-4c83-9dc9-3dbf7f1ea0d0"],"model_ids":["efb933d7-4154-4c2e-95f7-c53eb4cdf947"]}}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/work-packages/ID
DELETE
/external/v2/projects/:project_id/work-packages/:id

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.
Example Request Body
{}
Example Response Body
{
  "data": {
    "id": "ff3f25dd-9e1f-4be4-b213-81ad0606f4ac",
    "title": "Facade Package",
    "description": "Curtain wall, glazing, and external shading package",
    "compact_view": false,
    "include_unscoped_tasks": true,
    "filters": {
      "date_range": {
        "start_date": "2026-07-01T00:00:00.000Z",
        "end_date": "2026-08-01T00:00:00.000Z"
      },
      "milestone_ids": [
        "6a217d0f-692e-4987-a7d6-86c7247c5a74"
      ],
      "project_team_ids": [
        "2f1ca40f-f7fd-4864-a790-9ddc37e6fd0d"
      ],
      "user_ids": [
        "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6"
      ],
      "task_status_ids": [
        "1d83a077-4a4e-4f8f-94b0-2b2f8e4db8ce"
      ],
      "excluded_scope_row_ids": [
        "c57ce097-abf7-4f60-b8d5-3f5ef71677df"
      ],
      "requirement_tag_ids": [
        "4d8a8cff-e58d-4e53-a9f0-8ae36a5bf89a"
      ],
      "requirement_tag_match": "any",
      "task_field_ids": [
        "f4f63698-6557-4c83-9dc9-3dbf7f1ea0d0"
      ],
      "model_ids": [
        "efb933d7-4154-4c2e-95f7-c53eb4cdf947"
      ]
    },
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X DELETE -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/work-packages/ID
Models
GET
/external/v2/projects/:project_id/models

List models: Model list for project.

Example Response
{
  "data": [
    {
      "id": "efb933d7-4154-4c2e-95f7-c53eb4cdf947",
      "title": "ARC - Main Building",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/models
GET
/external/v2/projects/:project_id/models/:id

Get model: Single model.

Example Response
{
  "data": {
    "id": "efb933d7-4154-4c2e-95f7-c53eb4cdf947",
    "title": "ARC - Main Building",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/models/ID
GET
/external/v2/projects/:project_id/models/:model_id/model_versions

List model versions: Versions for one model.

Example Response
{
  "data": [
    {
      "id": "e078296b-54fd-4a52-aaf2-10245f5fe284",
      "model_id": "efb933d7-4154-4c2e-95f7-c53eb4cdf947",
      "title": "Issued for Coordination - Rev 12",
      "status": "success",
      "model_indexed": true,
      "output_type": "svf2",
      "file_type": "rvt",
      "updated_at": "2026-04-15T11:30:00.000000Z",
      "created_at": "2026-01-09T09:00:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/models/MODEL_ID/model_versions
GET
/external/v2/projects/:project_id/models/:model_id/model_versions/:id

Get model version: Single model version.

Example Response
{
  "data": {
    "id": "e078296b-54fd-4a52-aaf2-10245f5fe284",
    "model_id": "efb933d7-4154-4c2e-95f7-c53eb4cdf947",
    "title": "Issued for Coordination - Rev 12",
    "status": "success",
    "model_indexed": true,
    "output_type": "svf2",
    "file_type": "rvt",
    "updated_at": "2026-04-15T11:30:00.000000Z",
    "created_at": "2026-01-09T09:00:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/models/MODEL_ID/model_versions/ID

Other

SmartFields
GET
/external/v2/projects/:project_id/smart-fields

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.

  • Filters
    filter[key] Reference
    Optional filters supported on this collection endpoint.
Example Response
{
  "data": [
    {
      "id": "07f94c34-7349-4eb2-a413-cf8323a82b4a",
      "key": "Client",
      "field_type": "short_text",
      "value": "Acme",
      "link_url": null,
      "read_only": false,
      "propagation": null,
      "system_field_type": null,
      "reference_plan_item_id": null,
      "reference_doc_id": null,
      "created_at": "2026-01-09T09:00:00.000000Z",
      "updated_at": "2026-04-15T11:30:00.000000Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/smart-fields
GET
/external/v2/projects/:project_id/smart-fields/:id

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.

Example Response
{
  "data": {
    "id": "07f94c34-7349-4eb2-a413-cf8323a82b4a",
    "key": "Client",
    "field_type": "short_text",
    "value": "Acme",
    "link_url": null,
    "read_only": false,
    "propagation": null,
    "system_field_type": null,
    "reference_plan_item_id": null,
    "reference_doc_id": null,
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -H "Authorization: Bearer plly_user_xxx" \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/smart-fields/ID
POST
/external/v2/projects/:project_id/smart-fields

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.
      short_text long_text date boolean formatted_text hyperlink system
Example Request Body
{
  "data": {
    "key": "Client",
    "field_type": "short_text",
    "value": "Acme"
  }
}
Example Response Body
{
  "data": {
    "id": "07f94c34-7349-4eb2-a413-cf8323a82b4a",
    "key": "Client",
    "field_type": "short_text",
    "value": "Acme",
    "link_url": null,
    "read_only": false,
    "propagation": null,
    "system_field_type": null,
    "reference_plan_item_id": null,
    "reference_doc_id": null,
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X POST -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"key":"Client","field_type":"short_text","value":"Acme"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/smart-fields
PATCH
/external/v2/projects/:project_id/smart-fields/:id

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.
Example Request Body
{
  "data": {
    "value": "Acme"
  }
}
Example Response Body
{
  "data": {
    "id": "07f94c34-7349-4eb2-a413-cf8323a82b4a",
    "key": "Client",
    "field_type": "short_text",
    "value": "Acme",
    "link_url": null,
    "read_only": false,
    "propagation": null,
    "system_field_type": null,
    "reference_plan_item_id": null,
    "reference_doc_id": null,
    "created_at": "2026-01-09T09:00:00.000000Z",
    "updated_at": "2026-04-15T11:30:00.000000Z"
  },
  "meta": {
    "generated_at": "2026-04-16T17:00:00.000000Z",
    "user_id": "fd9fd8ce-c9f0-4ec8-b8c7-bf6faa86f6d6",
    "project_id": "b5f2d32d-6768-4981-b637-0db57f4262cc"
  }
}
Show cURL example
curl -X PATCH -H "Authorization: Bearer plly_user_xxx" -H "Content-Type: application/json" \
  -d '{"data":{"value":"Acme"}}' \
  https://api.plannerly.com/external/v2/projects/PROJECT_ID/smart-fields/ID

Error Shape

External API errors return JSON with a consistent shape:

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "invalid api key"
  }
}
  • 401 invalid or missing key.
  • 403 key cannot access the requested project.
  • 404 requested resource not found.
  • 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