Crap: Conditional Resource Access Protocol

thomasfromcdnjs1 pts0 comments

CRAP: Conditional Resource Access Protocol — Lord Ajax

Skip to contentWords: human · Code: AI

HTTP can say yes and it can say no, but it can’t ask you a question.

I’ve been thinking about this because of agents. One turns up at your API, and you’d probably let it in, but there’s stuff you’d like to know first and there’s nowhere to put the question. Not “are you logged in”, we have 401 for that. Not “did you pay”, that’s 402. I mean actual questions;

What are you going to do with this?

Which model are you, and how much context have you got?

Who told you to do this, and up to what spend?

Are you keeping the output? For how long?

Will you respect a no-train flag?

Is there a human watching right now?

Which of these three licenses are you accepting?

Is this a dry run?

Right now you get two options. Return a 403, which ends the conversation and tells the agent nothing about how to fix it. Or build some bespoke onboarding form on the side of your product and pray the agent’s operator fills it out six weeks before they need anything. Neither of those is a protocol, they’re just what you do when the protocol is missing.

MCP already solved a narrow version of this. Elicitation lets a server stop mid-operation, ask for structured input against a schema (or send the user off to a URL), and then carry on. It’s good! It’s also stuck inside MCP. And everything HTTP has is single purpose; 401 for auth, 402 and x402 for money, RFC 9457 for machine-readable problems, Web Bot Auth for agent identity. Nothing that just says hold on mate, I want to ask you some things.

So I wrote one.

CRAP

Conditional Resource Access Protocol. The acronym came first and I didn’t fight it.

The status code is 430 Input Required, which is currently sitting unassigned in the IANA registry. It means;

I understand what you’re asking for and I might give it to you, but I have some questions first. Here they are. Answer them and try again.

The bit I care about is that the questions are open ended. There’s no fixed vocabulary of approved intent-declarations that a committee has to agree on before anyone can ship. The server asks whatever it wants as JSON Schema and the protocol just carries it around. A genomics archive asking about ethics approval and a ticketing API asking if you’re a scalper are the same mechanism.

How it goes

Agent asks for something, server comes back with a challenge;

"type": "https://crap.donto.org/problems/input-required",<br>"status": 430,<br>"challenge": {<br>"id": "ch_01K1XG8JX9",<br>"expires_at": "2026-08-02T00:15:00Z",<br>"scope": {<br>"method": "GET",<br>"target": "https://data.example/v1/records",<br>"request_digest": "sha-256=:n4bQgYhMfWWaLq...:"<br>},<br>"input_requests": [<br>{ "id": "purpose", "mode": "form", "required": true,<br>"message": "What is this data for?",<br>"schema": { "type": "string",<br>"enum": ["academic_research", "commercial_product", "model_training"] } },<br>{ "id": "retention", "mode": "form", "required": true,<br>"message": "How long will you keep it?",<br>"schema": { "type": "string", "enum": ["session", "P30D", "indefinite"] } },<br>{ "id": "authority", "mode": "proof", "required": true,<br>"message": "Prove someone authorised this.",<br>"accepted_proof_types": ["oauth-delegation", "user-approval"] }<br>],<br>"submission": { "method": "POST", "target": "https://data.example/v1/records" },<br>"continuation": { "mode": "retry-original-request" }

The agent POSTs answers back to the same URI, gets an Input-Proof header, then retries its original request with that header attached and gets its 200.

There are four ways to answer. form is structured data the agent can fill in itself. proof is signatures, delegations, credentials, actual evidence. approval means a human has to click something. url sends you off to do OAuth or KYC out of band. That last one exists because passwords and card numbers and tokens must never come back through form mode, since form mode means it goes through the agent’s context window and now it’s sitting in a log somewhere forever. MCP worked this out already and I’ve just copied them.

reCAPTCHA, but pointed the other way

Here’s the bit I find funny.

Think about what CAPTCHAs actually were. For about fifteen years the price of admission to a website was a small piece of unpaid cognitive labour. Squiggly words that happened to be scans of books nobody had digitised. Then house numbers, which happened to be Street View. Then buses and traffic lights and crosswalks, which happened to be exactly the labelled data you’d want if you were training self-driving cars. Billions of us, one grid of blurry motorbikes at a time, doing piecework for a trillion dollar company while sincerely believing we were proving we were human. We were! We were also the training set.

Now it’s going the other way. It’s not people asking machines for access anymore, it’s machines asking us. Every agent on the internet wants your archive, your API, your forum’s twenty years of arguments about mud crab farming. And they show up with something we...

agent protocol form mode required asking

Related Articles