Agent fill: how a visitor hands your form to their own AI agent
Every public form page can show a card: "Want your AI agent to fill this?". The visitor copies one prompt. Their agent asks for missing details. It shows the answers. After a yes, it submits. Agents with tools use Path A. Plain chats use Path B.
Why two paths
Many people use Claude or ChatGPT in a plain chat. A plain chat cannot send a POST request. So Path B is a full path and not a fallback. The agent answers with a JSON block. The person pastes it into the form page. The page checks it, fills the fields and waits for the person to press Submit.
| Path A | Path B | |
|---|---|---|
| Agent needs | HTTP requests, or the fill connector | Nothing. A plain chat is enough. |
| Who submits | The agent, after the person says yes | The person, on the form page |
Response source | agent_api or agent_mcp | paste |
| Works in | Claude Code, Cursor, Claude Desktop, n8n, and Claude.ai or ChatGPT once the fill connector URL is added | Any chat that can return text |
What the person sees
- They open your form at
https://aiformapi.com/f/your-slug. - At the top is a card: Want your AI agent to fill this? They press it.
- The page asks the server for a fill token. A modal opens with four tabs.
- Copy prompt: one button that copies the full prompt.
- Agents with tools: the POST request and a curl example.
- Connector: the fill connector URL,
https://aiformapi.com/mcp/fill, with a one-line setup. - Paste your agent's answer: a box for Path B.
- They give the prompt to their agent and answer its questions.
- The agent shows all answers and asks "Send it?". Only a yes sends anything.
Nothing about the person's chat comes to us. We only see the final answers.
The exact prompt
The server fills this template when it mints the token. The same text appears in the prompt field of the response to POST /v1/public/forms/{slug}/fill-tokens.
You are helping me fill in a form. Please do it carefully.
Form: "{title}"
{description}
Sent through aiformapi.com · form id {form_id}
Questions:
1. [{field.id}] {label} — {type description}{, one of: options}{, required | optional}{, limits}
...
Rules:
- Use what you already know about me from this chat only when you are sure. Ask me for anything missing, one short question at a time.
- Never invent personal details. Leave out optional questions I skip.
- Before you submit, show me all answers and ask "Send it?". Submit only after I say yes.
How to submit (use the first option you can):
A) If you can make HTTP requests, or you have the aiformapi fill connector ({site}/mcp/fill):
POST {site}/v1/fill/{token}
Content-Type: application/json
{"answers": {<field_id>: <value>, ...}}
201 = done: tell me the receipt. 422 = fix the listed fields and send again (max 5 tries). 429 = wait Retry-After seconds.
B) Otherwise reply with ONLY this block, filled in, so I can paste it back into the form:
```json
{"form": "{form_id}", "answers": { ...every field id with an empty value... }}
```
This code expires at {expires_at} UTC.Each question line is built from the field: the id in square brackets, the label, the type in words, the options in quotes, required or optional, then limits such as max 500 characters or from 0 to 5. For a multiple-choice field the text says one or more of:. A field's help text is added at the end of its line after Note:. The expiry time is written as YYYY-MM-DD HH:MM UTC.
Here is a rendered example for a small form. In the Path B block, every field id appears with an empty value that fits its type: an empty string for text, null for numbers and ratings, [] for multiple choice and false for a checkbox.
You are helping me fill in a form. Please do it carefully.
Form: "Friday dinner RSVP"
Tell us if you can come. It takes 20 seconds.
Sent through aiformapi.com · form id frm_4k9QeV2mTc8Xa1
Questions:
1. [full_name] Your name — short text, required, max 500 characters
2. [attending] Can you come? — single choice, one of: "Yes", "No", "Maybe", required
3. [guests] How many people are you bringing? — number, optional, from 0 to 5
Rules:
- Use what you already know about me from this chat only when you are sure. Ask me for anything missing, one short question at a time.
- Never invent personal details. Leave out optional questions I skip.
- Before you submit, show me all answers and ask "Send it?". Submit only after I say yes.
How to submit (use the first option you can):
A) If you can make HTTP requests, or you have the aiformapi fill connector (https://aiformapi.com/mcp/fill):
POST https://aiformapi.com/v1/fill/fil_8Xk2mQ9vTz4LbN7cRp1WdYs5HgJf3aEu
Content-Type: application/json
{"answers": {<field_id>: <value>, ...}}
201 = done: tell me the receipt. 422 = fix the listed fields and send again (max 5 tries). 429 = wait Retry-After seconds.
B) Otherwise reply with ONLY this block, filled in, so I can paste it back into the form:
```json
{"form": "frm_4k9QeV2mTc8Xa1", "answers": {"full_name": "", "attending": "", "guests": null}}
```
This code expires at 2026-10-30 10:14 UTC.Path A: the agent has tools
The agent submits with one request:
curl -X POST https://aiformapi.com/v1/fill/fil_8Xk2mQ9vTz4LbN7cRp1WdYs5HgJf3aEu \
-H "Content-Type: application/json" \
-d '{"answers": {"full_name": "Ada Lovelace", "attending": "Yes", "guests": 1}}'201 returns a receipt:
{"response_id": "rsp_9Zt3mWq7Lx2KbN", "receipt": "AF-7K3Q-9XMD", "submitted_at": "2026-10-30T09:14:02Z"}The agent can also use the fill MCP server instead of raw HTTP. It has two tools: get_fill_form and submit_fill. Setup for Claude.ai, ChatGPT and other clients is in MCP. All status codes are in Fill API.
Path B: plain chat, paste it back
The agent replies with only a JSON block:
{
"form": "frm_4k9QeV2mTc8Xa1",
"answers": {
"full_name": "Ada Lovelace",
"attending": "Yes",
"guests": 1
}
}The person copies it and pastes it into Paste your agent's answer. The page then:
- Finds the first fenced block that holds JSON in the text, or the first top-level
{...}object. It also copes with curly quotes that some chat apps add. - Checks that
formmatches this form's id. - Checks
answerswith the same validator the API uses. - Fills the fields and highlights any problem.
- Stops. It never submits for the person. The person reads the form and presses Submit.
This is why a response from Path B has the source paste.
Token rules
| Rule | Value |
|---|---|
| Lifetime | 60 minutes |
| Successful uses | 1 |
| POST attempts | 5 at most. The next one gets 410 token_expired. |
GET /v1/fill/{token} | 30 per hour |
| Mint a token, per IP | 5 per minute and 30 per day |
| Mint a token, per form | 200 per day |
| POST, per IP | 10 per minute |
A token belongs to one form. Treat it like a secret for an hour. When it expires or is used, the person presses the card again to get a new one. Details are in Rate limits and quotas.
Turn it off
Agent fill is a form setting, and it is on by default. Set agent_fill to false:
curl -X PATCH https://aiformapi.com/v1/forms/FORM_ID \
-H "Authorization: Bearer $AIFORMAPI_KEY" \
-H "Content-Type: application/json" \
-d '{"settings": {"agent_fill": false}}'You can also use the agent fill switch on the form page in the dashboard. People can still fill the form by hand. Turn it back on the same way.
Be honest with yourself about agents
We cannot control someone else's agent. The prompt asks it to ask first, never invent details and wait for a yes. A good agent follows that. Some will not. That is why Path B never submits on its own, and why every response carries a source. See Responses.
Agent answers count toward your monthly response quota in the same way as human answers.
Related
- Fill API: status codes and examples.
- MCP: the fill connector.
- agent-fill.js: the same idea for forms on any website.
- Read why this matters on agent-fillable forms.