Submit Form API Reference
Submit form entries programmatically using the Forminit REST API.
Authentication: Optional
X-API-KEYheader. Required for protected forms and enables higher rate limits.
Endpoint
Section titled “Endpoint”POST https://forminit.com/f/{formId}
| Method | URL | Description |
|---|---|---|
POST | /f/{formId} | Create a new submission for a form |
Content Types
Section titled “Content Types”| Content Type | Use Case |
|---|---|
application/json | Recommended for API integrations |
multipart/form-data | Required for file uploads |
application/x-www-form-urlencoded | HTML native form posts |
Authentication
Section titled “Authentication”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:
- Go to Account - API Tokens in your Forminit dashboard
- Click Create Token
- Copy and securely store your token
Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
formId | string | Yes | Form identifier (e.g., YOUR-FORM-ID) |
Header Parameters
Section titled “Header Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
X-API-KEY | string | No | API key for protected forms and higher rate limits |
Content-Type | string | Yes | Request content type |
Request Body
Section titled “Request Body”JSON Format (Recommended)
Section titled “JSON Format (Recommended)”{
"blocks": [
{
"type": "sender",
"properties": {
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe"
}
},
{
"type": "text",
"name": "message",
"value": "Hello from Forminit!"
}
]
}
FormData Format
Section titled “FormData Format”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!
Block Types
Section titled “Block Types”Object Blocks
Section titled “Object Blocks”Can only appear once per submission.
| Block | Description |
|---|---|
sender | Submitter information (email, name, phone, etc.) |
tracking | UTM parameters and attribution data |
Field Blocks
Section titled “Field Blocks”Require a unique name identifier. Can have multiple instances with different names.
| Block | Value Type | Description |
|---|---|---|
text | string | Free-form text |
number | number | Numeric value |
email | string | Email address (validated) |
phone | string | Phone in E.164 format (validated) |
url | string | Valid URL (validated) |
date | string | ISO 8601 date/datetime |
rating | integer | Rating 1-5 |
select | string or string[] | Dropdown single or multi-select |
radio | string | Radio button single choice |
checkbox | string or string[] | Checkbox single or multi-choice |
file | binary | File upload (FormData only) |
country | string | ISO 3166-1 alpha-2 code |
Request Examples
Section titled “Request Examples”Basic Contact Form
Section titled “Basic Contact Form”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"
}
]
}'
With API Key
Section titled “With API Key”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"
}
}
]
}'
File Upload (FormData)
Section titled “File Upload (FormData)”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'
Complete Example
Section titled “Complete Example”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
}
]
}'
Response
Section titled “Response”Success Response (200)
Section titled “Success Response (200)”{
"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"
}
}
}
}
Response Fields
Section titled “Response Fields”| Field | Type | Description |
|---|---|---|
success | boolean | Always true on success |
redirectUrl | string | Thank you page URL |
submission.hashId | string | Unique submission identifier |
submission.date | string | Timestamp (YYYY-MM-DD HH:mm:ss) |
submission.blocks | object | All submitted field values |
submission.submissionInfo | object | IP, user agent, and location data |
Error Responses
Section titled “Error Responses”400 Bad Request
Section titled “400 Bad Request”{
"success": false,
"error": "EMPTY_SUBMISSION",
"code": 400,
"message": "At least one field with a value is required."
}
401 Unauthorized
Section titled “401 Unauthorized”{
"success": false,
"error": "MISSING_API_KEY",
"code": 401,
"message": "Missing X-API-KEY key in the header"
}
403 Forbidden
Section titled “403 Forbidden”{
"success": false,
"error": "FORM_DISABLED",
"code": 403,
"message": "This form is currently disabled."
}
404 Not Found
Section titled “404 Not Found”{
"success": false,
"error": "FORM_NOT_FOUND",
"code": 404,
"message": "This form has been deleted and is no longer available."
}
429 Too Many Requests
Section titled “429 Too Many Requests”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."
}
Common Error Codes
Section titled “Common Error Codes”| Error Code | Status | Description |
|---|---|---|
FORM_ID_REQUIRED | 400 | Form ID is missing |
EMPTY_SUBMISSION | 400 | No fields submitted |
FI_FIELD_TYPE_MISSING | 400 | Block type is missing |
FI_FIELD_NAME_MISSING | 400 | Field name is missing |
FI_FIELD_DUPLICATE_NAME | 400 | Duplicate field name |
FI_SCHEMA_FORMAT_EMAIL | 400 | Invalid email format |
FI_RULES_PHONE_INVALID | 400 | Invalid phone format |
FI_SCHEMA_RANGE_RATING | 400 | Rating not between 1-5 |
FI_DATA_COUNTRY_INVALID | 400 | Invalid country code |
MISSING_API_KEY | 401 | API key required but missing |
FORM_DISABLED | 403 | Form is disabled |
LIMIT_EXPIRED | 403 | Plan limit reached |
FORM_NOT_FOUND | 404 | Form does not exist |
UNSUPPORTED_CONTENT_TYPE | 415 | Invalid content type |
TOO_MANY_REQUESTS | 429 | Rate limit exceeded |
Rate Limits
Section titled “Rate Limits”| Authentication | Rate Limit | Counted per |
|---|---|---|
| With API Key (Protected mode) | 5 requests per second | IP address |
| Without API Key (Public mode) | 1 request per 5 seconds | IP address |
| Legacy Forms | 1 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.
Code Examples
Section titled “Code Examples”Node.js
Section titled “Node.js”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);
}
Python
Section titled “Python”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'];
}
Validation Rules
Section titled “Validation Rules”| Field | Rule |
|---|---|
sender.email | Valid email format |
sender.phone | E.164 format (+12025550123) |
sender.country | ISO 3166-1 alpha-2 code |
email block | Valid email format |
phone block | E.164 format |
url block | Valid URL format |
rating block | Integer 1-5 |
date block | ISO 8601 format |
country block | ISO 3166-1 alpha-2 code |
Limits
Section titled “Limits”| Limit | Value |
|---|---|
Maximum field blocks per submission (sender and tracking don’t count toward this limit) | 100 |
| Maximum blocks of same type | 50 |
| Maximum file blocks per submission | 20 |
| Maximum file upload size | 25 MB per submission (all files combined) |
Object blocks per type (sender, tracking) | 1 |
Related Documentation
Section titled “Related Documentation”- Form Blocks Reference - Complete block type reference
- File Uploads - File upload guide
- Get Submissions API - Retrieve submissions
- Node.js Integration - Node.js setup guide
Was this page helpful?
Thanks for your feedback.