Form infrastructure for agentic software

Headless forms
AI agents can ship
in 30 seconds.

No database. No UI to build. Define a schema in JSON, publish from the CLI, and your agent has a live form — hosted, validated, with signed webhooks back to your runtime.

No database setup No frontend to build One CLI command to publish

MIT · Cloudflare Workers · Sub-50ms cold starts

terminal — 30 seconds to a live form
$ agentsforms init
✓ Created forms/onboarding.json

$ agentsforms forms publish onboarding
✓ Published → forms.agentsforms.com/f/onboarding

# Agent creates a session, embeds the form
$ agentsforms sessions create onboarding \
--metadata '{"agent_run_id":"run_123"}'
✓ Session → forms.agentsforms.com/s/sess_abc

# Human fills it. Signed webhook fires.
← POST /your-agent/webhook
X-AgentsForms-Signature: t=1782..., v1=a3f2...
{ event: "submission.completed", answers: {...} }

API-first. Or drop in an iframe. Or send a link.

Your agent owns the form. Call the API to render fields, validate, and submit — full control over every pixel. Or use the hosted iframe for a zero-code embed. Same schema, same signed webhook at the other end.

Primary

Headless API

Your agent renders form fields directly in the page it's building. API calls handle sessions, validation, and submission — your agent owns the HTML and CSS. The form looks native to the site because it is native to the site.

1 Agent fetches the form schema
GET /v1/forms/onboarding/agent-schema returns the field definitions. Your agent reads the JSON and renders <input> and <select> elements directly into the page it's building. Native HTML, your CSS, your layout.
2 Agent creates a session, renders the form
POST /v1/forms/onboarding/sessions creates the session. Your agent renders the fields, wires up validation, and the user fills them inline — on your site, in your design system.
3 Agent submits via API, gets the result
POST /v1/sessions/:id/submit sends the answers. Validation runs server-side. Your agent gets the result directly or waits for the signed webhook. Submissions flow wherever you route them.
// Agent-built onboarding page const schema = await fetch('/v1/forms/onboarding/agent-schema') const session = await fetch('/v1/forms/onboarding/sessions', {method: 'POST'}) // Agent renders native fields from schema schema.fields.forEach(f => renderField(f)) // User fills them, agent submits await fetch(`/v1/sessions/${session.id}/submit`, { method: 'POST', body: JSON.stringify({ answers }) }) // Webhook fires → agent resumes
Also

iframe embed

One <iframe> tag and the form is live. No API calls, no rendering logic. The hosted form handles everything — validation, submit, success state. Fastest path to a working form.

1 Publish from the CLI
agentsforms initagentsforms forms publish onboarding. You get a hosted URL and an embed snippet. No database, no server.
2 Drop it into any page
Your agent pastes <iframe src="forms.agentsforms.com/f/onboarding"> into the site. The form renders inline with built-in validation. Users never leave the page.
3 Submissions go where you want
Signed webhook to your agent. API polling. CSV export. Forward to email. No lock-in — route submissions to whatever destination you need.
<!-- Agent-built support portal --> <h1>Support</h1> <iframe src="forms.agentsforms.com/f/support-intake" ></iframe> <!-- Form is live. Zero code. --> <!-- Submissions → webhook / API / email -->
Also

Send as a link

When your agent is mid-conversation and needs a quick answer — approval, clarification, missing field — fire a hosted form URL. One click for the human, structured data back.

1 Agent detects missing info
Mid-task, your agent realizes it needs approval or clarification. It calls POST /v1/forms/approval/sessions and gets back a hosted URL.
2 Agent sends the link
The agent drops the URL into chat, Slack, email — wherever the human is. "Hey, approve this deploy before I proceed: forms.agentsforms.com/s/sess_abc"
3 Human clicks, fills, done
One click opens the form. No login, no account. The human fills it, submits, and your agent's webhook fires. Agent resumes with the decision.
# Agent mid-conversation Agent: Before I deploy, approve these changes: forms.agentsforms.com/s/sess_abc Human: [clicks, checks boxes, submits] → webhook fires → agent deploys

What you get. What you don't have to build.

{ } schema.json

Schema-first

One JSON file is the contract. Fields, types, validation rules, agent hints. Same schema drives CLI, API, SDK, and the hosted renderer. No drift, no duplication.

{ "type": "select", "options": [...] }
↗ POST /sessions

Headless by default

Every form gets a hosted URL and an embed snippet. But the real surface is the API — your agent creates sessions and reads submissions without ever touching HTML.

POST /v1/forms/:id/sessions
🔏 HMAC-SHA256

Signed, not hopeful

Every webhook is cryptographically signed, timestamped, and idempotent. Retried with exponential backoff. Your agent resumes on data it can actually verify.

X-AgentsForms-Signature: t=…, v1=…

Same shape end-to-end. Define, submit, resume.

You define the schema. The human fills the form. The agent gets structured data. One contract, three surfaces.

01You define
support-intake.json { "name": "Support intake", "slug": "support-intake", "fields": [ { "id": "priority", "type": "select", "options": [ { "label": "High", "value": "high" }, { "label": "Normal", "value": "normal" } ] }, { "id": "message", "type": "textarea" } ] }
02Human submits
{ "submissionId": "sub_01J9X3...", "formId": "form_abc123", "status": "complete", "answers": { "priority": "high", "message": "Agent stuck on refund policy edge case." } }
03Agent resumes
POST /your-agent/webhook Content-Type: application/json X-AgentsForms-Signature: t=1782223332, v1=a3f2b9c1... { "event": "submission.completed", "data": { "submissionId": "sub_01J9X3...", "answers": { "priority": "high" } } }

Six commands. No database. Live in 30 seconds.

terminal
$ npm install -g @agentsforms/cli
$ agentsforms login
$ agentsforms init
✓ Created forms/onboarding.json
$ agentsforms forms publish onboarding
✓ Published → forms.agentsforms.com/f/onboarding

# Your agent now has a live form. Embed it or send the link.
$ agentsforms sessions create onboarding \
--metadata '{"agent_run_id":"run_123"}'
✓ Session → forms.agentsforms.com/s/sess_abc

$ agentsforms submissions tail onboarding
Waiting for submissions…

Prefer raw HTTP? API reference →