You are viewing beta documentation for Formie 4.x.
GraphQL

Create Submissions

Formie creates a form-specific GraphQL mutation for each form. The mutation name follows this pattern:

save_<formHandle>_Submission

For a form with the handle contactForm, the mutation is save_contactForm_Submission.

Basic Submission

Field handles become mutation arguments. This example assumes the form has a Single-Line Text field with the handle yourName.

mutation SaveSubmission($yourName: String) {
    save_contactForm_Submission(yourName: $yourName) {
        title

        ... on contactForm_Submission {
            yourName
        }
    }
}
{
    "yourName": "Peter Sherman"
}

The response returns the saved submission.

{
    "data": {
        "save_contactForm_Submission": {
            "title": "2026-04-10 10:29:06",
            "yourName": "Peter Sherman"
        }
    }
}

Mutation Arguments

Each form-specific mutation accepts Craft’s standard element mutation arguments, Formie’s submission arguments, the form’s field handles, and any enabled captcha arguments.

ArgumentTypeDescription
idIDSet this when updating an existing submission.
uidStringSet the submission UID.
enabledBooleanWhether the submission should be enabled.
titleStringSet the submission title.
statusStringSet the submission status by handle.
statusIdIntSet the submission status ID.
siteIdIntSet the submission site ID.
isIncompleteBooleanSet whether the submission is incomplete.
requestTokenStringOptional token for duplicate-submit and replay protection.
isNewSubmissionBooleanUseful when editing an existing submission and you need to control whether it is treated as new.
...Additional arguments are generated from the form’s field layout.

Query the form’s fields and include inputTypeName when you need to discover the correct variable type for each field.

{
    formieForm(handle: "contactForm") {
        formFields {
            handle
            inputTypeName
        }
    }
}

Complex Fields

Some fields accept structured input rather than a single string. Name, Address, Group, Repeater, Table and File Upload fields are the most common examples.

The generated input type usually follows this pattern:

<formHandle>_<fieldHandle>_Formie<Name>Input

For example, a Name field with the handle yourName on the contactForm form would use contactForm_yourName_FormieNameInput.

Name And Address Fields

mutation SaveSubmission(
    $yourName: contactForm_yourName_FormieNameInput
    $yourAddress: contactForm_yourAddress_FormieAddressInput
) {
    save_contactForm_Submission(yourName: $yourName, yourAddress: $yourAddress) {
        title

        ... on contactForm_Submission {
            yourName
            yourAddress
        }
    }
}
{
    "yourName": {
        "firstName": "Peter",
        "lastName": "Sherman"
    },
    "yourAddress": {
        "address1": "42 Wallaby Way",
        "city": "Sydney",
        "zip": "2000",
        "state": "NSW",
        "country": "Australia"
    }
}

File Upload Fields

File Upload fields accept an array. You can pass base64 file data so Formie can create the asset.

mutation SaveSubmission($fileUploadField: [FileUploadInput]) {
    save_contactForm_Submission(fileUploadField: $fileUploadField) {
        title
    }
}
{
    "fileUploadField": [
        {
            "fileData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQUA...",
            "filename": "testing.png"
        },
        {
            "fileData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQUA..."
        }
    ]
}

If the asset already exists, pass the asset ID instead.

{
    "fileUploadField": [
        {
            "assetId": 1234
        },
        {
            "assetId": 4562
        }
    ]
}

Group Fields

Group fields accept an object containing the nested field handles.

mutation SaveSubmission($groupField: contactForm_groupField_FormieGroupInput) {
    save_contactForm_Submission(groupField: $groupField) {
        title

        ... on contactForm_Submission {
            groupField {
                firstValue
                secondValue
            }
        }
    }
}
{
    "groupField": {
        "firstValue": "This content",
        "secondValue": "is for groups"
    }
}

Repeater Fields

Repeater fields accept a rows array. Each row contains the nested field handles for that row.

mutation SaveSubmission($repeaterField: contactForm_repeaterField_FormieRepeaterInput) {
    save_contactForm_Submission(repeaterField: $repeaterField) {
        title

        ... on contactForm_Submission {
            repeaterField {
                rows {
                    field1
                    field2
                }
            }
        }
    }
}
{
    "repeaterField": {
        "rows": [
            {
                "field1": "First row",
                "field2": "First row value"
            },
            {
                "field1": "Second row",
                "field2": "Second row value"
            }
        ]
    }
}

Captchas

When a form has a captcha enabled, Formie adds a captcha argument to that form’s submission mutation. The argument name is the captcha integration handle with Captcha appended and converted to camel case.

For example, a captcha integration with the handle turnstile becomes the argument turnstileCaptcha.

mutation SaveSubmission(
    $yourName: contactForm_yourName_FormieNameInput
    $turnstileCaptcha: FormieCaptchaInput
) {
    save_contactForm_Submission(yourName: $yourName, turnstileCaptcha: $turnstileCaptcha) {
        title
    }
}
{
    "yourName": {
        "firstName": "Peter",
        "lastName": "Sherman"
    },
    "turnstileCaptcha": {
        "name": "cf-turnstile-response",
        "value": "<token from the Turnstile widget>"
    }
}

The FormieCaptchaInput type contains name and value. Different captcha providers need different front-end handling, so the exact token you pass depends on the captcha integration. Query the generated schema for the form to confirm the argument name that Formie has added.

For full front-end package flows, use the package docs linked from Frontend Assets.

Validation Errors

If validation fails, Formie returns a GraphQL error with the validation errors encoded in the message and included in the error extensions.

{
    "errors": [
        {
            "message": "{\"emailAddress\":[\"Email Address cannot be blank.\"]}",
            "extensions": {
                "category": "validation",
                "errors": {
                    "emailAddress": [
                        "Email Address cannot be blank."
                    ]
                }
            }
        }
    ],
    "data": {
        "save_contactForm_Submission": null
    }
}

Deleting A Submission

Use deleteSubmission to delete a submission. It requires both id and siteId.

mutation DeleteSubmission {
    deleteSubmission(id: 1110, siteId: 2)
}

The mutation returns true when the submission was deleted.

{
    "data": {
        "deleteSubmission": true
    }
}