← Changelog
Apr 28, 2026 · 2 min

One URL, two interfaces

GET pluck.one/sprint-retro
├─ Accept: text/htmlform (for humans)
└─ Accept: application/jsonschema (for AI)

Every Pluck form lives at one URL. Open it in a browser, you get HTML. Open it with an Accept: application/json header, you get JSON. Same path, same form, different shape.

Content negotiation is older than I am, sort of. The RFC is from 1996. I'm using a 1996 idea to solve a 2026 problem and I want to be honest about that — there's no novelty here in the mechanism, only in who I'm using it for.

I almost shipped two URLs because it was easier. One for the page, another under /api for the JSON. That's what most products do, and it's what most REST tutorials tell you to do. I had it built that way for about a day. I'm glad I didn't ship it.

I changed my mind for one reason: sharing has to be dead simple. When you send a form to someone, you don't know what they'll open it with. They might paste it into a Slack DM, or into Claude, or into the address bar of a tab they already had open. The link has to work in all three cases without you thinking about it. One URL is the only way that's true. Two URLs leak the architecture into the user's brain.

So I lean on HTTP content negotiation, the way it was always supposed to work. The browser sends Accept: text/html, gets a page. An agent sends Accept: application/json, gets a structured form. If neither header is informative, I default to HTML and add a <link rel="alternate" type="application/json"> tag so a polite agent can discover the JSON without guessing.

I also support a .json suffix on the URL as a fallback, because not every client gets headers right and some let you paste a URL but don't let you set headers at all. Belt and suspenders. As an aside, my own form-generation endpoint calls the Anthropic API to build a spec, and the SDK sets Accept: application/json correctly out of the box — a well-behaved client gets the right shape with no extra work. That's the point.

None of this is new. REST people have been arguing about content negotiation versus URL suffixes for fifteen years. I've read those threads. What's new isn't the mechanism — it's that there are now two consumers worth designing for. Humans were always the audience. Agents weren't, until very recently. They are now.

The interesting question stopped being "which is more correct." It became "which makes sharing easier." For Pluck, that's one URL. I don't think it's even close. If I'm missing something obvious about why this is dumb, tell me — hi@pluck.one.

— Sumit

get started

Ready to get answers worth reading?

Your first form takes 60 seconds. Respondents can fill it in a browser or hand it to their AI.

Make your first form →