SKILL.md
Let's Clarify Skill
Human-in-the-Loop infrastructure. Use when your workflow needs structured human input — approvals, decisions, data collection — before proceeding.
Base URL: https://letsclarify.ai Auth: Authorization: Bearer lc_... on all API calls.
For full curl examples, detailed response payloads, MCP tool descriptions, all polling strategies, embed widget details, and advanced prefill rules, see [REFERENCE.md](./REFERENCE.md).
MCP Server (Preferred)
MCP-compatible agents should use the remote MCP endpoint instead of raw REST calls.
Endpoint: https://letsclarify.ai/mcp
Config: { "mcpServers": { "letsclarify": { "url": "https://letsclarify.ai/mcp", "headers": { "Authorization": "Bearer lc_..." } } } }
Tools: register (no auth), createform, addrecipients, getsummary, getresults, delete_form (all require auth).
REST API Reference
Register / Delete API Key
POST /api/v1/register with {"name": "...", "email": "..."} → {"apikey": "lc...", "keyprefix": "lcxxxxx"}. Store securely, shown only once.
DELETE /api/v1/register with auth header → {"deleted": true}.
Create Form
POST /api/v1/forms (auth required)
{
"title": "Approve Budget Increase",
"context_markdown": "## Q3 Budget\nPlease review the proposed 15% increase.",
"recipient_count": 3,
"retention_days": 7,
"webhook_url": "https://example.com/webhook",
"schema": [
{"id": "decision", "type": "radio", "label": "Your decision", "required": true,
"options": [{"value": "approve", "label": "Approve"}, {"value": "reject", "label": "Reject"}]},
{"id": "notes", "type": "textarea", "label": "Additional notes", "required": false}
]
}
Optional params: themecolor (hex, e.g. #1a2b3c). recipientcount accepts 1–1,000.
Response: formtoken, deletetoken, recipients (array of UUIDs), baseurltemplate, pollurl, summaryurl, delete_url.
Recipient URLs: https://letsclarify.ai/f/{formtoken}/{recipientuuid} — distribute via email, Slack, WhatsApp, etc.
Client-provided UUIDs/prefill: Instead of recipientcount, pass "recipients": [{"uuid": "...", "prefill": {"fieldid": "value"}}, {}]. UUIDs must be valid v4, prefill max 10KB. Both recipients array and recipient_count can be combined (count >= array length).
Add Recipients
POST /api/v1/forms/{form_token}/recipients with {"count": 5} or {"recipients": [...]}. Max 1,000/request, 10,000/form. Same UUID/prefill rules as creation.
Poll Summary
GET /api/v1/forms/{formtoken}/summary → {expired, knowntotal, submittedtotal, pendingtotal, updatedatmax}.
Poll Results
GET /api/v1/forms/{form_token}/results
Query params: limit, status (submitted/pending), cursor (pagination), includefiles=1 (base64), updatedsince (ISO 8601).
Response: {expired, nextcursor, servertime, results: [{recipientuuid, status, submittedat, updatedat, responsejson, files}]}.
Efficient polling: First paginate with cursor until nextcursor is null, store servertime. Then poll with updatedsince={servertime}.
Delete Form
DELETE /api/v1/forms/{formtoken} with X-Delete-Token: {deletetoken} → {"deleted": true}. Permanently removes form, submissions, and files.
Webhooks
If webhookurl (HTTPS) is set, a POST is sent per submission with {formtoken, recipientuuid, submittedat, response_json}. Retries 3× with backoff on 5xx/network errors. Non-blocking.
Waiting for Results
After creating a form and sending URLs, set up async polling. Do NOT assume immediate responses.
Recommended: Cron polling
openclaw cron add --name "poll-lc-{form_token}" --every 10m \
--message "Check Let's Clarify form {form_token}: get_summary to see if submitted_total == known_total. If all responded, get_results and summarize, then remove this cron. If expired, fetch what exists and clean up."
One-shot: openclaw cron add --name "check-lc-{formtoken}" --at +1h --delete-after-run --message "Check form {formtoken} results and report status."
Workflow: Create form → send URLs → cron polls summary → all responded or expired → fetch results → delete cron → optionally delete form.
Embed Widget
Embed forms directly in any page instead of linking to the hosted URL:
<script src="https://letsclarify.ai/embed.js"></script>
<div data-letsclarify-form="{form_token}" data-letsclarify-recipient="{recipient_uuid}"></div>
Auto-renders all field types, handles validation/submission, injects its own CSS.
Schema Field Types
| Type | Description | options required |
|---|---|---|
text |
Single-line input | No |
textarea |
Multi-line input | No |
checkbox |
Single boolean | No |
checkbox_group |
Multiple checkboxes | Yes |
radio |
Radio buttons | Yes |
select |
Dropdown | Yes |
file |
File upload | No |
Validation (optional): minlength/maxlength, pattern (regex) for text/textarea. minitems/maxitems for checkboxgroup. File config (optional): accept (MIME/extensions), maxsizemb (1-10), maxfiles (1-10).
Rate Limits
| Endpoint | Limit |
|---|---|
| Register | 5/hour |
| Create form | 10/min |
| All API / MCP | 60/min |
| Embed GET/POST | 30/20 per min |
On 429: read Retry-After header, exponential backoff (Retry-After × 2^attempt), max 5 retries.
Data Retention
Default 30 days, max 365 days. Expired forms return expired: true. Use delete endpoint for immediate cleanup.