Skip to content
Development
Skill

/lanes-forms

Use when the user wants a form backend or contact form set up (a live POST endpoint that captures submissions and emails them), OR wants an agent to fill in / submit to a form on their behalf. Lanes Forms creates and manages hosted form endpoints from Claude Code. Triggers on

From plugin
app
2766 skills1 command

Claude Code

$ npx -y skills add lanes-sh/app --skill lanes-forms --agent claude-code

SKILL.md

lanes-forms.SKILL.md
name: lanes-forms
description: Use when the user wants a form backend or contact form set up (a live POST endpoint that captures submissions and emails them), OR wants an agent to fill in / submit to a form on their behalf. Lanes Forms creates and manages hosted form endpoints from Claude Code. Triggers on "set up a contact form", "provision a form", "form backend", "wire up an HTML form", "Lanes Forms", "submit this to the form", or "fill in this form".

Lanes Forms

Lanes Forms is a form backend as a service. It gives an agent two capabilities:

1. **Provision** a live form endpoint that captures submissions from the first second and delivers them (email forwarding and/or stored in the dashboard). 2. **Fill** a form on a user's behalf by POSTing a submission to a live endpoint.

The API base URL is always `https://api.lanes.sh` — use this production host for every Lanes Forms call, including when wiring a form into a site you run on `localhost`. A form's endpoint lives only on the Lanes Forms API (the form ID exists nowhere else), and `localhost` is an allowed submit origin, so the production endpoint works from local dev too. **Never** point a form at a local or app-relative API base — that is the common mistake that silently posts to the wrong host in development. (The only exception is a Lanes maintainer developing the `api/` service itself, who may target a local `http://localhost:8080` checkout; end users never should.) Every error is a JSON envelope: `{"error": {"code", "message", "docs_url"}}`, so read `error.message` when a call fails.

Fastest path: the MCP server

The `lanes` MCP server wraps every call below and is the easiest way to work. If it isn't connected yet, run **`/lanes-forms:setup-mcp`** to register it — it points at the hosted server (`https://api.lanes.sh/mcp`), authenticated with a workspace key. Its five tools are `create_form`, `get_form`, `update_form`, `generate_form_snippet`, and `submit_form`. With a workspace key configured, `create_form` provisions a form **born claimed** into that workspace, and the management tools (`get_form` / `update_form` / `generate_form_snippet`) require it. Without the MCP, call the API directly as shown below.

Provision a form

Send a `POST` to `/v1/forms`. Only `schema` is required.

POST https://api.lanes.sh/v1/forms
Authorization: Bearer lfk_...          # workspace key — see "Get a workspace key"
Content-Type: application/json

{
  "name": "Contact form",
  "recipients": ["you@company.com"],
  "allowed_origins": ["example.com"],
  "schema": [
    {"name": "email", "type": "email", "required": true},
    {"name": "message", "type": "textarea", "description": "How can we help?"}
  ]
}
  • `schema` is **required** (1–50 fields). Each entry is `{name, type, required?, max_length?, description?}`. Field types: `text`, `email`, `textarea`, `number`, `checkbox`, `hidden`. Names must be unique, 1–80 chars; `_gotcha` is reserved (the spam honeypot) and is rejected in a schema. `description?` is optional helper text (≤500 chars, trimmed; blank becomes null) shown as subtext under the question on the hosted form page and as a `<small>` hint in generated HTML snippets.
  • `name`, `allowed_origins`, and `recipients` are optional. `allowed_origins` (max 20) are the sites allowed to submit from a browser — give a hostname (`example.com`), full origin (`https://example.com`), or wildcard (`*.example.com`); `localhost` is always allowed for local testing. `recipients` (max 5) are the addresses submissions are emailed to; the **first** is the claim/owner address.

The `201` response returns `form_id`, `endpoint_url` (POST submissions here), `state`, `expires_at`, `limits`, `workflow`, `forward_email`, `store_submissions`, and `claim_url`. An anonymous create **always** returns a clickable `claim_url` to hand to the owner; when you pass `recipients` it *also* emails that same link to the first address and sets `claim_email_sent_to`. A keyed (born-claimed) create returns both as `null`. There is no per-form management secret.

**How the form is created and claimed depends on the bearer:**

  • **With a workspace API key** (`Authorization: Bearer lfk_...`) — the reliable path. The form is born **claimed** in that workspace, ready to manage immediately. No claim email and no `claim_url`; `expires_at` is null. This is what the MCP uses when a workspace key is configured.
  • **Anonymous, with `recipients`:** the response returns a single-use `claim_url` AND a claim email is sent to the first address (`claim_email_sent_to` is set) carrying the same link. The owner can click either one, sign in, and the form lands in their dashboard.
  • **Anonymous, no `recipients`:** the response returns the single-use `claim_url` (there is no address to email it to) — hand it to whoever should own the form.

> **Anonymous provisioning is gated.** An unauthenticated `POST /v1/forms` returns `503 forms_public_disabled` on deployments where public provisioning is off (its current production default). When you can't sign the request anonymously, provision with a workspace `lfk_` key. Anonymous (unclaimed) forms store up to 25 submissions and **expire 7 days** after creation unless claimed.

Calling `/v1/forms` again with an identical **anonymous** request within 24h is an idempotent replay (`200`, `idempotent_replay: true`): nothing new is created and no fresh claim link is issued, so reuse the one from the original response. Keyed creates skip idempotency — every keyed call makes a new form.

Delivery: where submissions go (workflow)

By default every form **stores** submissions in the dashboard, and if you passed `recipients` it also **emails** them there (each recipient is verified before delivery starts). For a normal contact form that's the whole setup — you don't need to send a `workflow` at all.

To change delivery, use the simple sugar **or** an explicit `workflow` array, never both (sending both returns `422 workflow_conflict`):

  • **Su
Read more
@lanes-sh
Ships withapp

Run many CLI (Coding) Agents in parallel lanes: issues, worktrees, sessions, and loops on one board. The agentic development environment.

Stars on GitHub

Momentum

stars in total
276
Star history of lanes-sh/app on GitHub, a chart by star-history.com

Other skills on app.

github-lanes-bridge

github-lanes-bridge

Use when bridging GitHub and Lanes — importing GitHub issues into Lanes for local Claude Code execution, batch-spawning sessions…

@lanes-sh@lanes-shInstall Skill
linear-lanes-bridge

linear-lanes-bridge

Use when bridging Linear and Lanes — importing Linear issues into Lanes for local Claude Code execution, batch-spawning sessions…

@lanes-sh@lanes-shInstall Skill
install-lanes-desktop

install-lanes-desktop

Use when installing, updating, or repairing the Lanes desktop app on a Mac, or when someone wants the Lanes issue board running…

@lanes-sh@lanes-shInstall Skill
lanes-sessions

lanes-sessions

Use when managing Lanes issues or driving Claude Code sessions through the lanes_* MCP tools: creating issues,…

@lanes-sh@lanes-shInstall Skill
setup-lanes-link

setup-lanes-link

Use when installing or standing up Lanes Link, the self-hostable MCP endpoint that gives an agent someone's own accounts, memory,…

@lanes-sh@lanes-shInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about lanes-forms.

Which coding agents can use lanes-forms?
lanes-forms installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.