Custom Field API Documentation
Custom field management endpoints for creating, updating, copying, deleting, and retrieving custom fields for subscriber lists.
Create a Custom Field
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Required permissions:
CustomField.Create - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: customfield.create |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| SubscriberListID | Integer | Yes | ID of the subscriber list |
| FieldName | String | Conditional | Name of the custom field (required if PresetName not provided) |
| FieldType | String | Conditional | Type of field: "Single line", "Paragraph text", "Multiple choice", "Drop down", "Checkboxes", "Hidden field", "Date field", "Time field" (required if PresetName not provided) |
| PresetName | String | No | Preset name (e.g., "Country"). If set, only SubscriberListID is required |
| DataType | String | No | Simplified data type: "text", "longtext", "number", "datetime", "date", "time", "timestamp", "single-select", "multi-select". Overrides FieldType and other fields |
| DefaultValue | String | No | Default value for the custom field |
| ValidationMethod | String | No | Validation method: "Disabled", "Numbers", "Letters", "Numbers and letters", "Email address", "URL", "Date", "Time", "Custom" |
| ValidationRule | String | Conditional | Validation rule (required if ValidationMethod is "Custom") |
| MergeTagAlias | String | No | Custom merge tag alias (alphanumeric, spaces, dots, hyphens, underscores only). Cannot use reserved subscriber field names: SubscriberID, EmailAddress, SubscriptionDate, SubscriptionIP, OptInDate, SubscriptionStatus, BounceType |
| OptionLabel | Array | No | Array of option labels (for dropdown/multiple choice fields) |
| OptionValue | Array | No | Array of option values (for dropdown/multiple choice fields) |
| OptionSelected | Array | No | Array of selected option keys (for dropdown/multiple choice fields) |
| IsRequired | String | No | Whether field is required: "Yes" or "No" (default: "No") |
| IsUnique | String | No | Whether field must be unique: "Yes" or "No" (default: "No") |
| Visibility | String | No | Field visibility: "Public", "User Only", or "Hidden" (default: "User Only") |
| IsGlobal | String | No | Whether field is global: "Yes" or "No" (default: "No") |
| Years | String | Conditional | Year range for date fields (required if FieldType is "Date field"). Format: "YYYY-YYYY" (e.g., "2010-2030") |
| Meta | Object | No | Additional metadata for the field |
| UniqueIdentifier | Boolean | No | Whether field should be marked as unique identifier |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "customfield.create",
"SessionID": "your-session-id",
"SubscriberListID": 123,
"FieldName": "Company Name",
"FieldType": "Single line",
"DefaultValue": "",
"ValidationMethod": "Disabled",
"IsRequired": "No",
"IsUnique": "No",
"Visibility": "Public"
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": "",
"CustomFieldID": 456
}{
"Success": false,
"ErrorCode": [1, 2],
"ErrorText": ["Missing subscriber list id", "Missing field name"]
}0: Success
1: Missing subscriber list id
2: Missing field name
3: Missing field type
4: Missing validation rule
5: Invalid preset name
7: Invalid data type
8: Invalid subscriber list id
1000: Merge tag alias code has been set for another custom field
1001: Merge tag alias code includes invalid characters
1002: Merge tag alias cannot use a reserved subscriber field nameUpdate a Custom Field
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Required permissions:
CustomField.Update - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Behavior change (v5.9.3, #2348)
For choice-type fields (Drop down, Multiple choice, Checkboxes), the field's stored options are now preserved when you update the field without resending OptionLabel. In earlier versions, any update that omitted OptionLabel (for example, renaming the field while resending the required FieldType) silently erased all of its options. To change the options, send OptionLabel (with OptionValue/OptionSelected); to clear them, send an empty OptionLabel array or change the field to a non-choice type.
Behavior change (v5.9.3, #2341 / #2492)
SubscriberListID is now immutable on update — a custom field cannot be moved to a different list.
A custom field is a real column on that list's subscriber table, and this endpoint only updates the field's metadata; it does not move or recreate the column. Honoring a changed SubscriberListID would leave the field's metadata pointing at a list whose subscriber table has no matching column. To have the field on a different list, create it there with customfield.create.
The parameter is still accepted so existing integrations that echo the field's current list keep working. What changed:
- Sending a
SubscriberListIDthat names a different list you own now returns error14(previously the field was silently repointed, leaving it broken). - Sending a
SubscriberListIDthat names a list you do not own now returns error13(previously it was accepted without an ownership check). - Omitting the parameter now preserves the field's existing list. In earlier versions it wrote an empty list ID, detaching the field so it appeared across all of your lists.
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: customfield.update |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| CustomFieldID | Integer | Yes | ID of the custom field to update |
| FieldName | String | Yes | Name of the custom field |
| FieldType | String | Yes | Type of field: "Single line", "Paragraph text", "Multiple choice", "Drop down", "Checkboxes", "Hidden field", "Date field", "Time field" |
| SubscriberListID | Integer | No | ID of the subscriber list. Immutable — must match the field's current list if sent; a different list returns error 14, a list you do not own returns error 13. Omit to leave the field's list unchanged. A value that is not a positive integer (for example "abc", 0, -1, or an array) fails the format check and is silently ignored with Success: true — neither 13 nor 14 is returned. See the behavior-change note above. |
| DefaultValue | String | No | Default value for the custom field |
| ValidationMethod | String | No | Validation method: "Disabled", "Numbers", "Letters", "Numbers and letters", "Email address", "URL", "Date", "Time", "Custom" |
| ValidationRule | String | Conditional | Validation rule (required if ValidationMethod is "Date", "Time", or "Custom") |
| MergeTagAlias | String | No | Custom merge tag alias (alphanumeric, spaces, dots, hyphens, underscores only). Cannot use reserved subscriber field names: SubscriberID, EmailAddress, SubscriptionDate, SubscriptionIP, OptInDate, SubscriptionStatus, BounceType |
| OptionLabel | Array | No | Array of option labels (for dropdown/multiple choice fields) |
| OptionValue | Array | No | Array of option values (for dropdown/multiple choice fields) |
| OptionSelected | Array | No | Array of selected option keys (for dropdown/multiple choice fields) |
| IsRequired | String | No | Whether field is required: "Yes" or "No" |
| IsUnique | String | No | Whether field must be unique: "Yes" or "No" |
| Visibility | String | No | Field visibility: "Public", "User Only", or "Hidden" |
| IsGlobal | String | No | Whether field is global: "Yes" or "No" |
| Years | String | No | Year range for date fields. Format: "YYYY-YYYY" |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "customfield.update",
"SessionID": "your-session-id",
"CustomFieldID": 456,
"FieldName": "Company Name (Updated)",
"FieldType": "Single line",
"Visibility": "User Only",
"IsRequired": "Yes"
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": ""
}{
"Success": false,
"ErrorCode": [1, 6],
"ErrorText": ["Missing custom field id", "Invalid custom field id"]
}0: Success
1: Missing custom field id
2: Missing field name
3: Missing field type
4: Missing validation rule
6: Invalid custom field id
7: Invalid field type
8: Invalid validation method
9: Invalid visibility value
10: Invalid IsRequired value
11: Invalid IsUnique value
12: Invalid IsGlobal value
13: Invalid subscriber list id (the list does not exist or does not belong to you)
14: Custom field list cannot be changed. Create the custom field on the target list instead.
1000: Merge tag alias code has been set for another custom field
1001: Merge tag alias code includes invalid characters
1002: Merge tag alias cannot use a reserved subscriber field nameCopy Custom Fields Between Lists
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Required permissions:
CustomField.Create - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: customfields.copy |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| SourceListID | Integer | Yes | ID of the source subscriber list |
| TargetListID | Integer | Yes | ID of the target subscriber list |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "customfields.copy",
"SessionID": "your-session-id",
"SourceListID": 123,
"TargetListID": 456
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": ""
}{
"Success": false,
"ErrorCode": [1, 2],
"ErrorText": ["Missing source subscriber list id", "Missing target subscriber list id"]
}0: Success
1: Missing source subscriber list id
2: Missing target subscriber list id
3: Invalid source subscriber list id
4: Invalid target subscriber list idDelete Custom Fields
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Required permissions:
CustomFields.Delete - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: customfields.delete |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| CustomFields | String | Yes | Comma-separated list of custom field IDs to delete (e.g., "123,456,789") |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "customfields.delete",
"SessionID": "your-session-id",
"CustomFields": "456,789,1011"
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": ""
}{
"Success": false,
"ErrorCode": [1],
"ErrorText": ["Custom field ids are missing"]
}0: Success
1: Custom field ids are missingGet Custom Fields
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Required permissions:
CustomFields.Get - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: customfields.get |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| SubscriberListID | Integer | Yes | ID of the subscriber list |
| OrderField | String | No | Field to order by: "FieldName", "CustomFieldID", "FieldType", "IsRequired", "IsUnique", "Visibility", "IsGlobal" (default: "FieldName") |
| OrderType | String | No | Order direction: "ASC" or "DESC" (default: "ASC") |
| ReturnGlobalCustomFields | Boolean | No | Whether to include global custom fields in the response (default: false) |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "customfields.get",
"SessionID": "your-session-id",
"SubscriberListID": 123,
"OrderField": "FieldName",
"OrderType": "ASC",
"ReturnGlobalCustomFields": false
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": "",
"TotalFieldCount": 5,
"CustomFields": [
{
"CustomFieldID": "456",
"RelListID": "123",
"FieldName": "Company Name",
"FieldType": "Single line",
"FieldDefaultValue": "",
"ValidationMethod": "Disabled",
"IsRequired": "No",
"IsUnique": "No",
"Visibility": "Public",
"IsGlobal": "No"
}
]
}{
"Success": false,
"ErrorCode": [1],
"ErrorText": ["Missing subscriber list id"]
}0: Success
1: Missing subscriber list id
2: Invalid subscriber list idCreate a Global Custom Field
POST/api.phpAPI Usage Notes
- Authentication required: Admin API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Behavior change (v5.9.3, #2378)
The documented Years requirement for Date field is now enforced. Creating a field with FieldType set to Date field without a Years value returns error 5. In earlier versions the validation was a dead no-op, so the field was silently created with a default year range of the current year minus 10 through the current year plus 10.
Both an omitted Years and an empty string count as missing. If you relied on the old implicit default, send the range explicitly (for example "Years": "2015-2035").
This applies at creation time only — existing date fields are unaffected, and global.customfield.update is unchanged.
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: global.customfield.create |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| FieldName | String | Yes | Name of the global custom field |
| FieldType | String | Yes | Type of field: "Single line", "Paragraph text", "Multiple choice", "Drop down", "Checkboxes", "Hidden field", "Date field", "Time field" |
| DefaultValue | String | No | Default value for the custom field |
| ValidationMethod | String | No | Validation method: "Disabled", "Numbers", "Letters", "Numbers and letters", "Email address", "URL", "Date", "Time", "Custom" |
| ValidationRule | String | Conditional | Validation rule (required if ValidationMethod is "Custom") |
| MergeTagAlias | String | No | Custom merge tag alias (alphanumeric, spaces, dots, hyphens, underscores only). Cannot use reserved subscriber field names: SubscriberID, EmailAddress, SubscriptionDate, SubscriptionIP, OptInDate, SubscriptionStatus, BounceType |
| OptionLabel | Array | No | Array of option labels (for dropdown/multiple choice fields) |
| OptionValue | Array | No | Array of option values (for dropdown/multiple choice fields) |
| OptionSelected | Array | No | Array of selected option keys (for dropdown/multiple choice fields) |
| IsRequired | String | No | Whether field is required: "Yes" or "No" (default: "No") |
| IsUnique | String | No | Whether field must be unique: "Yes" or "No" (default: "No") |
| Visibility | String | No | Field visibility: "Public" or "User Only" (default: "User Only") |
| Years | String | Conditional | Year range for date fields (required if FieldType is "Date field"). Format: "YYYY-YYYY" (e.g., "2010-2030") |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "global.customfield.create",
"SessionID": "admin-session-id",
"FieldName": "Industry",
"FieldType": "Drop down",
"DefaultValue": "",
"ValidationMethod": "Disabled",
"IsRequired": "No",
"IsUnique": "No",
"Visibility": "Public",
"OptionLabel": ["Technology", "Healthcare", "Finance", "Retail"],
"OptionValue": ["tech", "health", "finance", "retail"],
"OptionSelected": []
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": "",
"CustomFieldID": 789
}{
"Success": false,
"ErrorCode": [2, 3],
"ErrorText": ["Missing field name", "Missing field type"]
}0: Success
2: Missing field name
3: Missing field type
4: Missing validation rule
5: Missing years (for date fields)
1000: Merge tag alias code has been set for another custom field
1001: Merge tag alias code includes invalid characters
1002: Merge tag alias cannot use a reserved subscriber field nameUpdate a Global Custom Field
POST/api.phpAPI Usage Notes
- Authentication required: Admin API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: global.customfield.update |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| CustomFieldID | Integer | Yes | ID of the global custom field to update |
| FieldName | String | Yes | Name of the global custom field |
| FieldType | String | Yes | Type of field: "Single line", "Paragraph text", "Multiple choice", "Drop down", "Checkboxes", "Hidden field", "Date field", "Time field" |
| DefaultValue | String | No | Default value for the custom field |
| ValidationMethod | String | No | Validation method: "Disabled", "Numbers", "Letters", "Numbers and letters", "Email address", "URL", "Date", "Time", "Custom" |
| ValidationRule | String | Conditional | Validation rule (required if ValidationMethod is "Date", "Time", or "Custom") |
| MergeTagAlias | String | No | Custom merge tag alias (alphanumeric, spaces, dots, hyphens, underscores only). Cannot use reserved subscriber field names: SubscriberID, EmailAddress, SubscriptionDate, SubscriptionIP, OptInDate, SubscriptionStatus, BounceType |
| OptionLabel | Array | No | Array of option labels (for dropdown/multiple choice fields) |
| OptionValue | Array | No | Array of option values (for dropdown/multiple choice fields) |
| OptionSelected | Array | No | Array of selected option keys (for dropdown/multiple choice fields) |
| IsRequired | String | No | Whether field is required: "Yes" or "No" |
| IsUnique | String | No | Whether field must be unique: "Yes" or "No" |
| Visibility | String | No | Field visibility: "Public" or "User Only" |
| Years | String | No | Year range for date fields. Format: "YYYY-YYYY" |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "global.customfield.update",
"SessionID": "admin-session-id",
"CustomFieldID": 789,
"FieldName": "Industry Sector",
"FieldType": "Drop down",
"Visibility": "Public",
"IsRequired": "Yes"
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": ""
}{
"Success": false,
"ErrorCode": [1, 6],
"ErrorText": ["Missing custom field id", "Invalid custom field id"]
}0: Success
1: Missing custom field id
2: Missing field name
3: Missing field type
4: Missing validation rule
6: Invalid custom field id
7: Invalid field type
8: Invalid validation method
9: Invalid visibility value
10: Invalid IsRequired value
11: Invalid IsUnique value
1000: Merge tag alias code has been set for another custom field
1001: Merge tag alias code includes invalid characters
1002: Merge tag alias cannot use a reserved subscriber field nameDelete Global Custom Fields
POST/api.phpAPI Usage Notes
- Authentication required: Admin API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: global.customfields.delete |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| CustomFields | String | Yes | Comma-separated list of global custom field IDs to delete (e.g., "123,456,789") |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "global.customfields.delete",
"SessionID": "admin-session-id",
"CustomFields": "789,790,791"
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": ""
}{
"Success": false,
"ErrorCode": [1],
"ErrorText": ["Custom field ids are missing"]
}0: Success
1: Custom field ids are missingGet Global Custom Fields
POST/api.phpAPI Usage Notes
- Authentication required: Admin API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: global.customfields.get |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| OrderField | String | No | Field to order by: "FieldName", "CustomFieldID", "FieldType", "IsRequired", "IsUnique", "Visibility", "IsGlobal" (default: "FieldName") |
| OrderType | String | No | Order direction: "ASC" or "DESC" (default: "ASC") |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "global.customfields.get",
"SessionID": "admin-session-id",
"OrderField": "FieldName",
"OrderType": "ASC"
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": "",
"TotalFieldCount": 3,
"CustomFields": [
{
"CustomFieldID": "789",
"RelListID": "0",
"RelOwnerUserID": "0",
"FieldName": "Industry Sector",
"FieldType": "Drop down",
"FieldDefaultValue": "",
"ValidationMethod": "Disabled",
"IsRequired": "No",
"IsUnique": "No",
"Visibility": "Public",
"IsGlobal": "Yes"
}
]
}{
"Success": false,
"ErrorCode": 0
}0: Success
Help Portal