# Element Publications

This page covers migration notes for publications that belong to an element.

Use it together with the [Element Publications API reference](/api/platform/element-publications),
[Publication Scheduling](/docs/guides/editorial-workflows/publication-scheduling),
[Publishing Publications](/docs/guides/editorial-workflows/publishing-publications),
[Platform Schedule Configuration](/docs/guides/resource-guides/platform-schedule-configuration), and
[Task-Publication Linking](/docs/guides/editorial-workflows/task-publication-linking). The API reference remains the source
of truth for exact schemas, examples, status codes, and field-level omission or `null` semantics.

## Scope

Covered v2 endpoints:

| Area | v2 endpoint |
|------|-------------|
| Create publication | `POST /api/v2/elements/{id}/publications` |
| Patch publication | `PATCH /api/v2/elements/{id}/publications/{publicationId}` |
| Delete publication | `DELETE /api/v2/elements/{elementId}/publications/{publicationId}` |
| Read publication schedule | `GET /api/v2/elements/{id}/publications/{publicationId}/schedule` |
| Replace publication schedule | `PUT /api/v2/elements/{id}/publications/{publicationId}/schedule` |
| Delete publication schedule | `DELETE /api/v2/elements/{id}/publications/{publicationId}/schedule` |
| Publish publication | `POST /api/v2/elements/{id}/publications/{publicationId}/publish` |

Root element `publications[]` branches use closely related models, but root `POST`, `PUT`, and
`PATCH` also have aggregate-level replacement and instruction-list semantics. See
[Elements](/docs/migration-from-v1/elements).

## Endpoint Mapping

| v1 usage pattern | v2 direction |
|------------------|--------------|
| `POST .../elements/{id}/publications/` | Use `POST /api/v2/elements/{id}/publications`. |
| `PATCH .../elements/{id}/publications/{publicationId}` | Use `PATCH /api/v2/elements/{id}/publications/{publicationId}` for non-schedule publication fields. |
| Schedule changes through publication create/patch fields such as `single`, `recurring`, or `timeSlot` | Use `schedule` on publication create, then `PUT /api/v2/elements/{id}/publications/{publicationId}/schedule` for later schedule replacement. |
| Writing actual published date/time through `published` | Use `POST /api/v2/elements/{id}/publications/{publicationId}/publish`. `published` is read-only in v2. |
| `DELETE .../elements/publication/{id}` | Use `DELETE /api/v2/elements/{elementId}/publications/{publicationId}` and expect `204 No Content`. |

Standalone publication create, patch, schedule replacement, and publish return the refreshed parent
element aggregate. Publication delete and schedule delete return no response body.

## Request Field Mapping

Common standalone publication mappings:

| v1-style field | v2 field |
|----------------|----------|
| `status` | `statusId` |
| `platform` | `platformId` |
| `category` | `categoryId` |
| `type` | `typeId` |
| `assignedTasks` | `assignedTaskIds` |
| `single.start.date` | `schedule.date` with `schedule.kind: "single"` |
| `single.start.time` | `schedule.timing.time` with `schedule.timing.type: "exactTime"` |
| `recurring.start` | `schedule.start` with `schedule.kind: "recurring"` |
| `recurring.end` | `schedule.end` |
| `recurring.occurrenceCount` | `schedule.occurrenceCount` |
| `recurring.schedule` | `schedule.weeklySchedule` for `schedule.type: "daily"` |
| `recurring.time` | `schedule.timing.time` with `schedule.timing.type: "exactTime"` |
| `timeSlot.id` | `schedule.timing.timeSlotId` with `schedule.timing.type: "timeSlot"` |
| `published` | read-only `published` response field; set through publish operation |
| `cms_id` | `cms.articleId` |
| `url_to_published_content` | `cms.publishedLink.url` |
| `url_to_published_content_title` | `cms.publishedLink.title` |
| `url_to_content_in_cms` | `cms.editLink.url` |
| `url_to_content_in_cms_title` | `cms.editLink.title` |

For root element writes, task links use `publications[].assignedTaskRefs`. For standalone
publication writes, task links use persisted `assignedTaskIds`.

## Create And Patch Semantics

`POST /api/v2/elements/{id}/publications` creates one publication under an existing element.

Key create rules:

- provide `platformId` or `categoryId` so the API can resolve publication placement.
- `statusId` can be omitted or set to `null` to use No Status.
- `statusId` cannot be the published status; use the publish operation.
- `assignedTaskIds` is optional and accepts only persisted tasks that belong to the same element.
- `schedule` is optional on create.
- `customFields` can be omitted, set to `null`, or sent as `[]` to create without publication
  custom-field values.

`PATCH /api/v2/elements/{id}/publications/{publicationId}` is presence-aware:

- omitted fields remain unchanged.
- `externalId`, `cms`, `scope`, and `upscoreId` can be cleared with `null`.
- `statusId`, `platformId`, `categoryId`, `typeId`, `assignedTaskIds`, and `customFields` reject
  explicit `null`.
- `assignedTaskIds: []` clears all task links; omitted `assignedTaskIds` leaves links unchanged.
- `customFields: []` is an empty patch instruction list; omitted `customFields` leaves values
  unchanged.
- `schedule`, `published`, and top-level `timeSlot` are not patch fields.

Use [Write Semantics](/docs/guides/api-conventions/write-semantics) for method-level rules.

## Schedule Changes

v2 separates publication schedule management from generic publication patching.

Publication create can include an initial `schedule`, but later schedule changes use the schedule
subresource:

```text title="Schedule subresource"
GET    /api/v2/elements/{id}/publications/{publicationId}/schedule
PUT    /api/v2/elements/{id}/publications/{publicationId}/schedule
DELETE /api/v2/elements/{id}/publications/{publicationId}/schedule
```

Important schedule changes from v1:

- `GET .../schedule` returns the schedule object directly.
- reading an undated publication schedule returns `404 Not Found`.
- `PUT .../schedule` is full replacement of the schedule resource.
- `DELETE .../schedule` makes the publication undated and returns `204 No Content`.
- `dateExternalId` can be returned for manual issue dates, but it is read-only and rejected in
  write requests.
- recurring schedules cannot coexist with sibling publications on the same element.

See [Publication Scheduling](/docs/guides/editorial-workflows/publication-scheduling) for schedule shapes and examples.

## Publishing

Publishing is a dedicated command:

```text title="Publish command"
POST /api/v2/elements/{id}/publications/{publicationId}/publish
```

The request has no body. The server sets the actual publish date and time, moves the publication
to the published status, and returns the refreshed parent element aggregate.

Generic publication create and patch reject:

- `published`
- `statusId` equal to the published status

:::caution{title="Already published returns 409"}

If the publication is already published, the publish operation returns `409 Conflict`.

:::

See [Publishing Publications](/docs/guides/editorial-workflows/publishing-publications) for the v2
publish lifecycle guide.

## Delete Behavior

Publication delete removes the addressed publication and returns `204 No Content`.

:::info{title="Deleting the last publication keeps the parent"}

You can delete a publication even when it is the last one on the element — the parent story or event
is not removed. The response has no body, so to read the element's current state afterward call
`GET /api/v2/elements/{id}`, which returns `200 OK` with the refreshed element (no longer including
the deleted publication) as long as the element is still accessible to you. For what an element must
contain to be valid, see [Element Content Requirement](/docs/getting-started/data-model#element-content-requirement).

:::

## Response Handling

For publication create, publication patch, schedule replacement, and publish:

- the response body is the refreshed parent element aggregate
- `Content-Location` points to the parent element
- publication create also returns `Location` for the newly created publication

For publication delete and schedule delete, expect `204 No Content`.

## Related Guides

- [Elements](/docs/migration-from-v1/elements)
- [Publication Scheduling](/docs/guides/editorial-workflows/publication-scheduling)
- [Publishing Publications](/docs/guides/editorial-workflows/publishing-publications)
- [Platform Schedule Configuration](/docs/guides/resource-guides/platform-schedule-configuration)
- [Task-Publication Linking](/docs/guides/editorial-workflows/task-publication-linking)
- [JSON Model Changes](/docs/migration-from-v1/request-response-models)
