# Custom-Field Migration

This page covers v1-to-v2 migration notes for custom-field definitions, selection options, and
value writes.

For the v2-native custom-field model, start with [Custom Fields](/docs/guides/resource-guides/custom-fields). Use the
[API reference](/api) for exact request schemas, response schemas, status codes, and
field-level validation.

## Definition Endpoint Mapping

| v1 usage pattern | v2 direction |
|------------------|--------------|
| Element definitions under `/custom-fields` | Use `/api/v2/custom-fields`. |
| Task definitions under `/task-custom-fields` | Use `/api/v2/task-custom-fields`. |
| Publication definitions under `/publication-custom-fields` | Use `/api/v2/publication-custom-fields`. |
| Task definitions assigned to one format through `/task-custom-fields/format/{id}` | Use `GET /api/v2/task-custom-fields?formatId={id}`. |
| Publication definitions assigned to one platform through `/publication-custom-fields/platform/{id}` | Use `GET /api/v2/publication-custom-fields?platformId={id}`. |
| Definition response `assignedEntitiesIds` | Read `assignedFormats[]` for task fields and `assignedPlatforms[]` for publication fields. |
| Numeric custom-field type values in definition responses | Read named v2 `type` values such as `TEXT`, `SINGLE_SELECTION`, `MULTIPLE_SELECTION`, `DATE`, and `NUMBER`. |

Definition list endpoints use the shared v2 pagination model. See
[Querying Lists](/docs/guides/api-conventions/querying-lists) before replacing v1 list parsers.

## Selection Option Changes

v2 uses plural `options` paths for reusable choices:

```text title="v2 options paths"
GET    /api/v2/custom-fields/{id}/options/{optionId}
GET    /api/v2/custom-fields/{id}/options/external-id/{externalId}
POST   /api/v2/custom-fields/{id}/options
PUT    /api/v2/custom-fields/{id}/options/{optionId}
PUT    /api/v2/custom-fields/{id}/options/external-id/{externalId}
PATCH  /api/v2/custom-fields/{id}/options/{optionId}
PATCH  /api/v2/custom-fields/{id}/options/external-id/{externalId}
DELETE /api/v2/custom-fields/{id}/options/{optionId}
DELETE /api/v2/custom-fields/{id}/options/external-id/{externalId}
```

The same pattern exists under `/api/v2/task-custom-fields` and
`/api/v2/publication-custom-fields`.

Client-impacting changes:

- create returns `201 Created`.
- delete returns `204 No Content`.
- by-external-id operations use `/options/external-id/{externalId}`.
- `PUT` replaces option fields.
- `PATCH` is presence-aware.
- `externalId: null` clears the external ID where documented.
- `name: null` is invalid.

## Value Field Mapping

Element, task, and publication writes use a shared custom-field value shape.

| v1 value field | v2 value field |
|----------------|----------------|
| `id` | `id` |
| `value` | `value` |
| `selectedOption` | `selectedOptionIds` |
| `selectedOptionModels` in responses | `selectedOptions` in responses |
| `date` | `date` (`yyyy-MM-dd`) |
| `number` | `number` |

Send exactly the field that matches the custom-field type. The v2 API validates the custom-field
definition, available option IDs, scope, and type-specific rules.

## Value Write Changes

The most important migration change is selection values:

- replace `selectedOption` with `selectedOptionIds` in write payloads.
- replace response parsing of `selectedOptionModels` with `selectedOptions`.
- clear selection fields by sending `selectedOptionIds: []`.

Empty values for fields that disallow them behave differently in v2:

- v1 rejects an empty date for date fields configured to disallow empty values.
- v2 substitutes a default instead of rejecting or clearing: the field's first option for
  selection fields, the current date for date fields. See
  [Empty-Value Fallback Defaults](/docs/guides/resource-guides/custom-fields#empty-value-fallback-defaults).

Other value-write rules are v2-native behavior and are documented in
[Custom Fields](/docs/guides/resource-guides/custom-fields#value-write-semantics).

## Scope Changes

Custom-field IDs are scoped by organization and placement:

- element custom-field IDs are valid for element values only.
- task custom-field IDs are valid for task values only.
- publication custom-field IDs are valid for publication values only.
- task custom fields can be limited to task formats.
- publication custom fields can be limited to platforms.

When migrating a shared element workflow, do not assume one organization can write another
organization's custom-field values.

## Migration Checklist

- Replace `selectedOption` with `selectedOptionIds` in value write payloads.
- Replace response parsing of `selectedOptionModels` with `selectedOptions`.
- Replace task custom-field format paths with the `formatId` list filter.
- Replace publication custom-field platform paths with the `platformId` list filter.
- Update option paths from singular `option` to plural `options`.
- Update option create/delete status handling to `201 Created` and `204 No Content`.
- Verify custom-field value clears by type instead of copying v1 payloads mechanically.
- Expect default substitution instead of an error when sending empty values to selection or date
  fields that disallow empty values (`allowEmptyValue: false` in definition reads).
