Most screenshot APIs let you script the page before capture: click: "#accept", wait_for: ".results", a blob of JavaScript. That covers a lot. It stops covering things when the screenshot you want is several clicks past the URL.
Say you want the revision history of a Wikipedia article, starting from the homepage. Step 1 is "type into the search box". Step 2 is "click the right result". The problem is step 2's DOM doesn't exist yet when you write the request. It only appears after step 1 has run in a live browser. To script the flow you'd have to run the flow first, which means keeping your own browser session open. And if you have one of those, you don't need a screenshot API.
Passing the goal in plain words
Framejet now takes a goal along with the URL:
curl -G -H "X-Api-Key: $KEY" -o shot.png \
--data-urlencode "url=https://en.wikipedia.org/" \
--data-urlencode "goal=Search for the Colosseum article, open it, then open its View history page. Stop when the revision list is visible." \
--data-urlencode "values=Colosseum" \
"https://framejet.dev/v1/take"
It walks the flow step by step and shoots when the stop condition is met. That exact request comes back as "Colosseum: Revision history" in about 16 seconds, with the site banner already stripped.
Why the navigation isn't done by an LLM
"AI navigates the page" usually means a language model reading the DOM and guessing a selector. Selector guessing is where these systems fail in the way that hurts most: the model names an element that isn't there, or clicks the wrong one and carries on.
The decisions here go to TypeSafe's Jev, a constrained-choice model. Each step, the visible controls are sent as a numbered menu, and Jev answers with one index plus a probability distribution over all of them:
- It can't answer with a selector, so it can't make one up.
- An off-menu or malformed answer is detectable, so it gets refused rather than executed.
- It's fast (roughly a second per decision) and cheap, because it's picking from a list, not writing text.
It doesn't invent the text it types
Anything typed into a field comes from the values you pass. If none of them fits the field in front of it, the capture fails instead of guessing. I didn't want a tool that puts made-up strings into someone else's form.
It fails loudly
This is the rule I'd want as a user: only a reported DONE returns an image. If the navigator reports BLOCKED, runs out of steps, or makes three moves without a page change, the API returns 422 goal_unreached and refunds the credit. A DONE judgment can still be wrong, so check important outputs.
An early version returned 200 with whatever page it ended on in four of those paths. The caller couldn't tell. Fixing that mattered more than any accuracy tweak.
When to use selectors instead (often)
If you know the page, a selector is better: deterministic, instant, free, and it reaches any node. Framejet still takes them:
actions=click:#searchInput;type:#searchInput=Colosseum;wait:1000
Visual regression testing in particular should use actions, not goal. A non-deterministic capture path turns your diffs into noise. goal is for the case a selector can't cover: an agent handed an arbitrary URL at runtime, or the same intent across many sites you don't control.
The rest
- Clean mode is on by default. Consent walls and chat widgets are removed before the capture, not cropped after. This matters more when a vision model reads the result, because a screenshot of a cookie banner tells it nothing.
-
REST and a remote MCP server share one key and one quota. The MCP tool is
screenshot(url, goal, values, actions, …), listed asdev.framejet/screenshoton the official MCP registry andframejet/screenshoton Smithery. There's nothing to install. - Limits: a single region (US East), a hard time limit of under a minute per capture, and goal mode is new, so some pages won't work. I'm genuinely interested in the ones that fail.
Have a public page that takes a few clicks to reach? Share the URL and the screen you need in a comment. I can try it with Framejet and reply with the request that worked, or the failure if it didn't.
200 screenshots a month free, no card: framejet.dev
Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.