Craft.io Portfolios API

The Portfolios API from Craft.io — 3 operation(s) for portfolios.

Operations 4

GET /portfolios/{accountId} Get portfolios #
GET /portfolio/{portfolioId}/portfolio_fields Get portfolio custom fields #
GET /portfolio/{portfolioId}/terminology Get portfolio terminology #
GET /portfolio/{portfolioId}/statuses Get portfolio statuses #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/craft-io:craft-io-portfolios-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

craft-io-portfolios-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Craft.io Public Portfolios API
  version: 1.0.0
  description: 'Our platform provides a set of comprehensive public APIs that allows users and applications to access and retrieve data about working items within our system.


    With our API, users can easily integrate item information into their own applications, such as dashboards or organizational tools for customer service, sales, and marketing.


    Our API supports a variety of data formats and retrieval methods, making it easy to customize and integrate with your existing systems. Whether you''re looking to build custom reports, track inventory, or monitor sales trends, our API provides the flexibility and scalability you need to get the job done.


    For getting an API key just approach our support team at support@craft.io or on the app chat (‘contact support’).'
  license:
    name: Terms and conditions
    url: https://craft.io/terms-and-conditions/
servers:
- url: /
tags:
- name: Portfolios
  description: ''
paths:
  /portfolios/{accountId}:
    get:
      operationId: GetPortfolios
      responses:
        '200':
          description: A list of portfolios
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/Portfolio'
                type: array
              examples:
                Example 1:
                  value:
                  - id: string
                    name: string
                    workspaces:
                    - id: string
                      name: string
                      key: string
        '400':
          description: Invalid account ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '401':
          description: No access to account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '500':
          description: An error occurred while fetching portfolios
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
      description: Get the list of your account’s portfolios and the workspaces they are connected with
      tags:
      - Portfolios
      security:
      - api_key:
        - read:portfolios:craft
      parameters:
      - in: path
        name: accountId
        required: true
        schema:
          type: string
      summary: Get portfolios
      x-summary-source: derived
  /portfolio/{portfolioId}/portfolio_fields:
    get:
      operationId: GetPortfolioCustomFields
      responses:
        '200':
          description: A list of portfolio fields and their metadata
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/CustomField'
                type: array
        '400':
          description: Invalid portfolio ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '401':
          description: No access to portfolio
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '500':
          description: An error occurred while fetching portfolio fields
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
      description: Get the list of portfolio fields and their metadata
      tags:
      - Portfolios
      security:
      - api_key:
        - read:portfolios:craft
      parameters:
      - in: path
        name: portfolioId
        required: true
        schema:
          type: string
      - in: query
        name: includeOptions
        required: false
        schema:
          default: false
          type: boolean
      summary: Get portfolio custom fields
      x-summary-source: derived
  /portfolio/{portfolioId}/terminology:
    get:
      operationId: GetPortfolioTerminology
      responses:
        '200':
          description: A list of portfolio entities terminology
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TerminologyList_Terminology_'
        '400':
          description: Invalid portfolio ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '401':
          description: No access to portfolio
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '500':
          description: An error occurred while fetching terminology
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
      description: Get the list of the portfolio entities terminology
      tags:
      - Portfolios
      security:
      - api_key:
        - read:portfolios:craft
      parameters:
      - in: path
        name: portfolioId
        required: true
        schema:
          type: string
      summary: Get portfolio terminology
      x-summary-source: derived
  /portfolio/{portfolioId}/statuses:
    get:
      operationId: GetPortfolioStatuses
      responses:
        '200':
          description: A list of the portfolio’s statuses
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/ItemStatus'
                type: array
        '400':
          description: Invalid portfolio ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '401':
          description: No access to portfolio
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '404':
          description: Portfolio not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '500':
          description: An error occurred while fetching statuses
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
      description: Get the portfolio’s full native status list (“Workflow & statuses”)
      tags:
      - Portfolios
      security:
      - api_key:
        - read:portfolios:craft
      parameters:
      - in: path
        name: portfolioId
        required: true
        schema:
          type: string
      summary: Get portfolio statuses
      x-summary-source: derived
components:
  schemas:
    Terminology:
      properties:
        category:
          type: string
        default:
          type: string
        customSingle:
          type: string
        customPlural:
          type: string
      required:
      - category
      - default
      - customSingle
      type: object
      additionalProperties: false
    OptionShape:
      type: string
      enum:
      - select
      - date
      - date_range
    CustomField:
      properties:
        id:
          type: string
        name:
          type: string
        type:
          type: string
        capacityEnabled:
          type: boolean
          description: 'NUMBER fields only: true when the container plans capacity against this

            field. A capacity field (FE, BE) is otherwise indistinguishable from any

            other number (Reach, ACV) here. Read the limits with /capacity.'
        categoryId:
          type:
          - string
          - 'null'
        categoryName:
          type:
          - string
          - 'null'
        values:
          items:
            type: string
          type: array
        options:
          items:
            $ref: '#/components/schemas/CustomFieldOption'
          type: array
        optionShape:
          $ref: '#/components/schemas/OptionShape'
        multi:
          type: boolean
        source:
          type: string
          enum:
          - portal
          - workspace
      required:
      - id
      - name
      - type
      type: object
      additionalProperties: false
    Portfolio:
      properties:
        id:
          type: string
        name:
          type:
          - string
          - 'null'
        workspaces:
          items:
            $ref: '#/components/schemas/Workspace'
          type: array
        webUrl:
          type: string
          description: Canonical Craft.io app URL for this portfolio. Computed in PublishService.
      required:
      - workspaces
      type: object
      additionalProperties: false
    ItemStatus:
      properties:
        id:
          type: string
        name:
          type: string
        phase:
          $ref: '#/components/schemas/StatusPhase'
          description: Workflow bucket the UI groups the status under. Absent if unmapped.
        color:
          type:
          - string
          - 'null'
          description: Swatch shown in the UI, e.g. `#586CF5`.
      required:
      - id
      - name
      type: object
      additionalProperties: false
    StatusPhase:
      type: string
      enum:
      - open
      - in_progress
      - done
      - released
      description: Workflow bucket a status belongs to, mirroring the core's GlobalStatus states.
    GeneralErrorResponse:
      properties:
        message:
          type: string
        error:
          type: string
          description: 'Stable machine code, present on the responses that carry one — the widget''s 401/403/404 and the

            attachment 413. Optional because most errors here only have a message, but it has to be part of

            the schema: tsoa emits `additionalProperties: false`, so an undeclared key makes every coded

            response violate the shape its own spec tells a caller to parse.


            OPTIONAL RATHER THAN A SEPARATE CODED-ERROR SCHEMA, and not for brevity: on the routes that

            carry codes, the same status can arrive with and without one. A widget-config 404 is

            `widget_unknown` when the widget id misses and a bare `Feedback portal not found` when the

            portal id does; a widget-config 401 is `token_invalid` for a bad token and a bare

            `Forbidden, there is no auth token` when the header is absent. A variant with `error` required

            would be declared on exactly those routes and would be wrong half the time they fail.


            Branch on it when it is there and fall back to the status when it is not. The vocabulary:

            401 `token_expired` (fetch a new token and retry once) | `token_invalid` | `dev_key_invalid` |

            `dev_origin_rejected`;

            403 `widget_not_enabled` | `insufficient_scope` | `mcp_disabled_by_account` | `no_paid_seat`;

            404 `widget_unknown` | `widget_deleted` | `widget_inactive` | `widget_no_categories`;

            413 `file_too_large`.

            The widget half of that list is the contract in docs/CRA-24100-widget-token-endpoint.md and is

            pinned by widgetFailureTaxonomy.test.ts — change the three together.


            Left as a free string rather than an enum on purpose — a closed set turns every new code into

            a breaking change for a generated client, and new codes are the whole point of the field.'
      required:
      - message
      type: object
      additionalProperties: false
    CustomFieldOption:
      properties:
        id:
          type: string
        label:
          type: string
        startDate:
          type:
          - string
          - 'null'
        endDate:
          type:
          - string
          - 'null'
      required:
      - id
      - label
      type: object
      additionalProperties: false
    Workspace:
      properties:
        id:
          type: string
        name:
          type:
          - string
          - 'null'
        key:
          type: string
        webUrl:
          type: string
          description: Canonical Craft.io app URL for this workspace. Computed in PublishService.
      type: object
      additionalProperties: false
    TerminologyList_Terminology_:
      properties: {}
      type: object
      additionalProperties:
        $ref: '#/components/schemas/Terminology'
  securitySchemes:
    api_key:
      type: apiKey
      in: header
      name: x-api-key
    portal_token:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: A short-lived token signed by the customer's own server with their feedback portal's widget secret, carrying the identity of whoever is submitting. Accepted only on the two feedback-creation routes, in place of x-api-key. Used by the portal's embedded feedback widget; the customer's own integration uses x-api-key instead.
externalDocs:
  description: Help center
  url: https://help.craft.io/en/
x-provenance:
  method: harvested
  publisher: Craft.io
  source: https://api.craft.io/openapi.json
  note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
    stamped by stamp-openapi-provenance.py (roadmap#793)