# Publishing Publications

Publishing is a lifecycle operation for a publication. It is separate from schedule management:
the schedule describes planned dates and timing, while publishing records the actual published
state managed by the server.

Use [Publication Scheduling](/docs/guides/editorial-workflows/publication-scheduling) for planned
publication dates and the [API reference](/api) for exact endpoint contracts.

## Publish Endpoint

Use the dedicated publish endpoint:

```bash title="Publish a publication"
curl -X POST https://api.kordiam.app/api/v2/elements/100/publications/200/publish \
  -H "Authorization: Bearer ..."
```

Rules:

- No request body is needed.
- The server sets the actual publish date and time from its own clock.
- Linked tasks can reflect server-applied done-state changes after the publication is published.
- The response body is the refreshed parent element aggregate.
- If the publication is already published, the server returns `409 Conflict`.

## Published State In Read Responses

After publishing, the publication object inside the element aggregate includes a read-only
`published` field alongside the schedule. This is a fragment of the publication within the
`GET /api/v2/elements/{elementId}` response, not the schedule subresource:

```json title="Published fragment in the element aggregate"
{
  "id": 200,
  "status": {
    "id": 5,
    "name": "Published"
  },
  "schedule": {
    "kind": "single",
    "date": "2026-04-10",
    "timing": {
      "type": "timeSlot",
      "timeSlotId": 10
    }
  },
  "published": {
    "date": "2026-04-10",
    "time": "11:30"
  }
}
```

In this example `published.time` (`11:30`) is the actual recorded publish time. The planned
`schedule.timing` remains separate read-only schedule data.

`published` is always read-only. Clients should treat it as observed state, not as writable input.

## What Generic Publication Writes Cannot Do

| Field                | Create (`POST`)     | Patch / Update                                 |
|----------------------|---------------------|------------------------------------------------|
| `schedule`           | Accepted (optional) | Rejected - use `/schedule` subresource         |
| `published`          | Rejected            | Rejected - read-only; set by publish operation |
| `status = PUBLISHED` | Rejected            | Rejected - use `POST .../publish`              |

## Common Mistakes

- Setting the publication status to `PUBLISHED` through a generic publication write.
- Sending a `published` object in create, replace, or patch payloads.
- Treating a planned schedule time as the actual publish time.
- Updating schedule and publish state through the same endpoint.
