Craft.io Workspaces API

Workspaces are the areas where product teams are managing the full lifecycle of their products

Operations 6

GET /workspaces/{accountId} Get workspaces #
GET /workspaces Get workspaces by key #
GET /workspace/{workspaceId}/custom_fields Get custom fields #
GET /workspace/{workspaceId}/terminology Get terminology #
GET /workspace/{workspaceId}/statuses Get workspace statuses #
GET /workspace/{workspaceId}/capacity Get workspace capacity #

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-workspaces-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-workspaces-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Craft.io Public Workspaces 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: Workspaces
  description: Workspaces are the areas where product teams are managing the full lifecycle of their products
paths:
  /workspaces/{accountId}:
    get:
      operationId: GetWorkspaces
      responses:
        '200':
          description: A list of workspaces
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/Workspace'
                type: array
              examples:
                Example 1:
                  value:
                  - id: string
                    name: string
                    key: string
                  - 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 workspaces
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
      description: Get the list of your account’s workspaces (workspace ID & name)
      tags:
      - Workspaces
      security:
      - api_key:
        - read:workspace-meta:craft
      parameters:
      - in: path
        name: accountId
        required: true
        schema:
          type: string
      summary: Get workspaces
      x-summary-source: derived
  /workspaces:
    get:
      operationId: GetWorkspacesByKey
      responses:
        '200':
          description: A list of workspaces
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/Workspace'
                type: array
              examples:
                Example 1:
                  value:
                  - id: string
                    name: string
                    key: string
                  - id: string
                    name: string
                    key: string
        '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 workspaces
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
      description: Get the list of your account’s workspaces (workspace ID & name)
      tags:
      - Workspaces
      security:
      - api_key:
        - read:workspace-meta:craft
      parameters: []
      summary: Get workspaces by key
      x-summary-source: derived
  /workspace/{workspaceId}/custom_fields:
    get:
      operationId: GetCustomFields
      responses:
        '200':
          description: A list of workspace custom fields and their metadata
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/CustomField'
                type: array
        '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 custom fields
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
      description: Get the list of all workspace custom fields and their metadata
      tags:
      - Workspaces
      security:
      - api_key:
        - read:workspace-meta:craft
      parameters:
      - in: path
        name: workspaceId
        required: true
        schema:
          type: string
      - in: query
        name: includeOptions
        required: false
        schema:
          default: false
          type: boolean
      summary: Get custom fields
      x-summary-source: derived
  /workspace/{workspaceId}/terminology:
    get:
      operationId: GetTerminology
      responses:
        '200':
          description: A list of workspace entities terminology
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TerminologyList_Terminology_'
        '400':
          description: Invalid workspace 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 terminology
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
      description: Get the list of the workspace entities terminology
      tags:
      - Workspaces
      security:
      - api_key:
        - read:workspace-meta:craft
      parameters:
      - in: path
        name: workspaceId
        required: true
        schema:
          type: string
      summary: Get terminology
      x-summary-source: derived
  /workspace/{workspaceId}/statuses:
    get:
      operationId: GetWorkspaceStatuses
      responses:
        '200':
          description: A list of the workspace’s statuses
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/ItemStatus'
                type: array
        '400':
          description: Invalid workspace 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'
        '404':
          description: Workspace 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 workspace’s full native status list (“Workflow & statuses”)
      tags:
      - Workspaces
      security:
      - api_key:
        - read:workspace-meta:craft
      parameters:
      - in: path
        name: workspaceId
        required: true
        schema:
          type: string
      summary: Get workspace statuses
      x-summary-source: derived
  /workspace/{workspaceId}/capacity:
    get:
      operationId: GetWorkspaceCapacity
      responses:
        '200':
          description: Capacity limits per period per capacity field
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/CapacityRow'
                type: array
        '400':
          description: Invalid workspace 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'
        '404':
          description: Workspace not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
        '422':
          description: Invalid periodType or id list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GeneralErrorResponse'
      description: 'Get the capacity limits a workspace plans against, per period per capacity field


        The item values say how much work is loaded into a period; this says how

        much the period can hold. `netCapacity` is the figure the Capacity Planning

        view shows.


        A capacity field is a NUMBER custom field flagged `capacityEnabled` in

        get_workspace_custom_fields, or the built-in `storyPoints`, which is what

        most workspaces actually plan against.'
      tags:
      - Workspaces
      security:
      - api_key:
        - read:workspace-meta:craft
      parameters:
      - in: path
        name: workspaceId
        required: true
        schema:
          type: string
      - description: 'Which periods to read: `sprint`, `quarter`, or `timeframe` (the options of a timeframe custom field).'
        in: query
        name: periodType
        required: true
        schema:
          $ref: '#/components/schemas/CapacityPeriodType'
      - description: Optional comma-separated period ids. Omit for every period.
        in: query
        name: periodIds
        required: false
        schema:
          type: string
      - description: Optional comma-separated capacity field ids; `storyPoints` is accepted.
        in: query
        name: capacityFieldIds
        required: false
        schema:
          type: string
      summary: Get workspace capacity
      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
    CapacityLimit:
      description: 'A capacity limit for one field in one period.


        `netCapacity` is the figure the Capacity Planning view shows, read from what

        the app stored rather than recomputed — the two disagree whenever no team

        size is set, and the stored value is the one the app plans against.'
      properties:
        mode:
          type: string
          enum:
          - perMember
          - flatLimit
          description: 'How the limit was expressed. `flatLimit` is a number typed straight in;

            `perMember` is a team size and a per-person figure less a buffer.'
        capacityPerPerson:
          type: number
          format: double
          description: perMember only.
        numberOfPeople:
          type: number
          format: double
          description: perMember only.
        bufferPercent:
          type: number
          format: double
          description: perMember only, as a percentage (20 means 20%).
        flatLimit:
          type: number
          format: double
          description: flatLimit only.
        netCapacity:
          type: number
          format: double
          description: What the period can hold. Compare the sum of item values against this.
      required:
      - mode
      - netCapacity
      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
    CapacityPeriodType:
      type: string
      enum:
      - sprint
      - quarter
      - timeframe
      description: 'A period a capacity limit can be set against.


        `timeframe` is not a period table: it is an option of a timeframe custom

        field (H1 2025, Q3''2026), which a workspace can plan against instead of

        sprints or quarters. Its period id is the option id.'
    CustomFieldOption:
      properties:
        id:
          type: string
        label:
          type: string
        startDate:
          type:
          - string
          - 'null'
        endDate:
          type:
          - string
          - 'null'
      required:
      - id
      - label
      type: object
      additionalProperties: false
    CapacityRow:
      properties:
        period:
          properties:
            endDate:
              type: string
              format: date-time
            startDate:
              type: string
              format: date-time
            type:
              $ref: '#/components/schemas/CapacityPeriodType'
            name:
              type: string
            id:
              type: string
          required:
          - type
          - name
          - id
          type: object
        periodField:
          properties:
            name:
              type: string
            id:
              type: string
          required:
          - name
          - id
          type: object
          description: 'Set for `timeframe` periods: the timeframe field the option belongs to.'
        capacityField:
          properties:
            deleted:
              type: boolean
            name:
              type:
              - string
              - 'null'
            id:
              type: string
          required:
          - name
          - id
          type: object
          description: '`storyPoints` for the built-in field, otherwise a custom field id.


            `name` is null when the id resolves to nothing — the field was deleted but

            the period kept its capacity setting. `deleted` marks that explicitly, so a

            caller never has to infer it by comparing the name against the id.'
        limit:
          allOf:
          - $ref: '#/components/schemas/CapacityLimit'
          description: Null when this period sets no capacity for the field — not a zero limit.
      required:
      - period
      - capacityField
      - limit
      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)