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}
Method URL Description
POST /f/{formId} Create a new submission for a form
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

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

Parameter Type Required Description
formId string Yes Form identifier (e.g., YOUR-FORM-ID)
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
{
  "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.

Block Description
sender Submitter information (email, name, phone, etc.)
tracking UTM parameters and attribution data

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

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"
      }
    }
  }
}
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

{
  "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 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

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.


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'];
}

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

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

View this page as Markdown