Submit a form

Submit a form on a lead's behalf, exactly like a visitor would. The contact is matched by email, then phone, or created (lead source form). The submission fires the form's "form submitted" workflows, which can send messages and place AI calls that cost money, and sends the form's notification email if one is set.

POST https://api.centerfy.ai/webhooks/inbound/forms/:id/submit

Headers

HeaderRequiredValueDescription
x-api-keyYesyour sub-account API key (cfy_…)Authenticates the request; or use Authorization: Bearer <key>.
X-Webhook-SourceNomy-crmYour system’s label. A contact created here is stamped with it so outbound webhooks with the same source don’t echo the change back to you.

Path parameters

NameTypeRequiredDescription
idstring (uuid)YesThe form id.

Body parameters

NameTypeRequiredDefaultDescription
dataobjectYes—Answers keyed by field label (field ids also work). Required fields must be present and non-empty. Consent fields take true, under the field’s label or “GDPR Consent” / “A2P-10DLC Consent”.
contactobjectNo—Overrides the contact details read from the form’s typed fields.
contact.emailstringNo—Matched case-insensitively.
contact.phonestringNo—E.164, e.g. +14155550123. Other formats are ignored.
contact.namestringNo—Full name for a newly created contact.
contact.first_namestringNo—First name for a newly created contact.
contact.last_namestringNo—Last name for a newly created contact.

Request body

{
  "data": {
    "Full name": "Jane Doe",
    "Email": "[email protected]",
    "Phone": "+14155550123"
  }
}

Example

curl -X POST "https://api.centerfy.ai/webhooks/inbound/forms/{id}/submit" \
  -H "x-api-key: $CENTERFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "data": {
    "Full name": "Jane Doe",
    "Email": "[email protected]",
    "Phone": "+14155550123"
  }
}'
import { CenterfyClient } from "@centerfy/sdk";

const centerfy = new CenterfyClient({ apiKey: process.env.CENTERFY_API_KEY! });

const result = await centerfy.forms.submit("<formId>", {
  "data": {
    "Full name": "Jane Doe",
    "Email": "[email protected]",
    "Phone": "+14155550123"
  }
});
console.log(result);
centerfy forms submit <formId> '{"data":{"Full name":"Jane Doe","Email":"[email protected]","Phone":"+14155550123"}}'

MCP tool: centerfy_forms_submit (see MCP server)

Response

{
  "status": "success",
  "submission": {
    "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "form_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
    "contact_id": "3f1c2a9e-7b4d-4c8a-9e2f-1a2b3c4d5e6f",
    "data": {
      "Full name": "Jane Doe",
      "Email": "[email protected]",
      "Phone": "+14155550123"
    },
    "metadata": {
      "ip": "",
      "userAgent": "curl/8.0",
      "referrerUrl": "",
      "pageUrl": "",
      "submittedAt": "2026-10-05T15:00:00.000Z",
      "via": "public_api"
    },
    "status": "complete",
    "source": "platform",
    "created_at": "2026-10-05T15:00:00.000Z"
  },
  "contact_id": "3f1c2a9e-7b4d-4c8a-9e2f-1a2b3c4d5e6f",
  "contact_created": true,
  "notification_sent": false
}

Errors

  • 400 — if data is not an object, or with missing_fields when required fields are missing.
  • 404 — if the form is not in this sub-account.
  • 409 — if the form is not active, or is a survey (surveys can’t be submitted through this endpoint).

Notes

Returns 201. An existing contact is not updated. With no email or phone the submission is saved without a contact (contact_id null). Answers to fields linked to custom fields are saved on the contact.

© 2026 Centerfy AI. All rights reserved.