Skip to content
Back to skills

Form Publishing

ASecurity

Form lifecycle management: draft, published, closed. Use when publishing forms, understanding public URLs, configuring captcha, or managing form branding.

  • 6,969 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 27, 2026
data-aigobashapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 20, 2026

npx -y skills add BuilderIO/agent-native --skill form-publishing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Form Publishing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Form Publishing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/builderio-form-publishing/badge)](https://www.skillsdirectory.com/skills/builderio-form-publishing)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: form-publishing
description: >-
  Form lifecycle management: draft, published, closed. Use when publishing
  forms, understanding public URLs, configuring captcha, or managing form
  branding.
---

# Form Publishing

## Form Lifecycle

Forms move through three statuses:

| Status      | Meaning                              | Public access |
| ----------- | ------------------------------------ | ------------- |
| `draft`     | Work in progress, not publicly available | No         |
| `published` | Live and accepting responses         | Yes           |
| `closed`    | No longer accepting responses        | Shows closed message |

## Publishing a Form

```bash
# Create as draft (default)
pnpm action create-form --title "Survey" --fields '[...]'

# Publish when ready
pnpm action update-form --id <form-id> --status published

# Close when done collecting responses
pnpm action update-form --id <form-id> --status closed
```

## Public URLs

Published forms are accessible at:

```
/f/<slug>
```

The slug is auto-generated from the title + a short unique suffix:
- Title: "Contact Form" -> Slug: `contact-form/a1b2c3`
- Full URL: `https://yourapp.com/f/contact-form/a1b2c3`

The slug updates automatically when the title changes.

## Captcha Protection

Public form submissions can be protected with Cloudflare Turnstile (opt-in). This prevents bot submissions without degrading the user experience.

## Branding

Public forms display a "Built with Agent-Native" badge by default. This can be configured in the form settings.

## Form Settings

Each form has a `settings` JSON object:

```json
{
  "submitText": "Submit",
  "successMessage": "Thank you! Your response has been recorded.",
  "redirectUrl": null,
  "completionMode": "message",
  "completionRefreshSeconds": 5,
  "showProgressBar": false,
  "emailOnNewResponses": false,
  "anonymous": false,
  "integrations": []
}
```

| Setting            | Type    | Description                                |
| ------------------ | ------- | ------------------------------------------ |
| `submitText`       | string  | Custom submit button text                  |
| `successMessage`   | string  | Message shown after successful submission  |
| `redirectUrl`      | string  | URL to redirect to after submission        |
| `completionMode`   | string  | `message`, `redirect`, `message_then_refresh`, or `refresh` |
| `completionRefreshSeconds` | number | Delay before refreshing for `message_then_refresh` (1–3600) |
| `showProgressBar`  | boolean | Show progress bar for multi-section forms  |
| `emailOnNewResponses` | boolean | Email the form owner's account when someone submits a response |
| `anonymous`        | boolean | Suppress IP, submitter identity, chat/run ids, page URL, and client-surface metadata for every response |
| `integrations`     | array   | Webhook/Slack/Discord/Google Sheets notification configs |

`emailOnNewResponses` sends through the configured email provider
(`RESEND_API_KEY` / `SENDGRID_API_KEY`). A submission still succeeds when
delivery fails, so check server logs when a notification never arrives.

For a genuinely anonymous form, set `anonymous: true` when creating the form.
Do not describe an ordinary published form as anonymous: published forms accept
public responses, but only anonymous mode suppresses identifying and source
metadata.

Unset `completionMode` keeps legacy behavior: forms with a `redirectUrl` redirect
and all other forms show the success message. A redirect with an invalid URL
falls back to the success message.

## Integration Types

Forms can notify external services on submission:

| Type            | Description                     |
| --------------- | ------------------------------- |
| `webhook`       | POST JSON to any URL            |
| `slack`         | Send to a Slack channel through an Incoming Webhook URL |
| `discord`       | Send to a Discord webhook       |
| `google-sheets` | Send response JSON to a deployed Apps Script `/exec` URL |

These are outbound form destinations configured in the form builder's
**Integrations** tab. They are separate from the managed Slack/Messaging
connection. Google Sheets Apps Script handlers should parse
`JSON.parse(e.postData.contents)`; a spreadsheet URL or `/dev` URL will not
receive submissions.

## Related Skills

- **form-building** — Creating and structuring forms
- **form-responses** — Viewing data after forms are published

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…