---
title: "Create a hosted form and get its public link via MPP"
method: POST
path: "/v1/mpp/forms"
tags: ["Forms"]
---

# Create a hosted form and get its public link via MPP

`POST /v1/mpp/forms`

## Request

- Base URL: `https://api.munition.io`
- URL: `https://api.munition.io/v1/mpp/forms`
- Auth: none required

Create a hosted web form that people fill in from any browser without an account, then read their answers as JSON. Costs 0.010 USDC per form. A form stays open up to 30 days (closesAt), closes after 100 responses, and its answers stay readable 7 days after closesAt. Up to 20 questions of six types: text, long_text, email, number, choice, multi_choice. Forms that ask for passwords, codes or bank details are rejected, and every form shows an AI-agent warning banner. Direct x402 and MPP calls return a secret readToken for GET /v1/forms/{id}/responses. Paid over MPP: 0.01 USDC on Base/Polygon/Arbitrum with a stablecoin-only charge authorization sent in Authorization: Payment.

## Headers

- `Idempotency-Key` string

## Request body

- FormCreateInput
  - `title` string, required: Form title shown to people.
  - `description` string: Optional intro under the title. Plain text: newlines are kept, links are not clickable.
  - `fields` object[], required: 1 to 20 questions, shown in order.
    - `id` string, required: Stable key used in answers, unique within the form.
    - `label` string, required: Question text shown to people.
    - `type` 'text' | 'long_text' | 'email' | 'number' | 'choice' | 'multi_choice', required: text (up to 2000 characters), long_text (up to 5000), email, number, choice (exactly one option) or multi_choice (any number of options).
    - `required` boolean
    - `options` string[]: Required for choice and multi_choice, not allowed otherwise. Unique, ignoring case.
  - `closesAt` string, date-time: When the form stops accepting answers, with a timezone: between 5 minutes and 30 days from now. Default: 30 days.
  - `successMessage` string: Optional message shown after an answer is sent.

## Response `200`

Form created

- FormCreateOutput
  - `formId` string, required
  - `publicUrl` string, uri, required: Share this link; people answer without an account.
  - `closesAt` string, date-time, required
  - `maxResponses` integer, required
  - `responsesReadableUntil` string, date-time, required
  - `readToken` string: Direct x402 and MPP only. Secret bearer token for GET /v1/forms/{id}/responses and POST /v1/forms/{id}/close. Returned again only on an identical replay that carries the same Idempotency-Key header.

## Other responses

- `400`: form_invalid or form_forbidden_content; nothing was charged
- `402`: Call without Authorization to receive an MPP challenge, then retry with Authorization: Payment <credential>. Invalid payment and settlement failures can also return 402.
- `409`: Idempotency conflict
- `503`: form_effect_pending: paid, form not opened yet; retry the identical request to finish without a second charge. form_settlement_unknown: do not pay again.

---

[API](https://skmtc.dev/munition/apis/munition-api.md) · [All operations](https://skmtc.dev/munition/apis/munition-api/llms.txt) · [OpenAPI document](https://skmtc.dev/munition/apis/munition-api/revisions/3b11109809d1?raw)
