Skills rizzforms
git clone https://github.com/openclaw/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/blairanderson/rizzforms" ~/.claude/skills/clawdbot-skills-rizzforms && rm -rf "$T"
skills/blairanderson/rizzforms/SKILL.mdRizzForms — Form Backend Skill
Create forms that collect submissions and deliver them via webhook — no server code required. RizzForms handles storage, spam filtering, and delivery.
Bundled CLI
This skill includes a CLI at
scripts/rizzforms. Use it instead of writing raw
curl commands — it handles authentication, pretty-prints JSON, and has commands
for every API operation.
# Make sure it's executable chmod +x <skill-path>/scripts/rizzforms # Set the API key (or run `rizzforms config` interactively) export RIZZFORMS_API_KEY="frk_..." # Now use it <skill-path>/scripts/rizzforms forms <skill-path>/scripts/rizzforms forms:create "Contact Form"
Run
<skill-path>/scripts/rizzforms help for the full command list.
Prerequisites
You need a RizzForms API key with the admin role (prefix
frk_).
Check for an API key: Look for
RIZZFORMS_API_KEY in the environment or
~/.config/rizzforms/config.
If no API key exists:
- Sign up at https://forms.rizzness.com/signup
- Go to Account Settings > API Keys > Create API Key (select Admin role)
- Set it:
export RIZZFORMS_API_KEY="frk_..."
Important: Two Subdomains
RizzForms uses two subdomains — using the wrong one is a common mistake:
| Subdomain | Purpose |
|---|---|
| Form submissions only ( and routes) |
| API, dashboard, docs ( routes) |
HTML form
action and JSON submission URLs use forms.rizzness.com.
API management calls use www.rizzness.com.
The CLI handles this automatically.
Workflow
Step 1: Create a form
<skill-path>/scripts/rizzforms forms:create "Contact Form"
The response includes
endpoint_token, submission_url, json_url,
embed_html, and examples with ready-to-use curl commands.
Save the
endpoint_token — you need it for every subsequent step.
Step 2: Configure a webhook (optional)
If the user wants submissions delivered to an external URL:
<skill-path>/scripts/rizzforms plugins:create <endpoint_token> "https://their-server.com/webhook"
Requirements:
- URL must use HTTPS
- URL must not resolve to a private/reserved IP
- Save the
from the response — it's shown only oncesigning_secret
The webhook receives a JSON POST on each submission:
{ "id": 12345, "created_at": "2026-03-22T12:00:00Z", "form_id": "abc123", "form_name": "Contact Form", "ip": "203.0.113.42", "user_agent": "Mozilla/5.0...", "referrer": "https://yoursite.com/contact", "data": { "name": "Jane Doe", "email": "jane@example.com", "message": "Hello!" } }
Each webhook includes an
X-RizzForms-Signature header (HMAC-SHA256 of the
body using the signing secret). See references/api.md for verification
examples in Ruby, Node.js, and Python.
Step 3: Test the pipeline
<skill-path>/scripts/rizzforms test <endpoint_token>
This sends a test submission with
?test=true for synchronous delivery results.
You can also pass custom JSON:
<skill-path>/scripts/rizzforms test <endpoint_token> '{"name": "Test", "email": "test@example.com"}'
If the webhook returns non-2xx or times out, the delivery status will be
"failed" with an error message.
Step 4: Generate HTML
Use the
embed_html from the form creation response, or build a custom form.
Always include the hidden honeypot field _hp for spam protection.
<form action="https://forms.rizzness.com/f/{endpoint_token}" method="POST"> <label for="name">Name</label> <input type="text" id="name" name="name" required> <label for="email">Email</label> <input type="email" id="email" name="email" required> <label for="message">Message</label> <textarea id="message" name="message" required></textarea> <!-- Honeypot — keep hidden, critical for spam protection --> <input type="text" name="_hp" style="display:none" tabindex="-1" autocomplete="off"> <button type="submit">Send</button> </form>
RizzForms captures ALL form fields — there is no fixed schema. Add phone, company, budget, file upload, radio buttons, checkboxes — whatever is needed.
Match the user's CSS framework:
- Tailwind CSS: utility classes (
)class="block w-full rounded-md border..." - Bootstrap 5: Bootstrap classes (
,class="form-control"
)class="mb-3" - Plain CSS: semantic HTML, no framework classes
Step 5: Install in the user's project
Place the HTML form in the appropriate location in the codebase. The form
action URL points to RizzForms — no server-side code is needed.
For server-side/AJAX submissions, POST JSON to
https://forms.rizzness.com/json/{endpoint_token} instead.
Managing Existing Forms
# List all forms <skill-path>/scripts/rizzforms forms # Show form details (includes submission count, spam rate, plugin status) <skill-path>/scripts/rizzforms forms:show <token> # Update a form <skill-path>/scripts/rizzforms forms:update <token> --name "New Name" <skill-path>/scripts/rizzforms forms:update <token> --redirect "https://site.com/thanks" <skill-path>/scripts/rizzforms forms:update <token> --active false # List/manage plugins <skill-path>/scripts/rizzforms plugins <token> <skill-path>/scripts/rizzforms plugins:delete <token> <plugin_id> <skill-path>/scripts/rizzforms plugins:rotate <token> <plugin_id>
Viewing Submissions
# Recent submissions (default: last 24h) <skill-path>/scripts/rizzforms submissions # Filter by form and time range <skill-path>/scripts/rizzforms submissions --form <token> --range 7d # Search submissions <skill-path>/scripts/rizzforms submissions --search "jane@example.com" # View a specific submission <skill-path>/scripts/rizzforms submissions:show <id> # View spam <skill-path>/scripts/rizzforms spam --form <token>
Spam Prevention
RizzForms has three layers of spam protection:
- Honeypot fields — Hidden
(or_hp
) field. Bots fill it, submission gets marked as spam. Always include this in your HTML._gotcha - Turnstile CAPTCHA — Cloudflare Turnstile invisible challenge, enabled in the dashboard.
- Rate limiting — 60 submissions per minute per IP per form. Returns HTTP 429 when exceeded.
Special Fields
These field names get automatic normalization (stored in
special_normalized):
| Field | Normalization |
|---|---|
| Whitespace trimmed |
, | Whitespace trimmed |
| Auto-computed from firstName + lastName if both present |
| CSV string converted to array |
| Lowercased, validated: low/medium/high/urgent |
| Coerced to boolean |
| Coerced to boolean (marketing opt-in) |
All fields are always stored as-is in
payload_json regardless of normalization.
Error Handling
All errors return
{"ok": false, "error": "code", "message": "..."}.
| Status | Error | Meaning |
|---|---|---|
| 401 | | API key missing, invalid, or expired |
| 403 | | Key lacks required permission |
| 404 | | Form/plugin not found or wrong account |
| 404 | | Form is deactivated — reactivate with |
| 422 | | Only "webhook" type supported via API |
| 422 | | Webhook URL invalid, not HTTPS, or private IP |
| 503 | | Temporary — retry shortly |
Full API Reference
For complete endpoint details, webhook signing verification code, and framework quick-starts (Next.js, Astro, Hugo), see
references/api.md.