Skip to content

Submit Form API Reference

Submit form entries programmatically using the Forminit REST API.

Authentication: Optional X-API-KEY header. Required for protected forms and enables higher rate limits.


POST https://forminit.com/f/{formId}
MethodURLDescription
POST/f/{formId}Create a new submission for a form
Content TypeUse Case
application/jsonRecommended for API integrations
multipart/form-dataRequired for file uploads
application/x-www-form-urlencodedHTML native form posts

Include your API key in the X-API-KEY header for protected forms or higher rate limits.

X-API-KEY: sk_live_abc123xyz

To generate an API key:

  1. Go to Account - API Tokens in your Forminit dashboard
  2. Click Create Token
  3. Copy and securely store your token

ParameterTypeRequiredDescription
formIdstringYesForm identifier (e.g., YOUR-FORM-ID)
ParameterTypeRequiredDescription
X-API-KEYstringNoAPI key for protected forms and higher rate limits
Content-TypestringYesRequest content type
{
  "blocks": [
    {
      "type": "sender",
      "properties": {
        "email": "john@example.com",
        "firstName": "John",
        "lastName": "Doe"
      }
    },
    {
      "type": "text",
      "name": "message",
      "value": "Hello from Forminit!"
    }
  ]
}

Use fi-{blockType}-{property} naming for fields:

fi-sender-email: john@example.com
fi-sender-firstName: John
fi-sender-lastName: Doe
fi-text-message: Hello from Forminit!

Can only appear once per submission.

BlockDescription
senderSubmitter information (email, name, phone, etc.)
trackingUTM parameters and attribution data

Require a unique name identifier. Can have multiple instances with different names.

BlockValue TypeDescription
textstringFree-form text
numbernumberNumeric value
emailstringEmail address (validated)
phonestringPhone in E.164 format (validated)
urlstringValid URL (validated)
datestringISO 8601 date/datetime
ratingintegerRating 1-5
selectstring or string[]Dropdown single or multi-select
radiostringRadio button single choice
checkboxstring or string[]Checkbox single or multi-choice
filebinaryFile upload (FormData only)
countrystringISO 3166-1 alpha-2 code

curl -X POST 'https://forminit.com/f/YOUR-FORM-ID' \
  -H 'Content-Type: application/json' \
  -d '{
    "blocks": [
      {
        "type": "sender",
        "properties": {
          "email": "john@example.com",
          "fullName": "John Doe"
        }
      },
      {
        "type": "text",
        "name": "message",
        "value": "Hello world"
      }
    ]
  }'
curl -X POST 'https://forminit.com/f/YOUR-FORM-ID' \
  -H 'Content-Type: application/json' \
  -H 'X-API-KEY: sk_live_abc123xyz' \
  -d '{
    "blocks": [
      {
        "type": "sender",
        "properties": {
          "email": "john@example.com"
        }
      }
    ]
  }'
curl -X POST 'https://forminit.com/f/YOUR-FORM-ID' \
  -H 'X-API-KEY: sk_live_abc123xyz' \
  -F 'fi-sender-email=john@example.com' \
  -F 'fi-sender-fullName=John Doe' \
  -F 'fi-text-message=Please find my CV attached.' \
  -F 'fi-file-resume=@/path/to/resume.pdf'
curl -X POST 'https://forminit.com/f/YOUR-FORM-ID' \
  -H 'Content-Type: application/json' \
  -H 'X-API-KEY: sk_live_abc123xyz' \
  -d '{
    "blocks": [
      {
        "type": "sender",
        "properties": {
          "email": "john@example.com",
          "firstName": "John",
          "lastName": "Doe",
          "phone": "+12025550123",
          "company": "Acme Corp"
        }
      },
      {
        "type": "tracking",
        "properties": {
          "utmSource": "google",
          "utmMedium": "cpc",
          "utmCampaign": "summer_sale"
        }
      },
      {
        "type": "text",
        "name": "message",
        "value": "I would like to learn more."
      },
      {
        "type": "select",
        "name": "plan",
        "value": "Enterprise"
      },
      {
        "type": "rating",
        "name": "urgency",
        "value": 4
      }
    ]
  }'

{
  "success": true,
  "redirectUrl": "https://forminit.com/thank-you",
  "submission": {
    "hashId": "yuTRm1S6lCqIPhCH",
    "date": "2025-12-17 22:22:11",
    "blocks": {
      "sender": {
        "email": "john@example.com",
        "firstName": "John",
        "lastName": "Doe"
      },
      "message": "Hello world",
      "plan": "Enterprise"
    },
    "submissionInfo": {
      "ip": "78.163.141.101",
      "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
      "referer": "https://example.com/",
      "location": {
        "country": {
          "name": "United States",
          "iso": "US"
        },
        "city": {
          "name": "New York"
        },
        "timezone": "America/New_York"
      }
    }
  }
}
FieldTypeDescription
successbooleanAlways true on success
redirectUrlstringThank you page URL
submission.hashIdstringUnique submission identifier
submission.datestringTimestamp (YYYY-MM-DD HH:mm:ss)
submission.blocksobjectAll submitted field values
submission.submissionInfoobjectIP, user agent, and location data

{
  "success": false,
  "error": "EMPTY_SUBMISSION",
  "code": 400,
  "message": "At least one field with a value is required."
}
{
  "success": false,
  "error": "MISSING_API_KEY",
  "code": 401,
  "message": "Missing X-API-KEY key in the header"
}
{
  "success": false,
  "error": "FORM_DISABLED",
  "code": 403,
  "message": "This form is currently disabled."
}
{
  "success": false,
  "error": "FORM_NOT_FOUND",
  "code": 404,
  "message": "This form has been deleted and is no longer available."
}

Protected mode (with an API key), over 5 requests per second:

{
  "success": false,
  "error": "TOO_MANY_REQUESTS",
  "code": 429,
  "message": "Rate limit exceeded. Maximum 5 requests per second allowed.",
  "suggest": "Wait a moment before making another request."
}

Public mode (no API key), more than one submission every 5 seconds:

{
  "success": false,
  "error": "TOO_MANY_REQUESTS",
  "code": 429,
  "message": "You can send new submissions once every 5 seconds.",
  "suggest": "Wait for 5 seconds before making another request."
}

Error CodeStatusDescription
FORM_ID_REQUIRED400Form ID is missing
EMPTY_SUBMISSION400No fields submitted
FI_FIELD_TYPE_MISSING400Block type is missing
FI_FIELD_NAME_MISSING400Field name is missing
FI_FIELD_DUPLICATE_NAME400Duplicate field name
FI_SCHEMA_FORMAT_EMAIL400Invalid email format
FI_RULES_PHONE_INVALID400Invalid phone format
FI_SCHEMA_RANGE_RATING400Rating not between 1-5
FI_DATA_COUNTRY_INVALID400Invalid country code
MISSING_API_KEY401API key required but missing
FORM_DISABLED403Form is disabled
LIMIT_EXPIRED403Plan limit reached
FORM_NOT_FOUND404Form does not exist
UNSUPPORTED_CONTENT_TYPE415Invalid content type
TOO_MANY_REQUESTS429Rate limit exceeded

AuthenticationRate LimitCounted per
With API Key (Protected mode)5 requests per secondIP address
Without API Key (Public mode)1 request per 5 secondsIP address
Legacy Forms1 request per 5 seconds

Requests over the limit are rejected with HTTP 429 and the TOO_MANY_REQUESTS error code, and the submission is not stored. Wait for the interval in the error’s suggest field before sending again. See 429 Too Many Requests for the response bodies.


const response = await fetch('https://forminit.com/f/YOUR-FORM-ID', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-KEY': process.env.FORMINIT_API_KEY,
  },
  body: JSON.stringify({
    blocks: [
      {
        type: 'sender',
        properties: {
          email: 'john@example.com',
          firstName: 'John',
          lastName: 'Doe',
        },
      },
      {
        type: 'text',
        name: 'message',
        value: 'Hello world',
      },
    ],
  }),
});

const result = await response.json();

if (result.success) {
  console.log('Submission ID:', result.submission.hashId);
} else {
  console.error('Error:', result.message);
}
import requests
import os

response = requests.post(
    'https://forminit.com/f/YOUR-FORM-ID',
    headers={
        'Content-Type': 'application/json',
        'X-API-KEY': os.environ.get('FORMINIT_API_KEY'),
    },
    json={
        'blocks': [
            {
                'type': 'sender',
                'properties': {
                    'email': 'john@example.com',
                    'firstName': 'John',
                    'lastName': 'Doe',
                },
            },
            {
                'type': 'text',
                'name': 'message',
                'value': 'Hello world',
            },
        ],
    },
)

result = response.json()

if result.get('success'):
    print('Submission ID:', result['submission']['hashId'])
else:
    print('Error:', result.get('message'))
<?php

$data = [
    'blocks' => [
        [
            'type' => 'sender',
            'properties' => [
                'email' => 'john@example.com',
                'firstName' => 'John',
                'lastName' => 'Doe',
            ],
        ],
        [
            'type' => 'text',
            'name' => 'message',
            'value' => 'Hello world',
        ],
    ],
];

$ch = curl_init('https://forminit.com/f/YOUR-FORM-ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-API-KEY: ' . getenv('FORMINIT_API_KEY'),
    ],
    CURLOPT_POSTFIELDS => json_encode($data),
]);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);

if ($result['success']) {
    echo 'Submission ID: ' . $result['submission']['hashId'];
} else {
    echo 'Error: ' . $result['message'];
}

FieldRule
sender.emailValid email format
sender.phoneE.164 format (+12025550123)
sender.countryISO 3166-1 alpha-2 code
email blockValid email format
phone blockE.164 format
url blockValid URL format
rating blockInteger 1-5
date blockISO 8601 format
country blockISO 3166-1 alpha-2 code

LimitValue
Maximum field blocks per submission (sender and tracking don’t count toward this limit)100
Maximum blocks of same type50
Maximum file blocks per submission20
Maximum file upload size25 MB per submission (all files combined)
Object blocks per type (sender, tracking)1

View this page as Markdown