{
  "openapi": "3.1.0",
  "info": {
    "title": "Harmony REST API",
    "version": "1.0",
    "summary": "Work with your AI Agents in Harmony.",
    "description": "Harmony is the shared surface for human–agent teams: one board where people\nand agents take an idea to a shipped PR.\n\n## Authentication\n\nTwo credentials reach this API, both in a request header. Every endpoint\nbelow needs one, except `GET /v1` and `GET /v1/health`, which are public.\n\n- `X-API-Key: hmy_...` — an API key created at https://gethmy.com/user/keys.\n  It acts for the user who created it, across every workspace that user\n  belongs to.\n- `Authorization: Bearer hmy_at_...` — an OAuth 2.1 access token issued by\n  https://app.gethmy.com. Harmony issues one named scope, `mcp`, and binds\n  each grant to the set of workspaces the user selected at consent time. A\n  request outside that set is refused with `403`, so the workspace binding\n  is the least-privilege boundary, not the scope string. The matching\n  RFC 9728 metadata is published at\n  https://gethmy.com/.well-known/oauth-protected-resource/api.\n\n## Errors\n\nEvery failure answers a JSON body of the shape `{\"error\": \"...\"}` with the\nstatus code listed on the operation.\n\n## Rate limiting\n\nRequests are rate limited per user. Over the limit answers `429`.\n\n## Links\n\n- Marketing: https://gethmy.com\n- Quick setup: https://gethmy.com/llms.txt\n- Full docs: https://gethmy.com/llms-full.txt\n- Authentication guide: https://gethmy.com/auth.md\n- MCP package: https://www.npmjs.com/package/@gethmy/mcp\n- Create an API key: https://gethmy.com/user/keys\n",
    "termsOfService": "https://gethmy.com/terms",
    "contact": {
      "name": "Harmony",
      "email": "hello@gethmy.com",
      "url": "https://gethmy.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://gethmy.com/terms"
    }
  },
  "externalDocs": {
    "description": "Full documentation for agents",
    "url": "https://gethmy.com/llms-full.txt"
  },
  "servers": [
    {
      "url": "https://gethmy.com/api",
      "description": "Production (marketing domain)"
    },
    {
      "url": "https://app.gethmy.com/api",
      "description": "Production (app domain)"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "OAuth2": [
        "mcp"
      ]
    }
  ],
  "tags": [
    {
      "name": "Discovery",
      "description": "Public endpoints that need no credential."
    },
    {
      "name": "Workspaces",
      "description": "Workspaces the credential can reach."
    },
    {
      "name": "Projects",
      "description": "Projects inside a workspace."
    },
    {
      "name": "Board",
      "description": "The full board state for a project."
    },
    {
      "name": "Cards",
      "description": "Create, read, update, move, and search cards."
    },
    {
      "name": "Columns",
      "description": "The columns a card moves through."
    },
    {
      "name": "Labels",
      "description": "Labels on a board and on a card."
    },
    {
      "name": "Subtasks",
      "description": "Checklist items on a card."
    },
    {
      "name": "Links",
      "description": "Relationships between cards."
    },
    {
      "name": "Agents",
      "description": "Prompts generated from a card for an agent to work from."
    },
    {
      "name": "NLU",
      "description": "Natural-language commands against the board."
    }
  ],
  "paths": {
    "/v1": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getApiIndex",
        "summary": "API index",
        "description": "Public index of this API — the spec URL, the accepted credentials, and\nthe endpoint list. Needs no credential, so an agent can confirm the\nsurface exists before it asks a user for a key.\n",
        "security": [],
        "responses": {
          "200": {
            "description": "The API index.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiIndex"
                }
              }
            }
          }
        }
      }
    },
    "/v1/health": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getHealth",
        "summary": "Liveness probe",
        "description": "Public and unrated. A rate-limited liveness probe reports a false\noutage under exactly the load you need it during.\n",
        "security": [],
        "responses": {
          "200": {
            "description": "The service is up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces": {
      "get": {
        "tags": [
          "Workspaces"
        ],
        "operationId": "listWorkspaces",
        "summary": "List workspaces accessible to the credential",
        "description": "An OAuth token lists only the workspaces its grant covers. An API key\nlists every workspace its user belongs to.\n",
        "responses": {
          "200": {
            "description": "The workspaces this credential can reach.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Workspace"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/workspaces/{id}/projects": {
      "get": {
        "tags": [
          "Projects"
        ],
        "operationId": "listProjects",
        "summary": "List projects in a workspace",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "The projects in the workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Project"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/workspaces/{id}/members": {
      "get": {
        "tags": [
          "Workspaces"
        ],
        "operationId": "listWorkspaceMembers",
        "summary": "Get workspace members",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "The members of the workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WorkspaceMember"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/board/{projectId}": {
      "get": {
        "tags": [
          "Board"
        ],
        "operationId": "getBoard",
        "summary": "Get the full board state for a project",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Columns, cards, and labels for the project.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Board"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/cards": {
      "post": {
        "tags": [
          "Cards"
        ],
        "operationId": "createCard",
        "summary": "Create a card",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardCreate"
              },
              "example": {
                "projectId": "6590761b-5b8e-4909-a8d2-c47bc920fbfc",
                "columnId": "c5b4fa13-1db3-40c7-a3ca-8e9426f7b8b8",
                "title": "Return a real 404 for unknown paths",
                "priority": "high"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created card.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Card"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/cards/{id}": {
      "get": {
        "tags": [
          "Cards"
        ],
        "operationId": "getCard",
        "summary": "Get a card",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "The card.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Card"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "tags": [
          "Cards"
        ],
        "operationId": "updateCard",
        "summary": "Update a card",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated card.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Card"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "tags": [
          "Cards"
        ],
        "operationId": "deleteCard",
        "summary": "Delete a card",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "204": {
            "description": "The card was deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/cards/{id}/move": {
      "post": {
        "tags": [
          "Cards"
        ],
        "operationId": "moveCard",
        "summary": "Move a card to a different column",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "columnId"
                ],
                "properties": {
                  "columnId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "position": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The moved card.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Card"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/search": {
      "get": {
        "tags": [
          "Cards"
        ],
        "operationId": "searchCards",
        "summary": "Search cards",
        "description": "Searches titles and descriptions. An OAuth token only ever matches\ncards inside the workspaces its grant covers.\n",
        "parameters": [
          {
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "agent readiness"
          }
        ],
        "responses": {
          "200": {
            "description": "The matching cards.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Card"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/columns": {
      "post": {
        "tags": [
          "Columns"
        ],
        "operationId": "createColumn",
        "summary": "Create a column",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "projectId",
                  "name"
                ],
                "properties": {
                  "projectId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string"
                  },
                  "position": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created column.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Column"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/v1/columns/{id}": {
      "patch": {
        "tags": [
          "Columns"
        ],
        "operationId": "updateColumn",
        "summary": "Update a column",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "position": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated column.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Column"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "delete": {
        "tags": [
          "Columns"
        ],
        "operationId": "deleteColumn",
        "summary": "Delete a column",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "204": {
            "description": "The column was deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/labels": {
      "post": {
        "tags": [
          "Labels"
        ],
        "operationId": "createLabel",
        "summary": "Create a label",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "projectId",
                  "name"
                ],
                "properties": {
                  "projectId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created label.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Label"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/cards/{id}/labels": {
      "post": {
        "tags": [
          "Labels"
        ],
        "operationId": "addLabelToCard",
        "summary": "Add a label to a card",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "labelId"
                ],
                "properties": {
                  "labelId": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The label is on the card."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/cards/{id}/labels/{labelId}": {
      "delete": {
        "tags": [
          "Labels"
        ],
        "operationId": "removeLabelFromCard",
        "summary": "Remove a label from a card",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "in": "path",
            "name": "labelId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The label is off the card."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/subtasks": {
      "post": {
        "tags": [
          "Subtasks"
        ],
        "operationId": "createSubtask",
        "summary": "Create a subtask",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "cardId",
                  "title"
                ],
                "properties": {
                  "cardId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "title": {
                    "type": "string"
                  },
                  "position": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created subtask.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subtask"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/subtasks/{id}/toggle": {
      "post": {
        "tags": [
          "Subtasks"
        ],
        "operationId": "toggleSubtask",
        "summary": "Toggle subtask completion",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "The subtask, with its new completion state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subtask"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/subtasks/{id}": {
      "delete": {
        "tags": [
          "Subtasks"
        ],
        "operationId": "deleteSubtask",
        "summary": "Delete a subtask",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "204": {
            "description": "The subtask was deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/cards/{id}/links": {
      "get": {
        "tags": [
          "Links"
        ],
        "operationId": "listCardLinks",
        "summary": "Get card links",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "The links on the card.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CardLink"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "post": {
        "tags": [
          "Links"
        ],
        "operationId": "createCardLink",
        "summary": "Create a card link",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "targetId",
                  "linkType"
                ],
                "properties": {
                  "targetId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "linkType": {
                    "type": "string",
                    "enum": [
                      "relates_to",
                      "blocks",
                      "duplicates",
                      "is_part_of"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created link.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CardLink"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/links/{id}": {
      "delete": {
        "tags": [
          "Links"
        ],
        "operationId": "deleteCardLink",
        "summary": "Delete a card link",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "204": {
            "description": "The link was deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/cards/{id}/prompt": {
      "get": {
        "tags": [
          "Agents"
        ],
        "operationId": "generateCardPrompt",
        "summary": "Generate an AI-ready prompt from a card",
        "description": "Builds role framing, focus areas, subtasks, and linked cards into one\nprompt an agent can work from.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "in": "query",
            "name": "variant",
            "description": "`analysis` to understand and plan, `draft` to design a solution,\n`execute` to implement fully. Defaults to `execute`.\n",
            "schema": {
              "type": "string",
              "enum": [
                "analysis",
                "draft",
                "execute"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The generated prompt.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "prompt": {
                      "type": "string"
                    },
                    "variant": {
                      "type": "string",
                      "enum": [
                        "analysis",
                        "draft",
                        "execute"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/nlu": {
      "post": {
        "tags": [
          "NLU"
        ],
        "operationId": "processCommand",
        "summary": "Process a natural-language command",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "command"
                ],
                "properties": {
                  "command": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "command": "move card 42 to review"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The interpreted command and what it did.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API key generated at https://gethmy.com/user/keys (starts with `hmy_`).\nIt acts for the user who created it, across every workspace that user\nbelongs to.\n"
      },
      "OAuth2": {
        "type": "oauth2",
        "description": "OAuth 2.1 with PKCE. Dynamic client registration (RFC 7591) and\nauthorization server metadata (RFC 8414) are published at\nhttps://app.gethmy.com/.well-known/oauth-authorization-server. The\nprotected-resource metadata for this API (RFC 9728) is at\nhttps://gethmy.com/.well-known/oauth-protected-resource/api.\n\nBeyond the `mcp` scope, each grant is bound at consent time to the set\nof workspaces the user selected. A request outside that set is refused\nwith `403`.\n",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://app.gethmy.com/oauth/authorize",
            "tokenUrl": "https://app.gethmy.com/oauth/token",
            "refreshUrl": "https://app.gethmy.com/oauth/token",
            "scopes": {
              "mcp": "Read and write the cards, columns, labels, subtasks, links, and\nagent sessions of the workspaces this grant covers.\n"
            }
          }
        }
      }
    },
    "parameters": {
      "Id": {
        "in": "path",
        "name": "id",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request was malformed or missing a required field.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "No credential, or the credential is invalid.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Missing API key or Authorization header"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The credential is valid but does not cover this workspace. An OAuth\ntoken scoped to one set of workspaces cannot act on another.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "OAuth token is scoped to a different workspace"
            }
          }
        }
      },
      "NotFound": {
        "description": "No such resource, or the credential cannot see it.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Card not found"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests for this user.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Rate limit exceeded. Please try again later."
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "A human-readable description of what went wrong."
          }
        }
      },
      "Health": {
        "type": "object",
        "required": [
          "status",
          "service"
        ],
        "properties": {
          "status": {
            "type": "string",
            "const": "ok"
          },
          "service": {
            "type": "string",
            "const": "harmony-api"
          }
        }
      },
      "ApiIndex": {
        "type": "object",
        "description": "The public index of this API. Lists the spec, the accepted credentials,\nand the endpoints.\n",
        "required": [
          "status",
          "service",
          "name",
          "baseUrl"
        ],
        "properties": {
          "status": {
            "type": "string",
            "const": "ok"
          },
          "service": {
            "type": "string",
            "const": "harmony-api"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "baseUrl": {
            "type": "string",
            "format": "uri"
          },
          "documentation": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          },
          "authentication": {
            "type": "object",
            "properties": {
              "required": {
                "type": "boolean"
              },
              "schemes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "publicEndpoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EndpointSummary"
            }
          },
          "endpoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EndpointSummary"
            }
          },
          "contact": {
            "type": "object",
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "EndpointSummary": {
        "type": "object",
        "required": [
          "method",
          "path"
        ],
        "properties": {
          "method": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          }
        }
      },
      "Workspace": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "role": {
            "type": "string",
            "description": "The calling user's role in this workspace."
          }
        }
      },
      "WorkspaceMember": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "role": {
            "type": "string"
          },
          "full_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Project": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Column": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "project_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "position": {
            "type": "integer"
          }
        }
      },
      "Label": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "project_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "color": {
            "type": "string"
          }
        }
      },
      "Subtask": {
        "type": "object",
        "required": [
          "id",
          "title"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "card_id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "completed": {
            "type": "boolean"
          },
          "position": {
            "type": "integer"
          }
        }
      },
      "CardLink": {
        "type": "object",
        "required": [
          "id",
          "link_type"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "source_card_id": {
            "type": "string",
            "format": "uuid"
          },
          "target_card_id": {
            "type": "string",
            "format": "uuid"
          },
          "link_type": {
            "type": "string",
            "enum": [
              "relates_to",
              "blocks",
              "duplicates",
              "is_part_of"
            ]
          }
        }
      },
      "Priority": {
        "type": "string",
        "enum": [
          "low",
          "medium",
          "high",
          "urgent"
        ]
      },
      "Card": {
        "type": "object",
        "description": "A card. The API returns the stored row plus its hydrated relations, so\nfields beyond the ones named here may appear.\n",
        "additionalProperties": true,
        "required": [
          "id",
          "title",
          "project_id",
          "column_id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "short_id": {
            "type": "integer",
            "description": "The per-project number a card is referenced by, e.g. 42."
          },
          "project_id": {
            "type": "string",
            "format": "uuid"
          },
          "column_id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "priority": {
            "$ref": "#/components/schemas/Priority"
          },
          "assignee_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "due_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "estimate_hours": {
            "type": [
              "number",
              "null"
            ]
          },
          "position": {
            "type": "number"
          },
          "done": {
            "type": "boolean"
          },
          "archived_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "labelIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "subtasks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Subtask"
            }
          },
          "column": {
            "$ref": "#/components/schemas/Column"
          }
        }
      },
      "CardCreate": {
        "type": "object",
        "required": [
          "projectId",
          "columnId",
          "title"
        ],
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "columnId": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "priority": {
            "$ref": "#/components/schemas/Priority"
          }
        }
      },
      "CardUpdate": {
        "type": "object",
        "description": "Only the fields present are changed.",
        "properties": {
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "priority": {
            "$ref": "#/components/schemas/Priority"
          },
          "done": {
            "type": "boolean"
          },
          "assigneeId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Board": {
        "type": "object",
        "description": "The full board state for one project.",
        "properties": {
          "project": {
            "$ref": "#/components/schemas/Project"
          },
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Column"
            }
          },
          "cards": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Card"
            }
          },
          "labels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Label"
            }
          }
        }
      }
    }
  }
}
