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

# Manage compliance custom fields

> Define the extra fields that appear on certificates, quality topics, and institutes — add seasons, facility details, ESG scores, or any attribute your compliance workflow needs.

<Info>
  **When to use this.** Compliance custom fields are admin-level definitions that extend the data
  model for certificates, institutes, and quality topics. You create a field once — choosing its
  type, allowed values, and whether it is mandatory or internal-only — and it then appears on
  every relevant record across your organisation. Use these endpoints to automate that setup, keep
  field definitions in sync with an ERP, or bulk-update a field library as regulations evolve.
</Info>

## The workflow

Custom fields are standalone definitions: create them, optionally deactivate or soft-delete them
when they are no longer needed, and list them to build filter UIs or validate incoming data.

<Steps>
  <Step title="Create the field definitions">
    `POST /api/compliance-custom-fields` with an array of one or more field definitions. A single
    call creates all fields in one all-or-nothing transaction. Choose the `type` carefully — it
    cannot be changed after creation. For dropdown fields, pass `allowedValues` in the same request.
  </Step>

  <Step title="Retrieve a specific field">
    `GET /api/compliance-custom-fields/{id}` to fetch a single definition by its ID, including its
    current allowed values and active property flags.
  </Step>

  <Step title="List and filter fields">
    `GET /api/compliance-custom-fields` to page through all definitions. Filter by `type`, `state`,
    `IsMandatory`, or `InternalOnly` to build admin UIs or validate that an ERP code (`userDefinedId`)
    already exists before creating a duplicate.
  </Step>

  <Step title="Update or retire fields">
    `PUT /api/compliance-custom-fields/{id}` for a full replacement (including a new allowed-value
    list). To retire a field, either set `state: inactive` to hide it from new records, or `DELETE
            /api/compliance-custom-fields/{id}` to soft-delete it. Use the bulk `PUT
            /api/compliance-custom-fields` to mix updates and deletes in a single transaction.
  </Step>
</Steps>

```mermaid theme={"dark"}
sequenceDiagram
  participant C as Client
  participant API as Delogue API
  C->>API: POST /api/compliance-custom-fields  (create field + allowed values)
  API-->>C: compliance_custom_fields_created + field ids
  C->>API: GET /api/compliance-custom-fields?Types=allowedValue&State=active
  API-->>C: paginated list of active dropdown fields
  C->>API: PUT /api/compliance-custom-fields/{id}  (add a new season option)
  API-->>C: compliance_custom_field_updated
  C->>API: DELETE /api/compliance-custom-fields/{id}  (retire a field)
  API-->>C: compliance_custom_field_deleted
```

## Walkthrough

Create an `allowedValue` field called **Facility Country** with three options. The body is an
array — one or many fields are created in a single all-or-nothing transaction.

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl -X POST "https://service.my.delogue.com/api/compliance-custom-fields" \
    -H "Accept: application/json" \
    -H "X-Auth-Token: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '[
    {
      "name": "Facility Country",
      "userDefinedId": "FAC-COUNTRY",
      "type": "allowedValue",
      "position": 3,
      "state": "active",
      "internalOnly": false,
      "isMandatory": true,
      "isMultiLine": false,
      "isSortByAllowedValueId": false,
      "maxChar": null,
      "allowedDecimals": 0,
      "parentCustomFieldId": null,
      "allowedValues": [
        {
          "id": null,
          "value": "China",
          "userDefinedId": "CN",
          "isDefaultValue": false
        },
        {
          "id": null,
          "value": "Bangladesh",
          "userDefinedId": "BD",
          "isDefaultValue": false
        },
        {
          "id": null,
          "value": "Turkey",
          "userDefinedId": "TR",
          "isDefaultValue": true
        }
      ]
    }
  ]'
  ```

  ```js JavaScript theme={"dark"}
  const res = await fetch("https://service.my.delogue.com/api/compliance-custom-fields", {
    method: "POST",
    headers: {
      "Accept": "application/json",
      "X-Auth-Token": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify([
    {
      "name": "Facility Country",
      "userDefinedId": "FAC-COUNTRY",
      "type": "allowedValue",
      "position": 3,
      "state": "active",
      "internalOnly": false,
      "isMandatory": true,
      "isMultiLine": false,
      "isSortByAllowedValueId": false,
      "maxChar": null,
      "allowedDecimals": 0,
      "parentCustomFieldId": null,
      "allowedValues": [
        {
          "id": null,
          "value": "China",
          "userDefinedId": "CN",
          "isDefaultValue": false
        },
        {
          "id": null,
          "value": "Bangladesh",
          "userDefinedId": "BD",
          "isDefaultValue": false
        },
        {
          "id": null,
          "value": "Turkey",
          "userDefinedId": "TR",
          "isDefaultValue": true
        }
      ]
    }
  ]),
  });
  const { data } = await res.json();
  ```
</CodeGroup>

```json theme={"dark"}
{
  "status": "success",
  "code": "compliance_custom_fields_created",
  "data": [
    {
      "id": 29100,
      "name": "Facility Country",
      "userDefinedId": "FAC-COUNTRY",
      "type": "allowedValue",
      "state": "active",
      "position": 3,
      "maxChar": null,
      "allowedDecimals": 0,
      "parentCustomFieldId": null,
      "parentCustomFieldName": null,
      "allowedValues": [
        {
          "id": 160001,
          "value": "China",
          "userDefinedId": "CN",
          "properties": []
        },
        {
          "id": 160002,
          "value": "Bangladesh",
          "userDefinedId": "BD",
          "properties": []
        },
        {
          "id": 160003,
          "value": "Turkey",
          "userDefinedId": "TR",
          "properties": [
            "defaultValue"
          ]
        }
      ],
      "properties": [
        "mandatory"
      ]
    }
  ]
}
```

The response returns the created fields with their assigned IDs. Hold onto each `id` — use it
when updating, deleting, or linking child fields under a `nestedAllowedValue` parent.

## Field reference

Fields that matter most when creating or updating a compliance custom field:

| Field                    | What it means at Delogue                                                                                                            |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `allowedDecimals`        | Number of decimal places for numeric-type fields. Defaults to 0 (integer).                                                          |
| `allowedValues`          | Initial set of selectable options for allowedValue or nestedAllowedValue fields. Null or omitted creates the field with no options. |
| `internalOnly`           | When true, the field is visible to brand users only and hidden from supplier users. Defaults to false.                              |
| `isMandatory`            | When true, the field must be filled in. Defaults to false.                                                                          |
| `isMultiLine`            | When true, text-type fields render as a multi-line textarea. Defaults to false.                                                     |
| `isSortByAllowedValueId` | When true, allowed values are sorted by insertion order rather than alphabetically. Defaults to false.                              |
| `maxChar`                | Maximum character length for text-type fields. Null to leave unrestricted.                                                          |
| `name`                   | Display name of the compliance custom field. Required.                                                                              |
| `parentCustomFieldId`    | ID of the parent compliance custom field. Required for nestedAllowedValue child fields; null for all other types.                   |
| `position`               | Display order within the compliance custom fields panel. Required.                                                                  |
| `state`                  | Initial lifecycle state. Defaults to active.                                                                                        |
| `type`                   | Field type: allowedValue, date, text, nestedAllowedValue, numeric, or divider. Required.                                            |
| `userDefinedId`          | Customer-defined identifier for the field, used in ERP integrations. Null to leave unset.                                           |

<Note>
  `PUT /api/compliance-custom-fields/{id}` is a full replacement. Omitting `isMandatory` or
  `internalOnly` lands them as `false`. The bulk `PUT /api/compliance-custom-fields` supports
  `state: deleted` per item to mix updates and soft-deletes in a single transaction.
</Note>

<Note>
  For a partial update, `PATCH /api/compliance-custom-fields/{id}` accepts an RFC 6902 JSON Patch
  document (`Content-Type: application/json-patch+json`) and touches only the paths you send — e.g.
  `/isMandatory`, `/internalOnly`, `/name`, `/state`. Unlike the full-replace `PUT`, a flag you do
  not patch is left unchanged. `/position` is read-only and `state` cannot be set to `deleted`.
</Note>

<Warning>
  **Breaking change.** On `PUT /api/compliance-custom-fields` and
  `PUT /api/compliance-custom-fields/{id}`, the request booleans `internalOnly`, `isMandatory`,
  `isMultiLine` and `isSortByAllowedValueId` are now non-nullable — they can no longer be sent as
  `null`. Because `PUT` is a full replace, omitting any of them writes `false`. Integrations that
  previously omitted a flag to leave it untouched must now send its current value on every `PUT`
  (or switch to `PATCH`, which only changes the paths you send).
</Warning>

## Roles & permissions

Managing compliance custom fields requires the **`compliance`** permission on a **designer (brand)**
account. In practice, this means the user must hold the **CompanyAdmin** role (and optionally
**Compliance Admin**) — supplier accounts cannot create or modify custom field definitions.

Fields marked `internalOnly: true` are not shown to supplier users anywhere in the platform
(Classic or 2.0), but they are always returned via this API regardless of the calling user's role.

## When things go wrong

Errors use the standard envelope (`status: "error"`, a `code`, and `error.details[]`). See
[Errors & responses](/concepts/errors) for the full list of codes and how to resolve them.

Common cases for compliance custom fields:

| Scenario                                                      | HTTP | `code`                                             |
| ------------------------------------------------------------- | ---- | -------------------------------------------------- |
| `position` is non-null on update                              | 400  | `validation_error.not_allowed`                     |
| Required field (`name`, `type`, `position`) missing on create | 400  | `validation_error.required_field`                  |
| Field ID not found or belongs to another organisation         | 404  | `resource_error.compliance_custom_field_not_found` |
| `parentCustomFieldId` references a non-existent field         | 404  | `resource_error.compliance_custom_field_not_found` |

## What to call next

<CardGroup cols={2}>
  <Card title="Compliance categories" href="/guides/compliance-categories">
    Group certificates by category before applying custom fields.
  </Card>

  <Card title="Size ranges" href="/guides/size-ranges">
    Another admin-level definition: the size sets that styles and items reference.
  </Card>

  <Card title="Style categories" href="/guides/style-categories">
    Organise styles with categories — a similar admin setup pattern.
  </Card>

  <Card title="Authentication" href="/authentication">
    How to get and send your `X-Auth-Token` API key.
  </Card>
</CardGroup>
