Docs

Build with Forms.

REST API, webhooks, and embedded workflows. Everything you need to ship.

BASEhttps://forms.inversify.live/api/v1·JSON over HTTPS·Bearer keys start with frmk_
01 / AUTH

Bearer keys.

Every request carries a workspace-scoped API key in the Authorization header. Mint keys from /settings/api. Keys are shown once, then stored as SHA-256 digests — don’t lose them, rotate if you do.

curl -H "Authorization: Bearer frmk_live_3a8f..." \
     https://forms.inversify.live/api/v1/forms/frm_7x2k9p/submissions

Missing or malformed headers return 401. Keys that don’t belong to the target form’s workspace return 403.

02 / SUBMIT

Post a response.

Submit answers to a published form. Field IDs come from the form schema (visible in the builder’s “Embed” tab). Unknown fields are rejected, required fields are enforced, types are coerced.

Request
POST https://forms.inversify.live/api/v1/forms/frm_7x2k9p/submissions
Authorization: Bearer frmk_live_3a8f...
Content-Type: application/json

{
  "answers": {
    "fld_name":   "Ada Lovelace",
    "fld_email":  "ada@analytical.engine",
    "fld_rating": 9,
    "fld_notes":  "Loved the conversational flow."
  }
}
Response
HTTP/1.1 201 Created
Content-Type: application/json

{
  "id":          "res_01HX9M2KQ4",
  "formId":      "frm_7x2k9p",
  "completedAt": "2026-04-21T17:42:08.314Z"
}

On success, a response.created webhook event fans out to every subscribed endpoint for that form.

03 / WEBHOOKS

Signed events.

Configure endpoints per form under Form → Integrations. Each delivery carries an HMAC-SHA256 signature of the raw body in X-Inversify-Signature. Verify before you trust.

Event types
  • response.createdFired immediately when any response is saved (form, chat, or API).
  • response.analyzedFired after open-text answers have been themed and sentiment-scored.
Sample payload
{
  "event":    "response.created",
  "formId":   "frm_7x2k9p",
  "deliveryId": "dlv_01HX9M...",
  "timestamp": "2026-04-21T17:42:08.314Z",
  "data": {
    "id":      "res_01HX9M2KQ4",
    "answers": { "fld_name": "Ada Lovelace", "fld_rating": 9 },
    "source":  "api"
  }
}
Verify in Node
import crypto from "node:crypto";

export function verify(rawBody: string, signature: string, secret: string) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");

  // timing-safe compare
  const a = Buffer.from(expected, "hex");
  const b = Buffer.from(signature, "hex");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

// in your handler:
const raw = await req.text();
const sig = req.headers.get("x-inversify-signature") ?? "";
if (!verify(raw, sig, process.env.FORM_WEBHOOK_SECRET!)) {
  return new Response("bad signature", { status: 401 });
}

Deliveries retry with exponential backoff for up to 24 hours on any non-2xx response. Each attempt carries the same deliveryId so you can dedupe cleanly.

04 / LIMITS

Rate limits.

Quotas are per API key, per form. Exceeded requests return 429 with a Retry-After header.

EndpointLimitWindow
POST /forms/:id/submissions30060s
POST /forms (AI generate)2060s
GET /forms/:id60060s
Webhook deliveries (out)

Need higher ceilings? Team plans raise submission throughput to 2,000 / 60s by default — email hi@inversify.live.