> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superoffice.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How to create a user-defined field using the web services API

> Describes how to create a user-defined field using web services

This guide describes how to create a user-defined field using the web services API.

<Note>
  To show a user-defined field in the client, it must first be published.
</Note>

## Steps

The following REST code snippets use plain http requests to demonstrate how to perform the operation. The WebApi code snippet demonstrates how to perform the same operation using our nuget package [SuperOffice.WebApi][1].

[1]: https://www.nuget.org/packages/SuperOffice.WebApi

All examples depend on the [udefFieldType][1] enum type to define what the data type of the user-defined field should be.

### Create user-defined field of type Number

These examples demonstrate how to create a Number user-defined field. First, a request is sent to obtain the default user-defined field structure, including calculated positioning in the client. Then field values are updated to reflect field text, tooltip, whether it should be indexed, or be mandatory.

<Tabs>
  <Tab title="RESTful REST API">
    1. First get the JSON structure that represents a user-defined field. **This is a POST request.**

       Yes, it is unconventional to use a POST request to get an entity structure, however, this is specific to user-defined fields.

       ```http theme={null}
       POST https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Contact/UdefLayout?udefFieldType=Number HTTP/1.1
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       ```

    2. Update the relevant fields. Change FieldLabel, ShortLabel to update what text is shown in the client.

       ```json theme={null}
       \{
           ...,
           "FieldLabel": "My Number Udef",
           "IsMandatory": true,
           "ShortLabel": "NumUdef",
           "Tooltip": "Tooltip for this Number UD field"
           ...,
       \}
       ```

    3. Save the user-defined field. **This is a PUT request**.

       Yes, it is unconventional to use a PUT request to save, however, this is specific to user-defined fields.

       The PUT request accepts an array of user-defined fields, so more than one could be updated or saved at the same time. Existing user-defined fields not in the array will not be deleted.

       ```http theme={null}
       PUT https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Contact/UdefLayout HTTP/1.1
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       Content-Type: application/json; charset=utf-8

       [\{
       "UDefFieldId": 0,
       "ColumnId": 8971,
       "FieldDefault": "",
       "FieldHeight": 17,
       "FieldLabel": "My Number Udef",
       "FieldLeft": 102,
       "FieldTop": 170,
       "FieldType": "Number",
       "FieldWidth": 100,
       "FormatMask": "",
       "HideLabel": false,
       "IsIndexed": false,
       "LabelHeight": 17,
       "LabelLeft": 0,
       "LabelTop": 170,
       "LabelWidth": 100,
       "LastVersionId": 0,
       "ListTableId": 136,
       "IsMandatory": true,
       "Type": "Contact",
       "Page1LineNo": 0,
       "ProgId": "SuperOffice:12",
       "IsReadOnly": false,
       "ShortLabel": "NumUdef",
       "TabOrder": 11,
       "TextLength": 0,
       "Tooltip": "Tooltip for this Number UD field",
       "UdefIdentity": 11,
       "UDListDefinitionId": 0,
       "Justification": "Left",
       "Version": 11,
       "TemplateVariableName": "cl11",
       "HasBeenPublished": false,
       "MdoListName": null
       \}]
       ```

       The response will contain all of the user-defined fields for this entity, but now the new user-defined field UDefFieldId property will contain a identity value.

    4. Make sure the Contact user-defined fields are not currently being updated.

       ```http theme={null}
       GET https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Contact/UdefLayout/Publish HTTP/1.1
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       ```

       Only if the response is False, proceed to publish and complete the delete operation.

    5. Publish the user-defined field.

           <Danger>
             A Publish request creates a new version of all user-defined fields for the entity. Therefore, all user-defined fields will have updated UdefFieldId values.
           </Danger>

       ```http theme={null}
       POST https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Contact/UdefLayout/Publish HTTP/1.1
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       ```

    6. Finally issue the RebuildUdefDeltas request to force the field to appear in the UI.

       Use the HTTP RPC Agent endpoint as there is no RESTful equivalent.

       ```http theme={null}
       POST https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Agents/Configuration/RebuildUdefDeltas
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       ```
  </Tab>

  <Tab title="HTTP RPC Agent API">
    1. First get the JSON structure that represents a user-defined field. **This is a POST request.**

       ```http theme={null}
       POST https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Agents/UserDefinedFieldInfo/CreateUserDefinedFieldInfo
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       Content-Type: application/json; charset=utf-8

       \{
           "OwnerType": "Contact",
           "FieldType": "Number",
       \}
       ```

       The response:

       ```json theme={null}
       \{
           "UDefFieldId": 0,
           "ColumnId": 8972,
           "FieldDefault": "",
           "FieldHeight": 17,
           "FieldLabel": "",
           "FieldLeft": 102,
           "FieldTop": 187,
           "FieldType": "Number",
           "FieldWidth": 100,
           "FormatMask": "",
           "HideLabel": false,
           "IsIndexed": false,
           "LabelHeight": 17,
           "LabelLeft": 0,
           "LabelTop": 187,
           "LabelWidth": 100,
           "LastVersionId": 0,
           "ListTableId": 0,
           "IsMandatory": false,
           "Type": "Contact",
           "Page1LineNo": 0,
           "ProgId": "SuperOffice:12",
           "IsReadOnly": false,
           "ShortLabel": "",
           "TabOrder": 12,
           "TextLength": 0,
           "Tooltip": "",
           "UdefIdentity": 12,
           "UDListDefinitionId": 0,
           "Justification": "Left",
           "Version": 13,
           "TemplateVariableName": "cl12",
           "HasBeenPublished": false,
           "MdoListName": null,
           "TableRight": null,
           "FieldProperties": \{
               "IsIndexed": \{
               "FieldRight": \{
                   "Mask": "Update",
                   "Reason": ""
               \},
               "FieldType": "System.Boolean",
               "FieldLength": 0
               \},
               "IsMandatory": \{
               "FieldRight": \{
                   "Mask": "Update",
                   "Reason": ""
               \},
               "FieldType": "System.Boolean",
               "FieldLength": 0
               \}
           \}
       \}
       ```

    2. Update the relevant fields. Change FieldLabel, ShortLabel to update what text is shown in the client.

       ```json theme={null}
       \{
           ...,
           "FieldLabel": "My Number Udef",
           "IsMandatory": true,
           "ShortLabel": "NumUdef",
           "Tooltip": "Tooltip for this Number UD field"
           ...,
       \}
       ```

    3. Save the user-defined field. **This is a PUT request**.

       The save request accepts the user-defined field to save.

       ```http theme={null}
       POST https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Agents/UserDefinedFieldInfo/SaveUserDefinedFieldInfo
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       Content-Type: application/json; charset=utf-8

       [\{
           "UDefFieldId": 0,
           "ColumnId": 8971,
           "FieldDefault": "",
           "FieldHeight": 17,
           "FieldLabel": "My Number Udef",
           "FieldLeft": 102,
           "FieldTop": 170,
           "FieldType": "Number",
           "FieldWidth": 100,
           "FormatMask": "",
           "HideLabel": false,
           "IsIndexed": false,
           "LabelHeight": 17,
           "LabelLeft": 0,
           "LabelTop": 170,
           "LabelWidth": 100,
           "LastVersionId": 0,
           "ListTableId": 136,
           "IsMandatory": true,
           "Type": "Contact",
           "Page1LineNo": 0,
           "ProgId": "SuperOffice:12",
           "IsReadOnly": false,
           "ShortLabel": "NumUdef",
           "TabOrder": 11,
           "TextLength": 0,
           "Tooltip": "Tooltip for this Number UD field",
           "UdefIdentity": 11,
           "UDListDefinitionId": 0,
           "Justification": "Left",
           "Version": 11,
           "TemplateVariableName": "cl11",
           "HasBeenPublished": false,
           "MdoListName": null
       \}]
       ```

       The response will contain all of the user-defined fields for this entity, but now the new user-defined field UDefFieldId property will contain a identity value.

       The field is not yet viewable in the UI. It needs to first be published.

    4. Publish the user-defined field.

           <Danger>
             A Publish request creates a new version of all user-defined fields for the entity. Therefore, all user-defined fields will have updated UdefFieldId values.
           </Danger>

       Before published fields, make sure there is no active publish event happening at the same time. As long as the `IsAnyPublishEventActive` call returns false, it is safe to proceed.

       ```http theme={null}
       POST https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Agents/UserDefinedFieldInfo/IsAnyPublishEventActive
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       ```

       To prevent anyone from overwriting your field changes, set the publish event flag for the entity.

       ```http theme={null}
       POST https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Agents/UserDefinedFieldInfo/SetPublishStartSystemEvent
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       Content-Type: application/json; charset=utf-8

       \{
           "OwnerType": "Contact"
       \}
       ```

       Publish the user-defined fields to activate the new field changes.

       ```http theme={null}
       POST https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Agents/UserDefinedFieldInfo/Publish
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       Content-Type: application/json; charset=utf-8

       \{
           "OwnerType": "Contact"
       \}
       ```

       Finally issue the RebuildUdefDeltas request to force the field to appear in the UI.

       ```http theme={null}
       POST https://\{\{env\}\}.superoffice.com/\{\{tenant\}\}/api/v1/Agents/Configuration/RebuildUdefDeltas
       Authorization: Bearer \{\{token\}\}
       Accept: application/json; charset=utf-8
       ```

    #### [SuperOffice.WebApi](#tab/create-webapi)

    1. First create the UserDefinedFieldInfo instance that represents a user-defined field.

       ```csharp theme={null}
       var config = new WebApiOptions(tenant.WebApiUrl);
       config.Authorization = new AuthorizationSystemUserTicket(sysUserInfo, sysUserTicket);

       var udefAgent = new UserDefinedFieldInfoAgent(config);
       var configAgent = new ConfigurationAgent(tenant.WebApiUrl);

       var udef = await udefAgent.CreateUserDefinedFieldInfoAsync(
           UDefType.Contact,
           UDefFieldType.Number
       );

       udef.FieldLabel = "My Number Def";
       udef.IsMandatory = true;
       udef.ShortLabel = "NumUdef";
       udef.Tooltip = "Tooltip for this Number UD field";

       udef = await udefAgent.SaveUserDefinedFieldInfoAsync(udef);
       ```

    2. Publish the user-defined field to make it appear in the client user interface.

       Fields are published by entity type. When published, all user-defined fields for that entity receive a new UDefFieldId number.

       ```csharp theme={null}
       // make sure no one else is trying to publish at the same time
       if(!await udefAgent.IsAnyPublishEventActiveAsync())
       \{
           // state intention to start publishing new / updated fields.
           await udefAgent.SetPublishStartSystemEventAsync(UDefType.Contact);
           // publish user-defined field changes by entity type
           var result = await udefAgent.PublishAsync(UDefType.Contact);

           //force rebuilding udefs so they appear in the UI
           configAgent.RebuildUdefDeltas();
       \}
       ```

       If the fields are not immediately observable in the client user interface (UI), navigate to the application with the ´?flush´ query string parameter at the end of the URL as an authenticated user. The fields should then appear in the UI.
  </Tab>

  <Tab title="CRMScript API">
    ```crmscript theme={null}
    NSUserDefinedFieldInfoAgent udefAgent;
    NSConfigurationAgent configAgent;

    // create the udef by entity type and data type.
    // this will predefine location and version

    NSUserDefinedFieldInfo udef = udefAgent.CreateUserDefinedFieldInfo(NSUDefType.Contact, NSUDefFieldType.Number);
    udef.SetFieldLabel("CRMScript Number");
    udef.SetShortLabel("CRMScript Number");
    udef.SetTooltip("CRMScript Number Tooltip");
    udef = udefAgent.SaveUserDefinedFieldInfo(udef);

    // publish the udefs by entity type

    udefAgent.SetPublishStartSystemEvent(NSUDefType.Contact);
    udefAgent.Publish(NSUDefType.Contact);

    // flush udefs caches (need this to appear in the UI)

    configAgent.RebuildUdefDeltas();
    ```
  </Tab>
</Tabs>

<Note>
  Depending on the user-case it might be a good idea to [flush caches][4].
</Note>

## User-Defined Field Lists

To create a user-defined field based on a list, create it with `udefFieldType` **List**.

### User-defined lists

For user-defined lists, set the ListTableId and  UDListDefinitionId property values accordingly.

| Property           | Description                                                                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| ListTableId        | User-defined lists are always **136**.                                                                                                              |
| UDListDefinitionId | The `UDListDefinitionId` is the udlist id value. To get the udlist id, see the [Get All Lists][2] documentation, and view lists with Type `udlist`. |

### Built-in lists

For Build in Lists. for example the **Business list entity**, only set the `ListTableId` property. You can get the `ListTableId` property from the [MDOProviders documentation][3] page. Alternatively, you can query for all using the dynamic archive provider.

**Request:**

<Tabs>
  <Tab title="Restful REST">
    ```http theme={null}
    GET https://{{env}}.superoffice.com/{{tenant}}/api/v1/archive/dynamic?$select=udlistdefinition.name,udlistdefinition.listTableId HTTP/1.1
    Accept: application/json
    Authorization: Bearer {{token}}
    SO-Language: en-US
    ```

    **Response:**

    All except Business list removed here for brevity.

    ```json theme={null}
    {
          "PrimaryKey": "81",
          "EntityName": "UDListDefinition",
          "udlistdefinition.name": "Company - Business",
          "udlistdefinition.listTableId": 61
    },
    ```
  </Tab>

  <Tab title="HTTP RPC Agent">
    ```http theme={null}
    POST https://{{env}}.superoffice.com/{{tenant}}/api/v1/Agents/Archive/GetArchiveListByColumns HTTP/1.1
    Content-Type: application/json
    Accept: application/json
    Authorization: Bearer {{token}}
    SO-Language: en-US

    {
      "ProviderName": "Dynamic",
      "Columns": [
        "udlistdefinition.name",
        "udlistdefinition.listTableId"
      ],
      "SortOrder": [
        {
          "Name": "udlistdefinition.name",
          "Direction": "ASC"
        }
      ],
      "Restriction": [
        {
          "Name": "getAllRows",
          "Operator": "=",
          "Values": [ "true" ],
          "IsActive": true
        }
      ],
      "Entities": [
        ""
      ],
      "Page": 0,
      "PageSize": 1000000
    }
    ```
  </Tab>

  <Tab title="SuperOffice.WebApi">
    ```csharp theme={null}
    var config = new WebApiOptions(tenant.WebApiUrl);
    config.Authorization = new AuthorizationAccessToken(
        "8A:Cust12345.eylksjdf...321C",
        OnlineEnvironment.SOD);

    var archiveAgent = new ArchiveAgent(config);

    // results contains the column fields and column data.
    var results = await archiveAgent.GetArchiveListByColumnsAsync(
        "dynamic",
        new [] {"udlistdefinition.name", "udlistdefinition.listTableId"},
        new [] {
            new ArchiveOrderByInfo()
            {
                Name="udlistdefinition.name",
                Direction=OrderBySortType.ASC
            }
        },
        new [] {
           new ArchiveRestrictionInfo()
           {
               Name="getAllRows",
               Operator="=",
               Values=new [] {"True"}

           }
        },
        null,
        0,
        int.MaxValue
       );
    ```
  </Tab>
</Tabs>

Do not use the PrimaryKey value, use the `udlistdefinition.listTableId` value.

[1]: /en/api/reference/webapi/SuperOffice.WebApi.Data.UDefFieldType

[2]: ../../../lists/services/how-to/get-all-lists

[3]: ../../../mdo-providers/reference/index

[4]: ../../../caching/flush-cache


## Related topics

- [How to update a user-defined field using the web services API](/en/api/web-services/howto/custom-objects/rest-update-udef-field.md)
- [How to delete a user-defined field using the web services API](/en/api/web-services/howto/custom-objects/rest-delete-udef-field.md)
- [How to get all user-defined fields using the web services API](/en/api/web-services/howto/custom-objects/rest-get-all-udef-fields.md)
- [How to set a user-defined list item on a Udef field (services)](/en/api/web-services/howto/custom-objects/set-udef-listitem-value.md)
- [SuperOffice.WebApi.Data.UserDefinedFieldInfo CreateUserDefinedFieldInfoRequest](/en/api/reference/webapi/SuperOffice.WebApi.Data.UserDefinedFieldInfo_CreateUserDefinedFieldInfoRequest.md)
- [SuperOffice.WebApi.Agents.UserDefinedFieldInfoAgent](/en/api/reference/webapi/SuperOffice.WebApi.Agents.UserDefinedFieldInfoAgent.md)
