← notes

A Farcaster frame is meta tags and a POST handler

Jan 28, 2024

Find out how small the Farcaster Frames protocol actually is by building one on plain Flask.

Very small, as it turns out. A frame is Open Graph meta tags in the head, fc:frame, fc:frame:image, fc:frame:button:N, plus an endpoint receiving a POST when a button is pressed. That is the entire surface, and the demo is a poll built from nothing else.

Two things bite immediately. The image must be an absolute URL at a fixed aspect ratio and clients cache it aggressively, so a poll showing changing results needs a distinct image URL per state rather than one URL whose content changes. People discover this by watching their poll show the same numbers forever.

The larger one is verification. Without checking the payload against a hub, anyone can POST claiming to be anyone, and the vote counts are fiction. An unverified frame is a form on the open internet with the author’s name on it. The demo does not verify; the commented-out neynar hub line is where that goes.

The framing that stuck: a frame is a state machine over stateless requests, and each response carries everything the next one needs.

Plain Flask was the right choice for learning it, because nothing was hidden.