Developer surface

Build on YeetForm.

A REST API for forms and responses, a JS SDK for embeds, signed webhooks, and an MCP server so an AI agent can create and read forms directly.

Authentication

Create an API key from Settings → API keys in the dashboard. Every /api/v1 request needs it as a bearer token. /app/settings.

curl https://yeetform.io/api/v1/me \
  -H "Authorization: Bearer yf_live_xxxxxxxxxxxxxxxx"

Endpoints

All /api/v1/* routes require the bearer token above. The /api/public/forms/{slug}/* routes are unauthenticated and CORS-enabled, they power the public renderer and the JS SDK. Files that respondents upload (the paths in response answers) are downloaded from /api/files/{fileId} and need the workspace session or the same bearer token; the same per-key rate limit applies.

GET/api/v1/me

Get the authenticated workspace

GET/api/v1/forms

List forms

  • limit (query) - Page size, clamped to 1..100.
  • cursor (query) - Opaque cursor from a previous response's `next_cursor`.
POST/api/v1/forms

Create a form

GET/api/v1/forms/{id}

Get a form

  • id (path, required)
DELETE/api/v1/forms/{id}

Archive a form

  • id (path, required)
GET/api/v1/forms/{id}/responses

List responses for a form

  • id (path, required)
  • limit (query)
  • cursor (query)
  • since (query) - Only responses submitted after this ISO timestamp.
GET/api/v1/responses/{id}

Get a single response

  • id (path, required)
GET/api/files/{fileId}

Download an uploaded file

  • fileId (path, required)
GET/api/public/forms/{slug}

Fetch a published form's schema

  • slug (path, required)
  • lang (query) - Locale override for form-content translations.
POST/api/public/forms/{slug}/responses

Submit a response

  • slug (path, required)
POST/api/public/forms/{slug}/unlock

Unlock a password-protected form

  • slug (path, required)
POST/api/public/forms/{slug}/save-progress

Save partial progress and email a resume link

  • slug (path, required)

OpenAPI

The full machine-readable spec, including request/response examples, is served as static JSON: /api/openapi.json

Webhooks

Configure a webhook per form under the form's Integrations tab. YeetForm POSTs a JSON payload to your URL on response.created (and webhook.test when you send a test event), signed with HMAC-SHA256 so you can verify it came from YeetForm.

X-YeetForm-Eventresponse.created | webhook.test
X-YeetForm-DeliveryUnique id for this delivery attempt
X-YeetForm-Signaturet=<unix ts>,v1=<hex hmac-sha256 of `${t}.${body}`>

Payload (response.created):

{
  "event": "response.created",
  "form_id": "<uuid>",
  "form_title": "Customer Feedback",
  "response_id": "<uuid>",
  "response_count": 42,
  "answers": { "fld_x": "..." },
  "fields": [{ "id": "fld_x", "label": "Your name", "type": "text" }],
  "submitted_at": "2026-09-13T12:00:00.000Z"
}

Node.js verification:

import { createHmac, timingSafeEqual } from "crypto";

function verify(secret, signatureHeader, rawBody) {
  const [tPart, v1Part] = signatureHeader.split(",");
  const timestamp = tPart.split("=")[1];
  const signature = v1Part.split("=")[1];

  const expected = createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  const a = Buffer.from(signature, "hex");
  const b = Buffer.from(expected, "hex");
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

JS SDK

One script, no build step. Add it to any page:

<script src="https://yeetform.io/sdk.js"></script>
YeetForm.render(slug, target, opts?)

Render a form inline into a container (CSS selector or element).

YeetForm.open(slug, opts?)

Open a form in a modal overlay.

YeetForm.load(slug, lang?)

Headless fetch of a form's schema, build your own UI on top.

YeetForm.submit(slug, answers)

Programmatically submit answers, keyed by field id.

YeetForm.embed(slug, target, opts?)

Inject a self-resizing iframe (?embed=true), no CORS/SDK-parity concerns since it's just the hosted renderer.

Web component:

<yeetform-embed slug="my-form-slug" lang="fr"></yeetform-embed>

MCP server

Point an MCP-compatible client (Claude Code, Claude Desktop, etc.) at YeetForm's MCP endpoint to list, create and read forms and responses, and to generate a new form from a description, all authenticated with the same API key.

claude mcp add --transport http yeetform https://yeetform.io/api/mcp \
  --header "Authorization: Bearer yf_live_xxxxxxxxxxxxxxxx"
list_formsList non-archived forms in the workspace.
get_formFetch a form plus its published and draft schemas.
create_formCreate a form from a schema, optionally publishing it.
list_responsesList responses submitted to a form.
get_responseFetch a single response by id.
generate_form_from_descriptionAI-generate a form schema from plain English (uses one AI generation).

For AI agents

Machine-readable summaries of this page, for agents that read llms.txt: