Human-in-the-Loop
for AI Agents
Your AI agent creates a form via API — one recipient for a quick approval, or thousands for a company-wide survey. Each person gets a unique URL that you send through your own channels: email, Slack, or embedded on your site. When they respond, your agent gets structured JSON back.
The Loop
Your agent starts it. A human completes it. Your agent continues.
┌─────────────┐
│ AI Agent │ "I need human input"
└──────┬──────┘
│
1. POST /api/v1/forms
│
▼
┌───────────────┐
│ Let's Clarify │ Generates unique URLs
└──────┬────────┘
│
2. Share URL ───► email / slack / embed
│
▼
┌─────────────┐
│ Human │ Fills out form in browser
└──────┬──────┘
│
3. Submits response
│
▼
┌───────────────┐
│ Let's Clarify │ Stores structured JSON
└──────┬────────┘
│
4. Webhook / GET results
│
▼
┌─────────────┐
│ AI Agent │ Continues workflow ✓
└─────────────┘
Three Steps. Structured Data.
No SDKs, no frontend to build. Only HTTP and an API key.
Create a Form
POST your schema and context to the API. Get back a form token and unique URLs for each recipient.
Share the URL
Distribute the unique URL via email, Slack, WhatsApp — any channel. Each recipient gets their own link.
Get Structured JSON
Poll the results endpoint or receive a webhook. Every response matches your schema exactly.
See It in Action
One API call. One form. Structured JSON back.
Your AI agent is organizing the team offsite. It has already booked the venue, sent calendar invites, and arranged transport. But it doesn't know everyone's food preferences — and it can't guess those. So it creates a form via one API call, sends each person a unique link, and gets structured JSON back with exactly the data it needs to place the catering order.
Get Your API Key
curl -X POST https://letsclarify.ai/api/v1/register \
-H "Content-Type: application/json" \
-d '{ "name": "My Agent", "email": "you@example.com" }'
{
"api_key": "lc_...",
"warning": "Store securely. Shown only once."
}
No credit card. No account dashboard. Just an API key.
curl -X POST https://letsclarify.ai/api/v1/forms \
-H "Content-Type: application/json" \
-H "Authorization: Bearer lc_..." \
-d '{
"title": "Team Lunch Preferences",
"context_markdown":
"**Friday Team Lunch — March 21st**\n\nOrdering catering for **Loft 42**.\nShare your preferences by Wednesday.",
"recipient_count": 12,
"retention_days": 3,
"webhook_url": "https://your-agent.ai/hook",
"schema": [
{ "id": "name", "type": "text",
"label": "Your name", "required": true },
{ "id": "cuisine", "type": "select",
"label": "Preferred cuisine",
"required": true,
"options": [
{ "value": "italian", "label": "Italian" },
{ "value": "japanese", "label": "Japanese" },
{ "value": "mexican", "label": "Mexican" },
{ "value": "indian", "label": "Indian" }
] },
{ "id": "restrictions",
"type": "checkbox_group",
"label": "Dietary restrictions",
"options": [
{ "value": "vegetarian", "label": "Vegetarian" },
{ "value": "vegan", "label": "Vegan" },
{ "value": "gluten_free", "label": "Gluten-free" },
{ "value": "halal", "label": "Halal" }
] }
]
}'
{
"form_token": "BVyzfoQB8IqZvt1OfUI-3fM9iGg3xdTnDutienigIPk",
"delete_token": "NGgulTYu-sCtwll53a8o2hcQjwV3dVIFGr7ctfpuPOU",
"base_url_template":
"https://letsclarify.ai/f/BVyzfoQB8IqZ.../{recipient_uuid}",
"poll_url":
"https://letsclarify.ai/api/v1/forms/BVyzfoQB8IqZ.../results",
"summary_url":
"https://letsclarify.ai/api/v1/forms/BVyzfoQB8IqZ.../summary",
"delete_url":
"https://letsclarify.ai/api/v1/forms/BVyzfoQB8IqZ...",
"recipients": [
"9c95f23c-878b-441b-8e1a-5a6af2f2c35f",
"8859a8f5-e28c-465b-9972-e641db1c61dd",
"0f56c698-4088-4e0e-9c60-ed21ae26cf28",
// ...12 unique UUIDs total
]
}
Team Lunch Preferences
Friday Team Lunch — March 21st
We're ordering catering for the offsite at Loft 42. Please share your food preferences so we can place the order by Wednesday.
{
"name": "",
"cuisine": "",
"restrictions": []
}
What Your Server Receives
When a human submits, Let's Clarify POSTs structured JSON to your webhook URL.
{
"form_token": "BVyzfoQB8IqZvt1O...",
"recipient_uuid": "9c95f23c-878b-...",
"submitted_at": "2025-03-19T14:32:07Z",
"response_json": {
"name": "Alice Chen",
"cuisine": "japanese",
"restrictions": ["vegetarian"]
}
}
Retries with exponential backoff. SSRF protection via DNS validation. HTTPS required.
Supported types: text, textarea, checkbox, checkbox_group, radio, select, file
Or Embed It
Drop forms into any page. The widget handles rendering, validation, file uploads, and submission. No extra CSS needed.
<script src="https://letsclarify.ai/embed.js"></script>
<div data-letsclarify-form="{token}"
data-letsclarify-recipient="{uuid}"></div>
Two lines. That's the entire integration. Works in any HTML page, React, Vue, or plain static sites.
Install the Skill
Give your AI agent the ability to collect human input — one command.
claude install github:heisee/LetsClarify-Skill
Works with Claude Code, or any agent that supports skill files.
Everything Your Agent Needs
One API. All the capabilities. Zero frontend work.
File Uploads
Up to 10 files, 10 MB each. MIME detection via magic bytes.
Webhooks
Auto-POST on submission. Retry with backoff. SSRF-safe.
Field Validation
Regex, min/max length, required, min/max items.
Cursor Pagination
Stable cursors. Filter by status or updated_since.
Theme Colors
Custom hex color per form. Widget adapts automatically.
Markdown Context
Rich context above form fields. Headers, lists, code.
Batch Recipients
Up to 10,000 unique URLs per form. Add more via API.
Auto-Expiration
1-365 days retention. Data and files auto-delete.
Resubmission
Recipients can update. Latest submission wins.
7 Field Types
text, textarea, select, radio, checkbox, checkbox_group, file.
Embed Widget
Drop-in JS. No build step. Handles everything.
Prefilled Values
Pre-populate fields per recipient. Client-provided UUIDs supported.
Delete on Demand
Delete with token. All data permanently removed.
Works With Any Agent
Pure HTTP. No SDK required. Here's a form in three languages.
import requests
resp = requests.post(
"https://letsclarify.ai/api/v1/forms",
headers={"Authorization": f"Bearer {api_key}"},
json={
"title": "Approve budget",
"recipient_count": 1,
"schema": [{"id": "ok", "type": "radio",
"label": "Approved?",
"options": [{"value": "yes"}, {"value": "no"}]},
{"id": "limit", "type": "text",
"label": "Approved up to ($)",
"placeholder": "50000"}]
}
)
url = resp.json()["base_url_template"]
Built for AI Workflows
Whenever your agent needs a human in the loop.
Approval Workflows
Get human sign-off on AI-generated proposals, budgets, or plans before executing.
Data Collection
Collect structured information from people who don't have API access or developer tools.
Human Verification
Verify AI outputs with human judgment before committing irreversible actions.
Decision Points
Let humans choose between options your agent has generated, with full context.
Document Review
Present documents for review and collect structured feedback with ratings.
Consent & Agreement
Collect explicit consent or agreement on terms before proceeding in a workflow.
Security by Design
No tracking. Data deleted automatically.
HTTPS Only
All traffic encrypted. Webhook URLs must be HTTPS.
Auto-Deletion
All data deleted after retention period. No indefinite storage.
GDPR Compliant
Data minimization. No marketing. No profiling. No cookies.
No Tracking
No analytics. No fingerprinting. No third-party scripts.
Open. Fair. Rate-Limited.
No credit card. No subscription. Register once and go.
| Endpoint | Limit | Window |
|---|---|---|
POST /api/v1/register |
3 requests | 1 hour |
POST /api/v1/forms |
10 requests | 1 minute |
GET /api/v1/forms/* |
60 requests | 1 minute |
GET /api/v1/embed/* |
30 requests | 1 minute |
POST /api/v1/embed/* |
20 requests | 1 minute |
Rate-limited responses return HTTP 429 with Retry-After header.
Frequently Asked Questions
Ready to Close the Loop?
Get an API key and start building in under a minute.
Get Your API Key →No credit card. No dashboard. Just curl and an API key.