postFormsData
Send form data to the OneEntry platform.
Description
Submits a form: the values the user entered (text, choices, files and so on) are saved as a form data record in OneEntry. Resolves to an IPostFormResponse with the created record in formData.
Quick example
A contact form with a single name field:
const response = await FormData.postFormsData({
formIdentifier: "contact_us", // form marker
formModuleConfigId: 2, // form module config ID (from the form)
moduleEntityIdentifier: "blog", // module entity the record belongs to
replayTo: null, // parent record ID (threaded replies); null for a top-level record
status: "sent", // "sent", "moderation", "approved", "banned" or "deleted"
formData: [
{
marker: "name", // field marker
type: "string", // field type
value: "John Smith" // the user's input
}
]
});
if ('statusCode' in response) {
console.error(response.message); // IError: the submission was rejected
} else {
console.log("Form data ID:", response.formData.id);
}
The examples below show how to send each field type.
Before you call it
You need three values:
formIdentifier: the form's marker (e.g."contact_us").formModuleConfigId: the ID of the form's module config, a number (e.g.2).moduleEntityIdentifier: the module entity the record belongs to (e.g."blog").
The last two are in the form's moduleFormConfigs, which Forms.getFormByMarker() returns: moduleFormConfigs[0].id and moduleFormConfigs[0].entityIdentifiers[0].id. You can also copy them from the form's settings in the admin panel of your project.
Method signature
.postFormsData(
,
);
Parameters schema
Schema (body)
body(required): IBodyPostFormData
Request body.
example:
{
"formIdentifier": "test-form",
"formModuleConfigId": 2,
"moduleEntityIdentifier": "blog",
"replayTo": null,
"status": "sent",
"formData": [
{
"marker": "name",
"type": "string",
"value": "Test"
}
]
}
body.formIdentifier(required): string
Marker of the form.
example: "form"
body.formModuleConfigId(required): number
ID of the form module configuration.
example: 2
body.moduleEntityIdentifier(required): string
Text identifier (marker) of the module entity.
example: "blog"
body.replayTo(required): number | null
Identifier of the parent form data record this one replies to (for threaded data such as comments); null for a top-level record. The platform stores it as parentId.
example: null
body.status(required): string
Status of the submitted data, for example "sent".
example: "sent"
body.formData(required): FormDataPostType[]
Form fields to submit. Submission value shapes differ from the read shapes; see FormDataPostType.
example:
[
{
"marker": "name",
"type": "string",
"value": "Jack"
}
]
body.fileQuery: IUploadingQuery
File storage parameters. Kept for compatibility: the SDK reads fileQuery from the file field itself (see IBodyTypeFile), not from the body, so setting it here does not change where the file is uploaded.
example:
{
"type": "page",
"entity": "editor",
"id": 3787
}
fileQuery.type(required): string
Storage type; determines the folder the file is stored in, for example "page".
example: "page"
fileQuery.entity(required): string
Name of the entity the file belongs to; sets the folder name in the storage.
example: "editor"
fileQuery.id(required): number
ID of the object the file belongs to; sets the folder name in the storage.
example: 3787
fileQuery.width: number
Not used by the upload and delete endpoints.
example: 0
fileQuery.height: number
Not used by the upload and delete endpoints.
example: 0
fileQuery.compress: boolean
Whether to compress (optimize) uploaded images.
example: true
langCode: string
Language code. Default: the langCode passed to defineOneEntry ("en_US" if none).
example: "en_US"
Examples
Minimal example
const body = { , , , , , { , , } ]};
const response = await FormData.postFormsData(body);
Example with "string", "integer" and "float" attributes
const body = { , , , , , { , , }, { , , }, { , , } ]};
const response = await FormData.postFormsData(body);
Example with "date", "dateTime" and "time" attributes
const body = { , , , , , { , , "fullDate": "2024-05-07T21:02:00.000Z", "formattedValue": "08-05-2024 00:02", "formatString": "DD-MM-YYYY HH:mm" } } ]};
const response = await FormData.postFormsData(body);
dateTime and time fields take the same value shape: fullDate, formattedValue and formatString.
Example with a "text" attribute (provide only one of htmlValue, plainValue or mdValue)
const body = { , , , , , { , , { "htmlValue": "<p>Hello world</p>", // "plainValue": "Hello world", // "mdValue": "Hello world", "params": { "isImageCompressed": true, "editorMode": "html" } } ] } ]};
const response = await FormData.postFormsData(body);
Example with a "textWithHeader" attribute (provide only one of htmlValue, plainValue or mdValue)
const body = { , , , , , { marker: , type: , : [ { "header": "Headline", "htmlValue": "<p>Hello World</p>", // "plainValue": "Hello world", // "mdValue": "Hello world", "params": { "isImageCompressed": true, "editorMode": "html" } } ] } ]};
const response = await FormData.postFormsData(body);
A file / image / groupOfImages value accepts any of the following, and you can mix them in one array:
- The file itself: a
File, aBlobor aFileList. The SDK uploads it first and sends the upload result. AddfileQueryto the field to choose where the file is stored; without it, the SDK uploads topage/editorunder a generated id. - A file already in storage: the object returned by FileUploading.upload(). Pass it as is. Since 1.0.171, the SDK sends it unchanged (except for
contentType, which the endpoint rejects) instead of uploading it a second time. - A hand-built value:
IFileValue(filename,downloadLink,size) orIImageValue(the same pluspreviewLinkandparams).
The endpoint has two requirements:
- The value goes in an array. A single object (a descriptor or an
IFileValue) gets400 formData's marker '…' value must be an array. A singleFileis fine, because the upload result is already an array. - An image group is
groupOfImages, plural.groupOfImagegets400 formData's marker '…' type must be one of […].
Before 1.0.171, the second option didn't work: a single descriptor threw fd.value.map is not a function inside the package, and an array of descriptors was uploaded again as if the descriptors were files, which the endpoint rejected with value[0].filename is required. On older versions, send the files themselves or a hand-built value.
Example with a file already in storage
const file = document.('input[type="file"]').files[0];const uploaded = await FileUploading.upload(file, { type: 'page', entity: 'editor', id: 3492});if ('statusCode' in uploaded) throw new Error(uploaded.message);const stored = uploaded[0];
const body = { , , , , , { , , ] } ]};
const response = await FormData.postFormsData(body);
Example with an "image" attribute
const testImageUrl = ;const filename = 'test-image.png';
const file = await FileUploading.(testImageUrl, filename);
const body = { , , , , , { marker: , type: , : [ file ] } ]};
const response = await FormData.postFormsData(body);
Example with a "groupOfImages" attribute
const testImageUrl = ;const filename = 'test-image.png';
const file = await FileUploading.(testImageUrl, filename);
const body = { , , , , , { marker: , type: , : [ file ] } ]};
const response = await FormData.postFormsData(body);
Example with a "file" attribute and a hand-built value
const body = { , , , , , { , , { "filename": "files/project/page/10/image/Screenshot-from-2024-05-02-15-23-14.png", "downloadLink": "http://my-site.com/cloud-static/files/project/page/10/image/Screenshot-from-2024-05-02-15-23-14.png", "size": 392585 } ] } ]};
const response = await FormData.postFormsData(body);
Example with a "list" attribute
const body = { , , , , , { , , , "3"] } ]};
const response = await FormData.postFormsData(body);
A submission sends the selected options as strings. The
[{ title, value }]shape that a page attribute stores is rejected here with400 formData's marker '<marker>' value[0] must be a string. Send each option'svaluefrom the field'slistTitles, not its title: an unknown value gets400 wrong values for type list.
For a radioButton field, send a single string or integer, not an array:
{ marker: 'size', type: 'radioButton', value: '2' }. Use the chosen option's value.
Example with a "spam" attribute (captcha)
The platform generates Google reCAPTCHA v3 keys: there's no checkbox and no picture puzzle. The visitor isn't asked anything. The token is obtained in the browser when the form is submitted, and the score is evaluated on the server.
Read the site key from the form itself. A spam field carries it in
settings.captcha.key, next to domainNames (the domain the key was issued
for). Get it from getFormByMarker instead of
hard-coding it. Note that a key issued for localhost won't pass on a
production domain.
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY"></script>
const form = await Forms.('contact_us');if ('statusCode' in form) throw new Error(form.message);const spamField = form.attributes.find((a) => a.type === 'spam');if (!spamField) throw new Error('The form has no spam field');const siteKey = spamField.settings.captcha.key;
const token = await window..execute(siteKey, { action: 'submit' });
const body = { "formIdentifier": "contact_us", "formModuleConfigId": 2, "moduleEntityIdentifier": "blog", "replayTo": null, "status": "sent", "formData": [ { "marker": "your_name", "type": "string", "value": "John Smith" }, { , , , "siteKey": siteKey } } } ]};
const response = await FormData.postFormsData(body);
The value is the event object, not the token string. A bare token, an empty value and a wrong shape all get the same response,
400 Captcha Validation Failed, captcha type is: google, so a malformed request looks exactly like a bot. Check the shape before blaming the score.
If the form has a spam field configured but you don't send it, the request is rejected with
400 formData doesn't have spam attribute.
Example with an "entity" attribute (nested list)
const body = { , , , , , { , , , 32, 24] } ]};
const response = await FormData.postFormsData(body);
The value holds numeric IDs for pages and string IDs for products. A product ID has the form p-[parentId]-[productId], for example p-1-2954.
Example with a "timeInterval" attribute
const body = { , , , , , { marker: , type: , : [ [ "2025-02-11T16:00:00.000Z", "2025-02-13T16:00:00.000Z" ] ] }, ]};
const response = await FormData.postFormsData(body);
The value is an array of [start, end] pairs in ISO 8601 UTC format, for example 2025-02-11T16:00:00.000Z.
Example response
{
"formData": {
"formIdentifier": "test-form",
"time": "2026-10-27T09:14:47.131Z",
"formData": [
{
"marker": "name",
"type": "string",
"value": "Test"
}
],
"userIdentifier": "john@example.com",
"entityIdentifier": "blog",
"fingerprint": "UQ_b7d3e8d8-0077-4802-ae5c-fea72f9254e9",
"isUserAdmin": false,
"formModuleId": 2,
"parentId": null,
"id": 9242
},
"actionMessage": ""
}
Response schema
Schema: IPostFormResponse
formData: object
The created form data record.
example:
{
"id": 42,
"formIdentifier": "contact_form",
"time": "2023-10-01T12:00:00Z",
"entityIdentifier": "blog",
"isUserAdmin": false,
"formModuleId": 2,
"parentId": null,
"userIdentifier": null,
"formData": [
{
"marker": "name",
"type": "string",
"value": "Jack"
}
]
}
formData.id: number
ID of the form data record.
example: 12345
formData.formIdentifier: string
Marker of the form.
example: "contact_form"
formData.time: string
Date and time of the submission.
example: "2023-10-01T12:00:00Z"
formData.entityIdentifier: string
Identifier of the entity.
example: "blog"
formData.isUserAdmin: boolean
Whether the record was submitted by an admin.
example: false
formData.formModuleId: number
ID of the form module.
example: 2
formData.userIdentifier: string | null
Identifier (login) of the user who submitted the form.
example: null
formData.parentId: number | null
ID of the parent record.
example: null
formData.formData: FormDataType[]
Form fields.
example:
[
{
"marker": "name",
"type": "string",
"value": "Jack"
}
]
actionMessage: string
Message shown after the form is submitted; can be localized.
example: "Form submitted successfully"
Usage examples
Step-by-step walkthroughs in the documentation:
- Submit a form — collect contact form input and post it back to OneEntry.
- Entity form — submit a form with entity-type fields (pages or products).
Try it live
Run this method interactively in the JS SDK sandbox. Connect your Project URL and App Token on your first visit, then open any scenario below to see real form submissions:
- Submit a form — collect contact form input and post it back to OneEntry.
- Entity form — submit a form with entity-type fields (pages or products).
- File form — submit a form that includes a file attachment.
- Spam form — submit a form with spam protection.
- Schedule form — submit a selected time slot via a
timeIntervalfield.