{
 "openapi": "3.0.3",
 "info": {
  "title": "Screenrove API",
  "version": "1.0.0",
  "description": "Read-only access to Screenrove's library of real product UI captures: onboarding flows,\nmarketing pages and in-product screens, each with notes, observed transitions and a\nmeasured design guide. Built for coding agents that need visual references before\nbuilding a UI.\n\nEverything here is observed from live products on the capture date. Treat it as\nreference, not source code or official brand guidance.\n\nThis file is the single source of truth. `npm run generate:api` runs it through\nForge (github.com/cloudflare/forge) to produce the MCP tool list served at /mcp.\n"
 },
 "servers": [
  {
   "url": "https://screenrove.com"
  }
 ],
 "x-forge-commands": {
  "products": {
   "description": "Captured products and their design guides."
  },
  "screens": {
   "description": "Individual captured screens and pages."
  },
  "handoffs": {
   "description": "Ready-to-paste build prompts for coding agents."
  },
  "picks": {
   "description": "Let a person choose a reference in their browser."
  },
  "checks": {
   "description": "Compare the user's own UI with real references."
  }
 },
 "tags": [
  {
   "name": "products"
  },
  {
   "name": "screens"
  },
  {
   "name": "handoffs"
  },
  {
   "name": "picks"
  },
  {
   "name": "checks"
  }
 ],
 "paths": {
  "/api/v1/products": {
   "get": {
    "operationId": "listProducts",
    "tags": [
     "products"
    ],
    "x-fern-sdk-group-name": "products",
    "x-fern-sdk-method-name": "list",
    "summary": "List captured products",
    "description": "List every product in the library with its capture date, tags, coverage notes and\nscreen counts. Start here to see what references exist.\n",
    "responses": {
     "200": {
      "description": "Product summaries.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "products": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/ProductSummary"
           }
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/products/{productId}": {
   "get": {
    "operationId": "getProduct",
    "tags": [
     "products"
    ],
    "x-fern-sdk-group-name": "products",
    "x-fern-sdk-method-name": "get",
    "summary": "Get one product",
    "description": "Get a product's coverage notes, design summary and every screen it contains, grouped\ninto the onboarding flow, marketing pages and in-product screens.\n",
    "parameters": [
     {
      "$ref": "#/components/parameters/productId"
     }
    ],
    "responses": {
     "200": {
      "description": "The product with its screens.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Product"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     }
    }
   }
  },
  "/api/v1/products/{productId}/design": {
   "get": {
    "operationId": "getDesign",
    "tags": [
     "products"
    ],
    "x-fern-sdk-group-name": "products",
    "x-fern-sdk-method-name": "design",
    "summary": "Get a product's design guide",
    "description": "Get the measured design guide for a product: font, palette, type scale, layout and\ncomponent notes. Marketing site and product UI are measured separately.\n",
    "parameters": [
     {
      "$ref": "#/components/parameters/productId"
     },
     {
      "name": "context",
      "in": "query",
      "description": "Which surface to return. Omit for both.",
      "schema": {
       "type": "string",
       "enum": [
        "marketing",
        "product"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The design guide.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Design"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     }
    }
   }
  },
  "/api/v1/screens": {
   "get": {
    "operationId": "searchScreens",
    "tags": [
     "screens"
    ],
    "x-fern-sdk-group-name": "screens",
    "x-fern-sdk-method-name": "search",
    "summary": "Search screens",
    "description": "Search every captured screen by keyword across titles, notes, page sections and\nobserved actions. Filter by product or kind. Use this to find references like\n\"pricing page\", \"empty state\" or \"date picker\".\n",
    "parameters": [
     {
      "name": "q",
      "in": "query",
      "description": "Keywords to match. Omit to list everything that matches the filters.",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "product",
      "in": "query",
      "description": "Only return screens from this product id, e.g. linear.",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "kind",
      "in": "query",
      "description": "Only return this kind of screen.",
      "schema": {
       "$ref": "#/components/schemas/ScreenKind"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "description": "Maximum results, 1 to 50.",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 50,
       "default": 20
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Matching screens, best match first.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "total": {
           "type": "integer"
          },
          "screens": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/ScreenSummary"
           }
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/screens/{screenId}": {
   "get": {
    "operationId": "getScreen",
    "tags": [
     "screens"
    ],
    "x-fern-sdk-group-name": "screens",
    "x-fern-sdk-method-name": "get",
    "summary": "Get one screen",
    "description": "Get everything recorded about one screen: notes, source URL, image URLs and\ndimensions, observed actions and where they lead, and page sections for long pages.\n",
    "parameters": [
     {
      "$ref": "#/components/parameters/screenId"
     }
    ],
    "responses": {
     "200": {
      "description": "The screen.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Screen"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     }
    }
   }
  },
  "/api/v1/screens/{screenId}/image": {
   "get": {
    "operationId": "getScreenImage",
    "tags": [
     "screens"
    ],
    "x-fern-sdk-group-name": "screens",
    "x-fern-sdk-method-name": "image",
    "summary": "Get a screen's screenshot",
    "description": "Get the screenshot itself so you can look at it. For marketing pages taller than\n4000px, preview returns only the first screen (above the fold); use size=full for the\nwhole page, which can exceed what vision models accept. getScreen lists the page's\nsections with their y offsets.\n",
    "parameters": [
     {
      "$ref": "#/components/parameters/screenId"
     },
     {
      "name": "size",
      "in": "query",
      "description": "preview (default) keeps images small enough to view; full returns the original capture.",
      "schema": {
       "type": "string",
       "enum": [
        "preview",
        "full"
       ],
       "default": "preview"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JPEG screenshot.",
      "content": {
       "image/jpeg": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     }
    }
   }
  },
  "/api/v1/handoffs/{referenceId}": {
   "get": {
    "operationId": "buildHandoff",
    "tags": [
     "handoffs"
    ],
    "x-fern-sdk-group-name": "handoffs",
    "x-fern-sdk-method-name": "build",
    "x-mcp-text-field": "prompt",
    "summary": "Build an agent handoff prompt",
    "description": "Build the same ready-to-follow prompt as the \"Use in agent\" button: ordered\nscreens with notes, observed transitions, image URLs, the design guide and an\nimplementation checklist. Use a product's onboarding flow (`{product}-onboarding`),\nits whole collection (`{product}-collection`) or any single screen id.\n",
    "parameters": [
     {
      "name": "referenceId",
      "in": "path",
      "required": true,
      "description": "e.g. linear-onboarding, stripe-collection or vercel-marketing-pricing.",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "goal",
      "in": "query",
      "description": "What you want to build. Goes at the top of the prompt.",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "stack",
      "in": "query",
      "description": "Preferred stack, e.g. Next.js and Tailwind.",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "screens",
      "in": "query",
      "description": "Comma-separated screen ids to keep. Omit to include every screen in the reference.",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "includeDesign",
      "in": "query",
      "description": "Include the observed design guide. Set false to use your project's own design system.",
      "schema": {
       "type": "boolean",
       "default": true
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Prompt and machine-readable manifest.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Handoff"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     }
    }
   }
  },
  "/api/v1/picks": {
   "post": {
    "operationId": "pickReference",
    "tags": [
     "picks"
    ],
    "x-fern-sdk-group-name": "picks",
    "x-fern-sdk-method-name": "create",
    "x-mcp-ui": "ui://screenrove/picker-v1",
    "summary": "Let the user pick a reference",
    "description": "Show the user a few matching references side by side in their browser and let them\nclick the one to build from. Prefer this over sending full-page images whenever the\nuser should decide. Returns a url: open it for them (run `open <url>` on macOS,\n`xdg-open <url>` on Linux, or show the link), tell them to choose, then call\nwaitForPick with the pickId.\n",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "q": {
          "type": "string",
          "description": "Search words, e.g. \"pricing page\". The best matches become the options."
         },
         "screens": {
          "type": "string",
          "description": "Comma-separated screen ids to show instead of searching, e.g. from an earlier searchScreens."
         },
         "product": {
          "type": "string",
          "description": "Only search this product id."
         },
         "kind": {
          "type": "string",
          "description": "Only search this kind of screen.",
          "enum": [
           "flow",
           "marketing",
           "product"
          ]
         },
         "count": {
          "type": "integer",
          "description": "How many options to show when searching, 2 to 6.",
          "default": 3
         },
         "goal": {
          "type": "string",
          "description": "What the user is building, shown on the page and used in the build prompt, e.g. \"NSDR premium upgrade page\"."
         },
         "stack": {
          "type": "string",
          "description": "Preferred stack for the build prompt."
         }
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The pick page is ready.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PickCreated"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     }
    }
   }
  },
  "/api/v1/picks/{pickId}": {
   "get": {
    "operationId": "waitForPick",
    "tags": [
     "picks"
    ],
    "x-fern-sdk-group-name": "picks",
    "x-fern-sdk-method-name": "wait",
    "x-mcp-text-field": "prompt",
    "x-mcp-image-field": "choice.previewUrl",
    "summary": "Wait for the user's pick",
    "description": "Wait for the user to choose on the pick page. Returns as soon as they click, or\nstatus pending after the wait; call again if so. Once chosen, returns their reference\nwith its screenshot and a full build prompt, so you can start building from it.\n",
    "parameters": [
     {
      "$ref": "#/components/parameters/pickId"
     },
     {
      "name": "wait",
      "in": "query",
      "description": "Seconds to wait for a choice, 0 to 50.",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "maximum": 50,
       "default": 45
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The pick's status and, once chosen, the reference and build prompt.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PickResult"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     }
    }
   }
  },
  "/api/v1/picks/{pickId}/choice": {
   "post": {
    "operationId": "choosePick",
    "tags": [
     "picks"
    ],
    "x-fern-sdk-group-name": "picks",
    "x-fern-sdk-method-name": "choose",
    "x-mcp-exclude": true,
    "summary": "Record the user's pick",
    "description": "Called by the pick page when the user clicks an option or \"None of these fit\". The first answer wins.",
    "parameters": [
     {
      "$ref": "#/components/parameters/pickId"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "screenId": {
          "type": "string",
          "description": "The chosen option's screen id."
         },
         "dismissed": {
          "type": "boolean",
          "description": "True when none of the options fit."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The saved answer.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "chosen",
            "dismissed"
           ]
          },
          "choice": {
           "type": "string",
           "nullable": true
          }
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     }
    }
   }
  },
  "/api/v1/checks": {
   "post": {
    "operationId": "checkMyUi",
    "tags": [
     "checks"
    ],
    "x-fern-sdk-group-name": "checks",
    "x-fern-sdk-method-name": "create",
    "x-mcp-text-field": "report",
    "x-mcp-image-field": "references.0.previewUrl",
    "x-mcp-read-only": true,
    "summary": "Check the user's UI against real references",
    "description": "Find the real product screens closest to the user's own screen or flow and compare\nthem: step counts, plan counts, page sections. First look at the user's screenshot or\nrunning app yourself, then describe its structure in these fields. Do not send the\nimage, and leave out real names, emails, prices or customer data: structure only.\nReturns a short report with the closest references (the best match's screenshot\nattached). To let the user choose one to build from, pass their ids to pickReference.\n",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "description"
        ],
        "properties": {
         "description": {
          "type": "string",
          "description": "One or two sentences on what the screen is for and how it is laid out, e.g. \"Pricing page with three plan cards, a monthly/yearly toggle and a feature table\"."
         },
         "screenType": {
          "type": "string",
          "description": "What kind of screen it is.",
          "enum": [
           "landing",
           "pricing",
           "feature-page",
           "sign-up",
           "sign-in",
           "verification",
           "onboarding-step",
           "plan-picker",
           "empty-state",
           "dashboard",
           "list",
           "detail",
           "create-form",
           "search",
           "picker",
           "booking",
           "checkout",
           "marketplace",
           "settings",
           "docs",
           "menu",
           "lesson"
          ]
         },
         "sections": {
          "type": "array",
          "items": {
           "type": "string"
          },
          "description": "Page sections top to bottom, e.g. [\"Hero\", \"Plan cards\", \"FAQ\"]."
         },
         "flowSteps": {
          "type": "array",
          "items": {
           "type": "string"
          },
          "description": "For a multi-screen flow, each step's title in order, e.g. [\"Sign up\", \"Verify email\", \"Create workspace\"]."
         },
         "flowType": {
          "type": "string",
          "description": "What the flow does, so step counts are only compared with flows of the same kind. Inferred from screenType when omitted.",
          "enum": [
           "signup-onboarding",
           "search",
           "checkout",
           "booking",
           "marketplace"
          ]
         },
         "primaryAction": {
          "type": "string",
          "description": "The main button or action, e.g. \"Start free trial\"."
         },
         "planCount": {
          "type": "integer",
          "description": "For pricing screens, how many plans are shown."
         },
         "kind": {
          "type": "string",
          "description": "Only compare with this kind of capture.",
          "enum": [
           "flow",
           "marketing",
           "product"
          ]
         },
         "product": {
          "type": "string",
          "description": "Only compare with this product id."
         },
         "limit": {
          "type": "integer",
          "description": "How many references to return, 1 to 5.",
          "default": 4
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Closest references with comparisons.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CheckResult"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     }
    }
   }
  }
 },
 "components": {
  "parameters": {
   "pickId": {
    "name": "pickId",
    "in": "path",
    "required": true,
    "description": "The pickId returned by pickReference.",
    "schema": {
     "type": "string"
    }
   },
   "productId": {
    "name": "productId",
    "in": "path",
    "required": true,
    "description": "Product id from listProducts, e.g. linear, stripe or airbnb.",
    "schema": {
     "type": "string"
    }
   },
   "screenId": {
    "name": "screenId",
    "in": "path",
    "required": true,
    "description": "Screen id from searchScreens or getProduct, e.g. linear-signup.",
    "schema": {
     "type": "string"
    }
   }
  },
  "responses": {
   "NotFound": {
    "description": "No product, screen or reference with that id.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "BadRequest": {
    "description": "The request could not be used.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   }
  },
  "schemas": {
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string"
     }
    }
   },
   "ScreenKind": {
    "type": "string",
    "description": "flow is an onboarding step, marketing a public web page, product an in-app screen.",
    "enum": [
     "flow",
     "marketing",
     "product"
    ]
   },
   "ProductSummary": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "description": {
      "type": "string"
     },
     "captured": {
      "type": "string",
      "format": "date"
     },
     "tags": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "source": {
      "type": "string"
     },
     "url": {
      "type": "string"
     },
     "counts": {
      "type": "object",
      "properties": {
       "flow": {
        "type": "integer"
       },
       "marketing": {
        "type": "integer"
       },
       "product": {
        "type": "integer"
       }
      }
     }
    }
   },
   "Product": {
    "allOf": [
     {
      "$ref": "#/components/schemas/ProductSummary"
     },
     {
      "type": "object",
      "properties": {
       "coverage": {
        "type": "string"
       },
       "captureNote": {
        "type": "string"
       },
       "flowTitle": {
        "type": "string"
       },
       "handoffs": {
        "type": "array",
        "items": {
         "type": "string"
        }
       },
       "screens": {
        "type": "object",
        "properties": {
         "flow": {
          "type": "array",
          "items": {
           "$ref": "#/components/schemas/ScreenSummary"
          }
         },
         "marketing": {
          "type": "array",
          "items": {
           "$ref": "#/components/schemas/ScreenSummary"
          }
         },
         "product": {
          "type": "array",
          "items": {
           "$ref": "#/components/schemas/ScreenSummary"
          }
         }
        }
       }
      }
     }
    ]
   },
   "ScreenSummary": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "product": {
      "type": "string"
     },
     "kind": {
      "$ref": "#/components/schemas/ScreenKind"
     },
     "title": {
      "type": "string"
     },
     "notes": {
      "type": "string"
     },
     "imageUrl": {
      "type": "string"
     },
     "previewUrl": {
      "type": "string",
      "description": "Screen-sized preview (the top of long pages). Present on pick options."
     },
     "productName": {
      "type": "string",
      "description": "Present on pick options."
     }
    }
   },
   "Screen": {
    "allOf": [
     {
      "$ref": "#/components/schemas/ScreenSummary"
     },
     {
      "type": "object",
      "properties": {
       "source": {
        "type": "string"
       },
       "captured": {
        "type": "string",
        "format": "date"
       },
       "width": {
        "type": "integer"
       },
       "height": {
        "type": "integer"
       },
       "previewUrl": {
        "type": "string"
       },
       "branch": {
        "type": "boolean"
       },
       "actions": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "label": {
           "type": "string"
          },
          "to": {
           "type": "string"
          },
          "region": {
           "type": "object",
           "description": "Hotspot position as percentages of the image.",
           "properties": {
            "x": {
             "type": "number"
            },
            "y": {
             "type": "number"
            },
            "width": {
             "type": "number"
            },
            "height": {
             "type": "number"
            }
           }
          }
         }
        }
       },
       "sections": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "title": {
           "type": "string"
          },
          "y": {
           "type": "integer"
          }
         }
        }
       }
      }
     }
    ]
   },
   "Design": {
    "type": "object",
    "properties": {
     "product": {
      "type": "string"
     },
     "summary": {
      "type": "string"
     },
     "font": {
      "type": "string"
     },
     "contexts": {
      "type": "object",
      "additionalProperties": {
       "type": "object",
       "properties": {
        "theme": {
         "type": "string"
        },
        "palette": {
         "type": "array",
         "items": {
          "type": "object"
         }
        },
        "type": {
         "type": "array",
         "items": {
          "type": "object"
         }
        },
        "layout": {
         "type": "array",
         "items": {
          "type": "string"
         }
        },
        "components": {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       }
      }
     }
    }
   },
   "PickCreated": {
    "type": "object",
    "properties": {
     "pickId": {
      "type": "string"
     },
     "url": {
      "type": "string",
      "description": "Open this for the user."
     },
     "canvasUrl": {
      "type": "string",
      "description": "Experimental pan-and-zoom canvas view of the same pick."
     },
     "status": {
      "type": "string",
      "enum": [
       "pending"
      ]
     },
     "options": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ScreenSummary"
      }
     },
     "next": {
      "type": "string",
      "description": "What to do next."
     }
    }
   },
   "PickResult": {
    "type": "object",
    "properties": {
     "pickId": {
      "type": "string"
     },
     "status": {
      "type": "string",
      "enum": [
       "pending",
       "chosen",
       "dismissed"
      ]
     },
     "message": {
      "type": "string"
     },
     "choice": {
      "$ref": "#/components/schemas/Screen"
     },
     "prompt": {
      "type": "string",
      "description": "Build prompt for the chosen reference."
     }
    }
   },
   "CheckResult": {
    "type": "object",
    "properties": {
     "report": {
      "type": "string",
      "description": "Markdown summary of the comparison."
     },
     "references": {
      "type": "array",
      "items": {
       "allOf": [
        {
         "$ref": "#/components/schemas/ScreenSummary"
        },
        {
         "type": "object",
         "properties": {
          "screenType": {
           "type": "string"
          },
          "why": {
           "type": "string"
          },
          "facts": {
           "type": "array",
           "items": {
            "type": "string"
           }
          },
          "previewUrl": {
           "type": "string"
          }
         }
        }
       ]
      }
     },
     "next": {
      "type": "string"
     }
    }
   },
   "Handoff": {
    "type": "object",
    "properties": {
     "prompt": {
      "type": "string",
      "description": "Markdown prompt to follow or paste into an agent."
     },
     "manifest": {
      "type": "object",
      "description": "Versioned reference manifest",
      "same as reference.json in the ZIP.": null
     }
    }
   }
  }
 }
}
