Forms
Marketo forms have a complex set of endpoints allowing full control of form management from remote systems. The structure of forms can be complex, as there are many different types of objects which must be managed as part of a form: Forms, Fields, Fieldsets, Visibility Rules, and Followup Page Rules.
Query
Forms support the standard methods of asset retrieval, , , and . Each form response contains all of its properties except for its field list.
By ID
takes a form id
as a path parameter and returns a form record.
GET /rest/asset/v1/form/{id}.json
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "948f#154e3bad8e3",
"result": [
{
"id": 736,
"name": "newForm",
"description": "test",
"createdAt": "2016-05-24T17:05:54Z+0000",
"updatedAt": "2016-05-24T17:05:54Z+0000",
"url": "https://app-devlocal1.marketo.com/#FO736B2",
"status": "draft",
"theme": "simple",
"language": "French",
"locale": "fr_FR",
"progressiveProfiling": false,
"labelPosition": "left",
"fontFamily": "Helvetica",
"fontSize": "13px",
"folder": {
"type": "Folder",
"value": 293,
"folderName": "yyLNLHzgOM"
},
"knownVisitor": {
"type": "form",
"template": null
},
"thankYouList": [
{
"followupType": "none",
"followupValue": null,
"default": true
}
],
"buttonLocation": 120,
"buttonLabel": "Envoyer",
"waitingLabel": "Veuillez patienter"
}
]
}
By Name
takes a form name
as a path parameter and returns a form record.
GET /rest/asset/v1/form/byName.json?name=newForm
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "948f#154e3bad8e3",
"result": [
{
"id": 736,
"name": "newForm",
"description": "test",
"createdAt": "2016-05-24T17:05:54Z+0000",
"updatedAt": "2016-05-24T17:05:54Z+0000",
"url": "https://app-devlocal1.marketo.com/#FO736B2",
"status": "draft",
"theme": "simple",
"language": "French",
"locale": "fr_FR",
"progressiveProfiling": false,
"labelPosition": "left",
"fontFamily": "Helvetica",
"fontSize": "13px",
"folder": {
"type": "Folder",
"value": 293,
"folderName": "yyLNLHzgOM"
},
"knownVisitor": {
"type": "form",
"template": null
},
"thankYouList": [
{
"followupType": "none",
"followupValue": null,
"default": true
}
],
"buttonLocation": 120,
"buttonLabel": "Envoyer",
"waitingLabel": "Veuillez patienter"
}
]
}
Browse
forms works like other Asset API browse endpoints, and allows optional filtering on status
,maxReturn
, and offset
. Status can be: approved, approved with draft, or draft.
GET /rest/asset/v1/forms.json
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "645d#154e3d499ac",
"result": [
{
"id": 227,
"name": "aKAUVDfbsX",
"description": "",
"createdAt": "2016-05-18T20:36:20Z+0000",
"updatedAt": "2016-05-18T20:36:20Z+0000",
"url": "https://app-devlocal1.marketo.com/#FO227B2",
"status": "draft",
"theme": "simple",
"language": "English",
"locale": "en_US",
"progressiveProfiling": false,
"labelPosition": "left",
"fontFamily": "Helvetica",
"fontSize": "13px",
"folder": {
"type": "Folder",
"value": 293,
"folderName": "yyLNLHzgOM"
},
"knownVisitor": {
"type": "form",
"template": null
},
"thankYouList": [
{
"followupType": "none",
"followupValue": null,
"default": true
}
],
"buttonLocation": 120,
"buttonLabel": "Submit",
"waitingLabel": "Please Wait"
},
{
"id": 695,
"name": "AoMXgfFbma",
"description": "",
"createdAt": "2016-05-19T18:50:40Z+0000",
"updatedAt": "2016-05-19T18:50:40Z+0000",
"url": "https://app-devlocal1.marketo.com/#FO695B2",
"status": "draft",
"theme": "simple",
"language": "English",
"locale": "en_US",
"progressiveProfiling": true,
"labelPosition": "left",
"fontFamily": "Helvetica",
"fontSize": "13px",
"folder": {
"type": "Folder",
"value": 565,
"folderName": "WfUvYmlcyT"
},
"knownVisitor": {
"type": "form",
"template": null
},
"thankYouList": [
{
"followupType": "none",
"followupValue": null,
"default": true
}
],
"buttonLocation": 120,
"buttonLabel": "Submit",
"waitingLabel": "Please Wait"
}
]
}
Field List
Retrieving the field list for a form is done on a per form basis.
GET /rest/asset/v1/form/{id}/fields.json
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "2165#154eee00d01",
"result": [
{
"id": "FirstName",
"label": "First Name:",
"dataType": "text",
"validationMessage": "This field is required.",
"rowNumber": 0,
"columnNumber": 0,
"maxLength": 255,
"required": false,
"formPrefill": true,
"visibilityRules": {
"ruleType": "alwaysShow"
}
},
{
"id": "LastName",
"label": "Last Name:",
"dataType": "text",
"validationMessage": "This field is required.",
"rowNumber": 1,
"columnNumber": 0,
"maxLength": 255,
"required": false,
"formPrefill": true,
"visibilityRules": {
"ruleType": "alwaysShow"
}
},
{
"id": "Email",
"label": "Email Address:",
"dataType": "email",
"validationMessage": "Must be valid email. <span class='mktoErrorDetail'>example@yourdomain.com</span>",
"rowNumber": 2,
"columnNumber": 0,
"required": false,
"formPrefill": true,
"visibilityRules": {
"ruleType": "alwaysShow"
}
},
{
"id": "Profiling",
"dataType": "profiling",
"rowNumber": 3,
"columnNumber": 0
}
]
}
When editing fields, or their behavior inside a form, the field list should always be retrieved before attempting edits. This ensures that you give the proper field id when updating or deleting.
Field Types
Dependencies
The endpoint takes a form id
as path parameter and returns the list of assets that depend on the form. Forms may be used by the following asset types: Landing Pages, Smart Lists, Smart Campaigns, Reports, Email Programs.
GET /rest/asset/v1/form/{id}/usedBy.json
{
"success": true,
"errors": [],
"requestId": "fdf4#17285b25038",
"warnings": [],
"result": [
{
"id": 1038,
"name": "LP Redirect Rules Program.LP Test 01",
"type": "Landing Page",
"status": "approved",
"updatedAt": "2020-02-23T01:31:21Z+0000"
}
]
}
Create and Update
When there are only two required fields: the parent folder of the form, the name of the form. All of the other parameters are optional with default value. When the form is created it comes with three default fields: First Name, Last Name, Email.
POST /rest/asset/v1/forms.json
Content-Type: application/x-www-form-urlencoded
name=newForm&description=test&folder={"type": "Folder","id": 293}&language=French
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "948f#154e3bad8e3",
"result": [
{
"id": 736,
"name": "newForm",
"description": "test",
"createdAt": "2016-05-24T17:05:54Z+0000",
"updatedAt": "2016-05-24T17:05:54Z+0000",
"url": "https://app-devlocal1.marketo.com/#FO736B2",
"status": "draft",
"theme": "simple",
"language": "French",
"locale": "fr_FR",
"progressiveProfiling": false,
"labelPosition": "left",
"fontFamily": "Helvetica",
"fontSize": "13px",
"folder": {
"type": "Folder",
"value": 293,
"folderName": "yyLNLHzgOM"
},
"knownVisitor": {
"type": "form",
"template": null
},
"thankYouList": [
{
"followupType": "none",
"followupValue": null,
"default": true
}
],
"buttonLocation": 120,
"buttonLabel": "Envoyer",
"waitingLabel": "Veuillez patienter"
}
]
}
Forms are with a similar call via their id. During either creation or update, any of the base styling parameters are accessible and editable, allowing you to modify how the form is displayed to the end user.
POST /rest/asset/v1/form/736.json
Content-Type: application/x-www-form-urlencoded
name=updated name&description=This is a test for updateapi&language=English&progressiveProfiling=true&locale=en_US
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "6307#154e3cf6efe",
"result": [
{
"id": 736,
"name": "updated name",
"description": "This is a test for update api",
"createdAt": "2016-05-24T17:05:54Z+0000",
"updatedAt": "2016-05-24T17:28:23Z+0000",
"status": "draft",
"theme": "simple",
"language": "English",
"locale": "en_US",
"progressiveProfiling": true,
"labelPosition": "left",
"fontFamily": "Helvetica",
"fontSize": "13px",
"folder": {
"type": "Folder",
"value": 293,
"folderName": "yyLNLHzgOM"
},
"knownVisitor": {
"type": "form",
"template": null
},
"thankYouList": [
{
"followupType": "none",
"followupValue": null,
"default": true
}
],
"buttonLocation": 120,
"buttonLabel": "Submit",
"waitingLabel": "Please Wait"
}
]
}
The known visitor and thank you page behaviors cannot be modified via the create or update form calls, and must be accessed via their respective endpoints.
Field Metadata
To properly add or edit fields belonging to a form, you must retrieve the list of valid fields for the target instance. Field interactions are always done based on the field’s id property which is shown for each item in the result.
For Lead fields, this is done by using the endpoint and includes the data type and default metadata for the field when it is added to a form.
GET /rest/asset/v1/form/fields.json
{
"success": true,
"errors": [],
"requestId": "176ca#167a9808f4c",
"warnings": [],
"result": [
{
"id": "AnnualRevenue",
"isRequired": false,
"dataType": "currency"
},
{
"id": "City",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "Company",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "Country",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "Description",
"isRequired": false,
"dataType": "textarea",
"maxLength": 32000,
"visibleRows": 2
},
{
"id": "Email",
"isRequired": false,
"dataType": "email"
},
{
"id": "Fax",
"isRequired": false,
"dataType": "phone"
},
{
"id": "FirstName",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "Industry",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "LastName",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "LeadSource",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "MobilePhone",
"isRequired": false,
"dataType": "phone"
},
{
"id": "NumberOfEmployees",
"isRequired": false,
"dataType": "int"
},
{
"id": "Phone",
"isRequired": false,
"dataType": "phone"
},
{
"id": "PostalCode",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "Rating",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "Salutation",
"isRequired": false,
"dataType": "picklist",
"picklistValues": "Mr.,Ms.,Mrs.,Dr.,Prof."
},
{
"id": "State",
"isRequired": false,
"dataType": "picklist",
"picklistValues": "AK::AK,AL::AL,AR::AR,AZ::AZ,CA::CA,CO::CO,CT::CT,DE::DE,FL::FL,GA::GA,HI::HI,IA::IA,ID::ID,IL::IL,IN::IN,KS::KS,KY::KY,LA::LA,MA::MA,MD::MD,ME::ME,MI::MI,MN::MN,MO::MO,MS::MS,MT::MT,NC::NC,ND::ND,NE::NE,NH::NH,NJ::NJ,NM::NM,NV::NV,NY::NY,OH::OH,OK::OK,OR::OR,PA::PA,RI::RI,SC::SC,SD::SD,TN::TN,TX::TX,UT::UT,VA::VA,VT::VT,WA::WA,WI::WI,WV::WV,WY::WY"
},
{
"id": "Street",
"isRequired": false,
"dataType": "textarea",
"maxLength": 2000,
"visibleRows": 2
},
{
"id": "Title",
"isRequired": false,
"dataType": "picklist"
}
]
}
For Program Member custom fields, call endpoint to retrieve Program Member custom field data types and default metadata. To use these fields in a form, the form must reside underneath a Program (not in Design Studio). Landing Pages containing forms using these fields must also reside underneath a Program (cannot reside in Design Studio, or be cloned into Design Studio).
GET /rest/asset/v1/form/programMemberFields.json
{
"success": true,
"errors": [],
"requestId": "109c6#16fa0b9c51a",
"warnings": [],
"result": [
{
"id": "pMCFCustomField01",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "pMCFCustomField02",
"isRequired": false,
"dataType": "string",
"maxLength": 255
},
{
"id": "myPMCF",
"isRequired": false,
"dataType": "string",
"maxLength": 255
}
]
}
Edit Field
Each form contains an editable list of fields, which will be displayed to the end user when loaded. Each field is added, updated, or deleted from the field list one at a time via their respective endpoints.
only requires the id of the parent form and the fieldId of the field. All other fields will either be empty or have default values based on their datatype and field metadata. Data is passed as POST x-www-form-urlencoded, not as JSON.
POST /rest/asset/v1/form/{id}/fields.json
Content-Type: application/x-www-form-urlencoded
fieldId=NumberOfEmployees&maxLength=125&defaultValue=this is default&required=true&fieldWidth=100&validationMessage=hey, you there?&label=employee count&hintText=Hint me&minValue=10
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "1826e#154f41b214c",
"result": [
{
"id": "NumberOfEmployees",
"label": "employee count",
"fieldWidth": 100,
"dataType": "number",
"defaultValue": "this is default",
"validationMessage": "hey, you there?",
"rowNumber": 5,
"columnNumber": 0,
"required": true,
"formPrefill": true,
"fieldMetaData": {
"minValue": 10,
"maxValue": null
},
"visibilityRules": {
"ruleType": "alwaysShow"
},
"hintText": "Hint me"
}
]
}
Updates may edit all of the same fields as adding a field, and similarly require form id and the fieldId, except that the fieldId is a path parameter and not a query parameter when performing updates.
POST /rest/asset/v1/form/{id}/field/LastName.json
Content-Type: application/x-www-form-urlencoded
label=enter the last name here
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "5634#15508303abb",
"result": [
{
"id": "LastName",
"label": "enter the last name here",
"dataType": "text",
"validationMessage": "This field is required.",
"rowNumber": 0,
"columnNumber": 0,
"maxLength": 255,
"required": false,
"formPrefill": true,
"visibilityRules": {
"ruleType": "alwaysShow"
}
}
]
}
In the example above we are updating LastName field which is a simple string. Some form fields are more complex. For example, the Salutation field is a “select” field type that contains list of items, and a default value. If you add or update a select type field, unless you set one of the choices to have an isDefault
value of true, then the first choice has no value, and be labeled “Select…”
To update the list items, the format of the “values” parameter is as follows:
POST /rest/asset/v1/form/{id}/field/Salutation.json
Content-Type: application/x-www-form-urlencoded
values=[{"label":"Select...","value":"","isDefault":true,"selected":true}, {"label":"MR","value":"MR"}, {"label":"MS","value":"MS"}, {"label":"MRS","value":"MRS"}, {"label":"DR","value":"DR"}, {"label":"PROF","value":"PROF"}]
{
"success": true,
"warnings": [ ],
"errors": [ ],
"requestId": "71fd#1588d9d1b0c",
"result": [
{
"id": "Salutation",
"label": "Salutation:",
"dataType": "select",
"validationMessage": "This field is required.",
"rowNumber": 3,
"columnNumber": 0,
"required": false,
"formPrefill": true,
"fieldMetaData": {
"multiSelect": false,
"values": [
{
"label": "Select...",
"value": "",
"isDefault": true,
"selected": true
},
{
"label": "MR",
"value": "MR"
},
{
"label": "MS",
"value": "MS"
},
{
"label": "MRS",
"value": "MRS"
},
{
"label": "DR",
"value": "DR"
},
{
"label": "PROF",
"value": "PROF"
}
],
"visibleLines": 1
},
"visibilityRules": {
"ruleType": "alwaysShow"
}
}
]
}
To determine how to format a complex form field, look at the response from Add Field to Form.
Rearranging Field
Fields in a form must be rearranged all as a single unit via the endpoint. The endpoint requires a parameter called positions
, which is a JSON Array of objects with three members:
- columnNumber
- rowNumber
- fieldName (refers to the id of the field)
Fields in a form are arranged in a table-like interface, with up to three columns, and up to ten rows. Both row and column are indexed from 0, so the first row and first column are both indicated by passing a 0. All fields must occupy a unique position
If the target field is also a fieldset, then its record within the positions array, should also contain a parameter called fieldList, an array of objects containing the same columnNumber, rowNumber, and fieldName members. The fieldset itself is treated as a single field for its position in the parent list, while its subfields are positioned according to the given positions in the fieldList parameter.
POST /rest/asset/v1/form/{id}/reArrange.json
Content-Type: application/x-www-form-urlencoded
positions=[{"columnNumber":0,"rowNumber":0,"fieldName":"FirstName"},{"columnNumber":0,"rowNumber":1,"fieldName":"LastName"}, {"columnNumber":0,"rowNumber":2, "fieldName":"Email"}]
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "bb18#15508ef9c04",
"result": [
{
"id": 764
}
]
}
Rich Text
Rich text fields are added through a from lead fields. The field content is passed as multipart/form-data. It should be structured as HTML content which does not contain any script, meta tags, or link tags.
POST /rest/asset/v1/form/{id}/richText.json
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="text"
Content-Type: text/html
<div>Fancy Rich Text Component</div>
-----------------------------9051914041544843365972754266--
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "82c8#154f423bf5c",
"result": [
{
"id": "SHRtbFRleHRfMjAxNi0wNS0yN1QxNDozNDoyNC4xMTVa",
"labelWidth": 260,
"dataType": "htmltext",
"rowNumber": 8,
"columnNumber": 0,
"visibilityRules": {
"ruleType": "alwaysShow"
},
"text": "<div>Fancy Rich Text Component</div>"
}
]
}
Fieldset
Marketo forms feature an optional component called fieldsets. Fieldsets are groups of fields which are treated as a single field within the top-level field list for purposes of movement and treatment by visibility rules. For example, if there is a field for Compliance Requirements, and a client selects yes it might reveal a fieldset containing fields for HIPAA and PCI Compliance requirements.
Fields within fieldsets are unique to the form as a whole, so duplicate fields may not be in both the form’s parent field list, and a child fieldset. Fieldsets are added via the endpoint and will then appear in the result of . Fields are added to a fieldset by moving them into the fieldset’s fieldList via . For these endpoints, data is passed as POST x-www-form-urlencoded, not as JSON.
Visibility Rule
Each field may have a set of visibility rules which determine whether the field can be seen by a visitor depending the values that they have inputted into the form. The rules make a comparison between the value of a subjectField which is present in the form, and a list of values given in the rule. Each field may have one type of visibility rule, show, hide, or alwaysShow, and then a list of rules to evaluate. The rules are evaluated as from top to bottom, and the first rule which evaluates to true is the one which will be applied.
Changing visibility rules is a destructive update.
POST /rest/asset/v1/form/{id}/field/Email/visibility.json
Content-Type: application/x-www-form-urlencoded
visibilityRule={"ruleType":"show", "rules":[{"subjectField": "LastName", "operator": "isNotEmpty", "values": [], "altLabel": "Email:"}]}
{
"success": true,
"warnings": [],
"errors": [],
"requestId": "ab4a#15509030601",
"result": [
{
"formFieldId": "Email",
"ruleType": "show",
"rules": [
{
"subjectField": "LastName",
"operator": "isNotEmpty",
"values": [],
"altLabel": "Email:"
}
]
}
]
}
For the full list of available operators, see the endpoint reference page for .
Followup
Marketo forms may have dynamic follow-up page behavior where rules to redirect to a given page, or stay on the current page may be applied based on the content of designated fields upon submission. Rules may be called Thank You Page rules or Followup Page rules interchangeably. These rules are represented as a JSON array with the members followupType
, followupValue
, operator
, subjectField
, values
, and default
. default
is a Boolean value for which only one record in the array may be true. When a visitor qualifies for no other rules, the rule designated as default will be used. followupType
may be either lp or url, where lp indicates a Marketo Landing Page id for followupValue
, and url will indicate a URL to another page. The operator is used to compare of the value of subject field against the list of values provided.
Submit Button
The submit button styling of the form is managed with the endpoint. The buttonPosition, buttonStyle, label, and waitingLabel (the label shown while submission is pending) can be modified.
This is a destructive update.
Approval
Like most other assets, forms follow a draft-approved model, where there can be a draft version and/or an approved version. Whenever updates are applied to a form, they are always applied to the draft version first, and will only be seen live when the form has been approved. Approving a form takes the current draft version and replacing the approved version, if there is one, with the draft. If the form must be taken down from live, it must first be unapproved, which deletes any current drafts, and demote the approved version to a draft-only state. Forms should always be unapproved before attempting deletion.
Progressive Profiling
When progressive profiling is enabled for a form, a fieldset called “Profiling” is included in its field list. To add or remove fields from the progressive profiling list, you must use the Update Field Positions endpoint. This endpoint makes destructive updates, so all fields in the form must be included in each request. The below example adds the field “Phone” to the progressive profiling list.
POST /rest/asset/v1/form/{id}/reArrange.json
Content-Type: application/x-www-form-urlencoded
positions=[{"columnNumber":0,"rowNumber":0,"fieldName":"Email"},{"columnNumber":0,"rowNumber":1,"fieldName":"LastName"},{"columnNumber":0,"rowNumber":2,"fieldName":"Company"},{"columnNumber":0,"rowNumber":3,"fieldName":"Website"},{"columnNumber":0,"rowNumber":4,"fieldName":"Profiling","fieldList":[{"columnNumber":0,"rowNumber":0,"fieldName":"Phone"}]}]
{
"success": true,
"errors": [],
"requestId": "3d6a#164190dbdf2",
"result": [
{
"id": 1031
}
]
}