{
  "openapi": "3.1.1",
  "info": {
    "title": "Reference Board Planner API",
    "version": "1.0.0",
    "summary": "Turn a list of website references into an editable board.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://pageboardreferenceplanner.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Turn a list of website references into an editable board.",
        "description": "Create an organized Pageboard from one reference per line, with optional source, type, platform and tags. Download the project and continue arranging it in Pageboard.\n\nMethodology:\n- Each nonempty line is split into up to five pipe-separated fields: title, source URL, site type, platform and comma-separated tags. Empty optional fields may be left blank.\n- The board allows at most 100 references and eight tags per reference. URLs must be HTTP or HTTPS without credentials; each entry receives a stable sequential ID and an editable neutral accent.\n- Links are stored as text and never fetched. Screenshots must be added separately in Pageboard; use images you have permission to include.\n- The download is the native editable project. If its encoded data exceeds one million characters, import the project file instead of using the editor link.\n\nThis tool does not capture screenshots, fetch URLs or import third-party galleries. Use your own links and images.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "pageboard_reference_planner",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PageboardReferencePlannerInput"
              },
              "examples": {
                "example1": {
                  "summary": "Create a website research board",
                  "value": {}
                },
                "example2": {
                  "summary": "Plan a collection without links",
                  "value": {
                    "name": "Event ideas",
                    "references": "Festival landing | | Event | Mobile | color, type\nTicketing page | | Event | Desktop | conversion"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageboardReferencePlannerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "PageboardReferencePlannerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "title": "Board name",
            "type": "string",
            "maxLength": 120,
            "default": "Website references"
          },
          "references": {
            "title": "References, one per line",
            "description": "Title | URL | Type | Platform | comma-separated tags. Only the title is required.",
            "type": "string",
            "maxLength": 100000,
            "default": "Quiet studio | https://example.com/studio | Portfolio | Desktop | typography, minimal\nGarden journal | https://example.org/journal | Editorial | Mobile | photography, nature"
          }
        },
        "required": []
      },
      "PageboardReferencePlannerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "project",
              "report",
              "projectFile",
              "openInApp"
            ],
            "properties": {
              "project": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "title": "Pageboard project",
                "type": "object",
                "required": [
                  "format",
                  "version",
                  "name",
                  "entries"
                ],
                "properties": {
                  "format": {
                    "const": "pageboard-project"
                  },
                  "version": {
                    "const": 1
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "entries": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "required": [
                        "id",
                        "title",
                        "url",
                        "type",
                        "platform",
                        "tags",
                        "notes",
                        "favorite",
                        "accent",
                        "screenshot"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$"
                        },
                        "title": {
                          "type": "string",
                          "maxLength": 120
                        },
                        "url": {
                          "type": "string",
                          "maxLength": 2048
                        },
                        "type": {
                          "type": "string",
                          "maxLength": 80
                        },
                        "platform": {
                          "type": "string",
                          "maxLength": 80
                        },
                        "tags": {
                          "type": "array",
                          "maxItems": 8,
                          "items": {
                            "type": "string",
                            "maxLength": 40
                          }
                        },
                        "notes": {
                          "type": "string",
                          "maxLength": 4000
                        },
                        "favorite": {
                          "type": "boolean"
                        },
                        "accent": {
                          "type": "string",
                          "pattern": "^#[0-9a-fA-F]{6}$"
                        },
                        "screenshot": {
                          "type": "string",
                          "maxLength": 400040,
                          "pattern": "^(|data:image/(png|jpeg|webp);base64,[A-Za-z0-9+/]+=*)$"
                        }
                      }
                    }
                  },
                  "moodboard": {
                    "type": "object",
                    "description": "Optional spatial moodboard on a 1600 × 1000 canvas; array order is the stacking order.",
                    "required": [
                      "items"
                    ],
                    "properties": {
                      "items": {
                        "type": "array",
                        "maxItems": 80,
                        "items": {
                          "type": "object",
                          "required": [
                            "id",
                            "kind",
                            "x",
                            "y"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$"
                            },
                            "kind": {
                              "enum": [
                                "reference",
                                "note",
                                "swatch",
                                "image"
                              ]
                            },
                            "x": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 1600
                            },
                            "y": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 1000
                            },
                            "w": {
                              "type": "integer",
                              "minimum": 120,
                              "maximum": 480
                            },
                            "h": {
                              "type": "integer",
                              "minimum": 90,
                              "maximum": 400
                            },
                            "text": {
                              "type": "string",
                              "maxLength": 300
                            },
                            "color": {
                              "type": "string",
                              "pattern": "^#[0-9a-fA-F]{6}$"
                            },
                            "ref": {
                              "type": "string",
                              "description": "Entry id of a reference card."
                            },
                            "image": {
                              "type": "string",
                              "description": "Embedded PNG/JPEG/WebP data URI of an image card (under 300 KB)."
                            }
                          }
                        }
                      }
                    }
                  }
                }
              },
              "report": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "name",
                  "entries",
                  "favorites",
                  "withScreenshots",
                  "withUrls",
                  "types",
                  "platforms",
                  "tags",
                  "moodboardCards",
                  "bytes"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "entries": {
                    "type": "integer"
                  },
                  "favorites": {
                    "type": "integer"
                  },
                  "withScreenshots": {
                    "type": "integer"
                  },
                  "withUrls": {
                    "type": "integer"
                  },
                  "types": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "integer"
                    }
                  },
                  "platforms": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "integer"
                    }
                  },
                  "tags": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "integer"
                    }
                  },
                  "moodboardCards": {
                    "type": "integer"
                  },
                  "bytes": {
                    "type": "integer"
                  }
                }
              },
              "projectFile": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "openInApp": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}