PortfolioStack

REST API

API Reference

Programmatic read access to the PortfolioStack project catalog and portfolio workspace.

Overview

The PortfolioStack REST API provides read access to the project catalog and portfolio workspace. Use it to query projects, retrieve portfolio data, and integrate PortfolioStack into your own tools, dashboards, and reporting systems.

Base URLhttps://rest.portfoliostack.com
Versionv1
ProtocolHTTPS only
Response formatJSON

Getting Started

API access requires a PortfolioStack account on a plan with API access enabled. Generate an API key from your account settings to authenticate requests.

  1. Sign in to PortfolioStack
  2. Go to Account → Integrations
  3. Under API Keys, click Generate Key
  4. Give the key a label and click Create
  5. Copy the psk_… key — it is shown once and cannot be retrieved again

If the API Keys section is not visible in Account → Integrations, API access is not enabled on your current plan.

Authentication

All requests must include your API key as a Bearer token in the Authorization header.

HTTP
Authorization: Bearer psk_your_key_here

API keys are long-lived. Store them securely and treat them like passwords. If a key is compromised, revoke it from Account → Integrations and generate a new one. You can maintain multiple active keys — for example, one per integration or environment.

Authentication errors

StatusCause
401 UnauthorizedMissing, malformed, or revoked API key
403 ForbiddenAPI access not enabled on your plan

Rate Limits

The API allows 100 requests per minute per IP address. Exceeding this limit returns a 429 Too Many Requests response.

JSON
{ "error": "Too many requests, please try again later." }

Projects

Projects are structured work plans from the PortfolioStack catalog. Each project includes a task hierarchy, industry classification, roles, compliance requirements, and linked resources.

List projects

HTTP
GET https://rest.portfoliostack.com/v1/projects

Returns a paginated list of projects from the catalog. Supports keyword search, NAICS code filtering, and role filtering.

Query parameters

ParameterTypeDefaultDescription
qstringKeyword search across project names, industries, and tags
naicsstringOne or more NAICS codes, comma-separated (e.g. 4841,2361)
rolestringRole name or alias, comma-separated. Common names and abbreviations are resolved automatically (e.g. PM, project manager, Safety Manager)
pageinteger1Page number
limitinteger50Results per page (max 100)

Response

JSON
{
  "data": [
    {
      "id": "proj_abc123",
      "name": "HAZMAT Incident Response Program",
      "industry": "Truck Transportation",
      "naics_codes": ["4841"],
      "description": "...",
      "task_count": 22,
      "phase_count": 4,
      "phases": ["Planning", "Procurement", "Execution", "Closeout"],
      "roles": ["Safety Manager", "Project Manager", "EHS Specialist"],
      "task_names": ["Initial Hazard Assessment", "PPE Procurement", "..."],
      "search_tags": ["hazmat", "dot", "emergency response"],
      "generated_at": "2025-01-15T00:00:00.000Z"
    }
  ],
  "meta": {
    "total": 2100,
    "page": 1,
    "limit": 50,
    "pages": 42,
    "suggestion": null
  }
}

When a keyword search returns no primary results, meta.suggestion may contain a spelling correction and results will reflect the corrected query. When primary results are empty but related projects exist, they appear in meta.secondary.

Get project

HTTP
GET https://rest.portfoliostack.com/v1/projects/:id

Returns full project detail including all tasks. The id parameter accepts a project ID, instance ID, or MongoDB ObjectId.

Query parameters

ParameterTypeDescription
expandstringComma-separated resource types to include on each task: skills, tools, apps

Response

JSON
{
  "id": "proj_abc123",
  "name": "HAZMAT Incident Response Program",
  "industry": "Truck Transportation",
  "naics_codes": ["4841"],
  "description": "...",
  "rationale": "...",
  "audience": "...",
  "target_companies": "...",
  "value_potential": "...",
  "sources": [{ "label": "...", "url": "..." }],
  "search_tags": ["hazmat", "dot"],
  "generated_at": "2025-01-15T00:00:00.000Z",
  "task_count": 22,
  "tasks": [
    {
      "wbs_code": "1.1",
      "name": "Initial Hazard Assessment",
      "type": "task",
      "category": "Planning",
      "owner_role": "Safety Manager",
      "duration_days": 5,
      "dependency_hints": [],
      "obligation_ids": [],
      "evidence_ids": [],
      "notes": "..."
    }
  ]
}

Portfolios

Portfolios are user-created collections of projects. Portfolio endpoints return data belonging to the authenticated user — including metrics, phases, and task-level grid data matching what is visible in the portfolio workspace.

List portfolios

HTTP
GET https://rest.portfoliostack.com/v1/portfolios

Returns all active portfolios for the authenticated user, with project summaries and counts. No query parameters.

Response

JSON
{
  "data": [
    {
      "id": "64a1b2c3d4e5f6a7b8c9d0e1",
      "name": "FY2026 Infrastructure",
      "created_at": "2026-01-10T00:00:00.000Z",
      "updated_at": "2026-07-15T00:00:00.000Z",
      "project_count": 2,
      "task_count": 87,
      "phase_count": 12,
      "projects": [
        {
          "id": "proj_abc123",
          "name": "HAZMAT Incident Response Program",
          "task_count": 30,
          "added_at": "2026-01-12T00:00:00.000Z"
        }
      ]
    }
  ]
}

Get portfolio

HTTP
GET https://rest.portfoliostack.com/v1/portfolios/:id

Returns full portfolio detail including metrics, phases, and the complete task grid for all projects in the portfolio.

Query parameters

ParameterTypeDescription
expandstringComma-separated resource types to include on each task: skills, tools, apps

Response

JSON
{
  "id": "64a1b2c3d4e5f6a7b8c9d0e1",
  "name": "FY2026 Infrastructure",
  "created_at": "2026-01-10T00:00:00.000Z",
  "updated_at": "2026-07-15T00:00:00.000Z",
  "metrics": {
    "project_count": 2,
    "task_count": 87,
    "total_estimated_cost": 412500,
    "completion_pct": 22,
    "status_breakdown": {
      "not_started": 40,
      "in_progress": 28,
      "blocked": 0,
      "complete": 19
    },
    "by_project": [
      {
        "project_id": "proj_abc123",
        "name": "HAZMAT Incident Response Program",
        "task_count": 30,
        "complete_count": 10,
        "completion_pct": 33,
        "estimated_cost": 187500
      }
    ],
    "by_role": [
      { "role": "PM", "task_count": 22 },
      { "role": "Safety Manager", "task_count": 18 }
    ]
  },
  "projects": [
    {
      "id": "64b2c3d4e5f6a7b8c9d0e1f2",
      "project_id": "proj_abc123",
      "name": "HAZMAT Incident Response Program",
      "industry": "Truck Transportation",
      "naics_codes": ["4841"],
      "added_at": "2026-01-12T00:00:00.000Z",
      "phase_count": 4,
      "task_count": 30,
      "phases": [
        {
          "wbs_code": "1.0",
          "name": "Planning Phase",
          "description": "Establish project scope and regulatory requirements."
        }
      ],
      "tasks": [
        {
          "wbs_code": "1.1.1",
          "name": "Initial Hazard Assessment",
          "phase": "Planning Phase",
          "category": "Planning",
          "owner_role": "Safety Manager",
          "duration_days": 5,
          "start_date": "2026-03-01T00:00:00.000Z",
          "end_date": "2026-03-05T00:00:00.000Z",
          "estimated_cost": 6250,
          "status": "Complete",
          "description": "...",
          "user_notes": null,
          "dependency_hints": [],
          "obligation_ids": ["OBL-001"],
          "evidence_ids": ["EV-001"]
        }
      ]
    }
  ]
}

phase vs category: phase is the name of the parent WBS summary task (e.g. "Planning Phase") derived by walking the task list. category is the task category field stored on each leaf task (e.g. "Planning").

Expand parameter

The expand query parameter enriches task-level data with linked resources from the PortfolioStack catalog. Supported on GET /v1/projects/:id and GET /v1/portfolios/:id.

ValueDescription
skillsSuggested learning pathways and certifications linked to each task
toolsRecommended software tools linked to each task
appsTask-linked app templates available in PortfolioStack

Values are comma-separated. Tasks without a linked intent return empty arrays for the requested expand types.

HTTP
GET /v1/projects/:id?expand=skills,tools,apps

Each task gains

JSON
{
  "skills": [
    {
      "id": "...",
      "name": "Hazardous Materials Handling",
      "links": [{ "name": "HAZWOPER 40-Hour", "url": "...", "platform": "OSHA" }]
    }
  ],
  "tools": [{ "id": "...", "name": "Incident Command Software", "links": [...] }],
  "apps":  [{ "id": "...", "name": "Incident Report Form", "links": [] }]
}

Error codes

All error responses return JSON with an error field describing the issue.

StatusMeaning
401Missing, malformed, or revoked API key
403API access not enabled on your plan
404Resource not found
429Rate limit exceeded — 100 requests per minute
500Unexpected server error
JSON
{ "error": "Invalid or revoked API key." }