{"openapi":"3.1.0","info":{"title":"Munition API — forms","version":"0.0.16","description":"Munition provides pay-per-call file sharing, HTML to PDF conversion, web search, page content extraction and flight data for AI agents. Upload a report or image and share its public download link; turn self-contained HTML into an A4 PDF; search and read web sources with Exa, Firecrawl and Serper. Direct HTTP services use USDC payments. The local @munition/mcp adapter (0.0.15+) supports files, flights, web research and HTML to PDF.","x-guidance":"Munition provides USDC-paid x402/MPP services and free public tools for AI agents. Pay-per-call routes settle in stablecoin USDC via x402 on Base/Polygon/Arbitrum/Solana, or MPP on Base/Polygon/Arbitrum (Solana is x402 only); no API key or signup is required for direct x402 routes. Fetch /llms.txt for the full agent guide.\n\n## Which route to call\n- Web search: POST /v1/exa/search (0.01 USDC, neural, best for research questions and finding sources; add contents.text to get page text in the same call). For Google-style results with snippets use POST /v1/serper/search (0.004 USDC).\n- Read a page: POST /v1/firecrawl/scrape (0.015 USDC, renders JavaScript, returns markdown; use when a plain fetch returns empty, JS-only or 403). For many URLs cheaply use POST /v1/exa/contents (0.002 USDC for up to 20 URLs from Exa's cache).\n- Direct answer with citations: POST /v1/exa/answer (0.01 USDC).\n- Related pages / competitors of a URL: POST /v1/exa/find-similar (0.01 USDC).\n- News, images, products: POST /v1/serper/news, /v1/serper/images, /v1/serper/shopping (0.004 USDC each; country gl and language hl selectable).\n- Search + full content of each result in one call: POST /v1/firecrawl/search (0.03 USDC).\n- Deliver a file to a human: POST /v1/render/pdf (0.02 USDC, self-contained HTML → PDF link) or POST /v1/uploads (0.005 USDC, presigned upload slot → public link, 7 days).\n- Ask people questions: POST /v1/forms (0.01 USDC) returns a hosted form link and a readToken; read answers free with GET /v1/forms/{id}/responses (Authorization: Bearer <readToken>).\n- Travel: POST /v1/flights/search (0.05 USDC), GET /v1/flights/offers/{id} (0.01 USDC), POST /v1/airports/search (0.001 USDC).\n- External flight search links: POST /v1/tools/flight-booking-links (free, no authentication or payment). Pass origin, destination, departureDate and optional returnDate to receive KAYAK and Kiwi.com search URLs. These start new searches and do not reserve a flight or guarantee a fare.\n\n## Calling convention for paid routes\n1. POST with a JSON body and no payment header → 402 with PAYMENT-REQUIRED (accepts[] with exact atomic amounts) and the Bazaar input/output schema.\n2. Sign and retry with PAYMENT-SIGNATURE. Send Idempotency-Key: replays return the stored result without a second charge.\n3. 400 = input rejected before any payment. 422/502 after payment = upstream provider failed; the response carries paidCallId for reconciliation, do not pay again blindly.\nMPP alternative: every web search/scrape/Google route above also exists under /v1/mpp/ (e.g. POST /v1/mpp/exa/search, same price and body); call without Authorization to get the WWW-Authenticate Payment challenge, then retry with Authorization: Payment.\nAll paid-route prices are fixed per call and listed at /v1/tools/prices. The free flight-booking-links route accepts JSON directly and returns 200 on success or 400 for invalid input; no payment headers or Idempotency-Key are required.","contact":{"name":"Munition","email":"hello@munition.io","url":"https://munition.io"}},"x-agentcash-guidance":{"llmsTxtUrl":"https://api.munition.io/llms.txt","agentOpenApiUrl":"https://api.munition.io/openapi.json","fullOpenApiUrl":"https://api.munition.io/openapi-full.json"},"x-agentcash-provenance":{"ownershipProofs":["https://munition.io","https://api.munition.io/openapi.json","https://api.munition.io/.well-known/x402.json","https://api.munition.io/.well-known/mpp.json"]},"servers":[{"url":"https://api.munition.io"}],"tags":[{"name":"Forms"}],"paths":{"/v1/forms":{"post":{"tags":["Forms"],"summary":"Create a hosted form and get its public link via x402","description":"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. Call without payment for the canonical 402 challenge, then retry with the x402 payment signature. Unsigned requests are not validated; signed requests are validated before verification and settlement, so an invalid form is never charged.","security":[],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.01"},"protocols":[{"x402":{}}]},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Optional retry key; it must be a random, secret value such as a UUID. If omitted, the server derives it from the payment envelope. Reuse the same request, envelope and key on retries. Send one to be able to recover readToken on retry."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCreateInput"}}}},"responses":{"200":{"description":"Form created. readToken is returned again only on an identical replay that carries the same Idempotency-Key header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCreateOutput"}}}},"400":{"description":"form_invalid or form_forbidden_content; nothing was charged"},"402":{"description":"x402 payment required or settlement failed"},"409":{"description":"Idempotency conflict, or an earlier attempt needs manual reconciliation"},"503":{"description":"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."}}}},"/v1/mpp/forms":{"post":{"tags":["Forms"],"summary":"Create a hosted form and get its public link via MPP","description":"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.","security":[],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.01"},"protocols":[{"mpp":{"method":"evm","intent":"charge","currency":"USD"}}]},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Optional retry key; it must be a random, secret value such as a UUID. If omitted, the server derives it from the Payment credential. Reuse the same request, credential and key on retries. Send one to be able to recover readToken on retry."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCreateInput"}}}},"responses":{"200":{"headers":{"Payment-Receipt":{"description":"Encoded MPP settlement receipt. Cached idempotent replays or completed-effect recovery may omit this header.","schema":{"type":"string"}}},"description":"Form created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCreateOutput"}}}},"400":{"description":"form_invalid or form_forbidden_content; nothing was charged"},"402":{"description":"Call without Authorization to receive an MPP challenge, then retry with Authorization: Payment <credential>. Invalid payment and settlement failures can also return 402.","headers":{"WWW-Authenticate":{"description":"MPP Payment challenge for a stablecoin-only USDC charge. Returned on the unpaid challenge response.","schema":{"type":"string"}}}},"409":{"description":"Idempotency conflict"},"503":{"description":"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."}}}},"/v1/forms/{id}/responses":{"get":{"tags":["Forms"],"summary":"Read a form's answers with its read token","description":"Free. Send Authorization: Bearer <readToken> from the create response. Returns the form state and its answers, oldest first; page with nextCursor. Unknown forms and wrong tokens both return 404.","security":[{"formReadToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^frm_[A-Za-z0-9_-]{22}$"}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string","maxLength":400}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Form state and answers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormResponsesOutput"}}}},"401":{"description":"Missing or malformed read token"},"404":{"description":"Form not found"}}}},"/v1/forms/{id}/close":{"post":{"tags":["Forms"],"summary":"Stop a form from accepting answers","description":"Free and idempotent. Send Authorization: Bearer <readToken>. Answers stay readable until responsesReadableUntil.","security":[{"formReadToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^frm_[A-Za-z0-9_-]{22}$"}}],"responses":{"200":{"description":"Form state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCloseOutput"}}}},"401":{"description":"Missing or malformed read token"},"404":{"description":"Form not found"}}}},"/v1/tools/forms":{"post":{"tags":["Forms"],"operationId":"create_form","summary":"Create a hosted form with account-funded payment","description":"Account-funded Munition Forms, used by the create_form MCP tool. Requires a Munition account bearer token and Idempotency-Key, and settles 0.01 USDC from the account wallet. No readToken: read answers with GET /v1/tools/forms/{id}/responses. A 503 form_effect_pending after settlement carries paidCallId; retry with the same Idempotency-Key and body to finish without a second charge.","security":[{"accountBearer":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Stable idempotency key for paid or state-changing operations."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCreateInput"}}}},"responses":{"200":{"description":"Form created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCreateOutput"}}}},"400":{"description":"form_invalid or form_forbidden_content; nothing was charged"},"401":{"description":"Missing or invalid account token"},"409":{"description":"Idempotency conflict"},"503":{"description":"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."}}}},"/v1/tools/forms/{id}/responses":{"get":{"tags":["Forms"],"operationId":"form_responses","summary":"Read a form's answers from the creating account","description":"Free. Same output as GET /v1/forms/{id}/responses, authorized by the account that created the form.","security":[{"accountBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^frm_[A-Za-z0-9_-]{22}$"}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string","maxLength":400}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Form state and answers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormResponsesOutput"}}}},"401":{"description":"Missing or invalid account token"},"404":{"description":"Form not found"}}}},"/v1/tools/forms/{id}/close":{"post":{"tags":["Forms"],"operationId":"close_form","summary":"Stop a form from accepting answers (creating account)","description":"Free and idempotent. Answers stay readable until responsesReadableUntil.","security":[{"accountBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^frm_[A-Za-z0-9_-]{22}$"}}],"responses":{"200":{"description":"Form state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCloseOutput"}}}},"401":{"description":"Missing or invalid account token"},"404":{"description":"Form not found"}}}}},"components":{"securitySchemes":{"accountBearer":{"type":"http","scheme":"bearer","description":"Anonymous Munition account token created by /v1/accounts/bootstrap."},"formReadToken":{"type":"http","scheme":"bearer","description":"Per-form read token (frt_…) returned by POST /v1/forms and POST /v1/mpp/forms."}},"schemas":{"FormCreateInput":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":120,"description":"Form title shown to people."},"description":{"type":"string","maxLength":1000,"description":"Optional intro under the title. Plain text: newlines are kept, links are not clickable."},"fields":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","description":"Stable key used in answers, unique within the form."},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Question text shown to people."},"type":{"type":"string","enum":["text","long_text","email","number","choice","multi_choice"],"description":"text (up to 2000 characters), long_text (up to 5000), email, number, choice (exactly one option) or multi_choice (any number of options)."},"required":{"type":"boolean","default":false},"options":{"type":"array","minItems":2,"maxItems":20,"items":{"type":"string","minLength":1,"maxLength":100},"description":"Required for choice and multi_choice, not allowed otherwise. Unique, ignoring case."}},"required":["id","label","type"],"additionalProperties":false},"description":"1 to 20 questions, shown in order."},"closesAt":{"type":"string","format":"date-time","description":"When the form stops accepting answers, with a timezone: between 5 minutes and 30 days from now. Default: 30 days."},"successMessage":{"type":"string","maxLength":300,"description":"Optional message shown after an answer is sent."}},"required":["title","fields"],"additionalProperties":false},"FormCreateOutput":{"type":"object","properties":{"formId":{"type":"string"},"publicUrl":{"type":"string","format":"uri","description":"Share this link; people answer without an account."},"closesAt":{"type":"string","format":"date-time"},"maxResponses":{"type":"integer"},"responsesReadableUntil":{"type":"string","format":"date-time"},"readToken":{"type":"string","description":"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."}},"required":["formId","publicUrl","closesAt","maxResponses","responsesReadableUntil"],"additionalProperties":false},"FormResponsesOutput":{"type":"object","properties":{"form":{"type":"object","properties":{"formId":{"type":"string"},"publicUrl":{"type":"string","format":"uri"},"title":{"type":"string"},"description":{"type":["string","null"]},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","description":"Stable key used in answers, unique within the form."},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Question text shown to people."},"type":{"type":"string","enum":["text","long_text","email","number","choice","multi_choice"],"description":"text (up to 2000 characters), long_text (up to 5000), email, number, choice (exactly one option) or multi_choice (any number of options)."},"required":{"type":"boolean","default":false},"options":{"type":"array","minItems":2,"maxItems":20,"items":{"type":"string","minLength":1,"maxLength":100},"description":"Required for choice and multi_choice, not allowed otherwise. Unique, ignoring case."}},"required":["id","label","type"],"additionalProperties":false}},"status":{"type":"string","enum":["open","closed","suspended"]},"closeReason":{"type":["string","null"],"enum":["expired","full","creator","reports",null]},"closesAt":{"type":"string","format":"date-time"},"responseCount":{"type":"integer"},"maxResponses":{"type":"integer"},"responsesReadableUntil":{"type":"string","format":"date-time"}},"required":["formId","publicUrl","title","description","fields","status","closeReason","closesAt","responseCount","maxResponses","responsesReadableUntil"],"additionalProperties":false},"responses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"},"answers":{"type":"object","description":"One key per field id. Empty optional fields are null, multi_choice answers are arrays (empty optional multi_choice answers are []), number answers are numbers.","additionalProperties":{"type":["string","number","array","null"],"items":{"type":"string"}}}},"required":["id","submittedAt","answers"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["form","responses","nextCursor"],"additionalProperties":false},"FormCloseOutput":{"type":"object","properties":{"form":{"type":"object","properties":{"formId":{"type":"string"},"publicUrl":{"type":"string","format":"uri"},"title":{"type":"string"},"description":{"type":["string","null"]},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","description":"Stable key used in answers, unique within the form."},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Question text shown to people."},"type":{"type":"string","enum":["text","long_text","email","number","choice","multi_choice"],"description":"text (up to 2000 characters), long_text (up to 5000), email, number, choice (exactly one option) or multi_choice (any number of options)."},"required":{"type":"boolean","default":false},"options":{"type":"array","minItems":2,"maxItems":20,"items":{"type":"string","minLength":1,"maxLength":100},"description":"Required for choice and multi_choice, not allowed otherwise. Unique, ignoring case."}},"required":["id","label","type"],"additionalProperties":false}},"status":{"type":"string","enum":["open","closed","suspended"]},"closeReason":{"type":["string","null"],"enum":["expired","full","creator","reports",null]},"closesAt":{"type":"string","format":"date-time"},"responseCount":{"type":"integer"},"maxResponses":{"type":"integer"},"responsesReadableUntil":{"type":"string","format":"date-time"}},"required":["formId","publicUrl","title","description","fields","status","closeReason","closesAt","responseCount","maxResponses","responsesReadableUntil"],"additionalProperties":false}},"required":["form"],"additionalProperties":false}}}}