---
title: "POST /api/admin/course_landing_pages/{id}/publish"
method: POST
path: "/api/admin/course_landing_pages/{id}/publish"
tags: ["Admin: Course Landing Pages"]
---

# POST /api/admin/course_landing_pages/{id}/publish

`POST /api/admin/course_landing_pages/{id}/publish`

## Request

- The document declares no server URL.
- Auth: API key in cookie `session`

Publish a draft or archived landing page. A state is not an update: each change of
      Publication State is its own operation with its own Permission. An illegal
      move, or repeating the current state, is a 409 with a localized `detail`.

## Path parameters

- `id` integer, required

## Response `200`

The request has succeeded.

- CourseLandingPage: A marketing landing page for a course (legacy: `LanguageLandingPage`).
  - `id` integer, required
  - `courseId` integer, required
  - `courseSlug` string, required
  - `createdAt` string, date-time, required
  - `slug` string, required
  - `name` string, required
  - `main` boolean, nullable, required
  - `listed` boolean, nullable, required
  - `state` 'draft' | 'archived' | 'published', required: Publication state shared by landing pages.
  - `order` string, nullable, required: Free-form ordering key (legacy stores it as a string).
  - `footer` boolean, nullable, required: Footer visibility + link caption. Part of the read model so the admin edit form can round-trip the fields it writes.
  - `footerName` string, nullable, required
  - `landingPageToRedirectId` integer, nullable, required
  - `metaTitle` string, required
  - `metaDescription` string, required
  - `header` string, required
  - `description` string, required
  - `usedInHeader` string, nullable, required
  - `usedInDescription` string, nullable, required
  - `outcomesHeader` string, nullable, required
  - `outcomesDescription` string, nullable, required
  - `outcomesImage` string, nullable, required
  - `duration` integer, required: Estimated duration in hours.
  - `enrollmentsCount` integer, required

## Other responses

- `default`: Default error response shared by every operation. `@error` emits an OpenAPI `default` response, keeping central transport failures typed without enumerating every status on every operation.

## Changes

- **2026-10-18** `9380d4c85a04`: 3 info
  - removed the non-success response with the status `401`
  - removed the non-success response with the status `403`
  - added the optional property `errors` to the response with the `default` status
- **2026-10-17** `023e7c2cd140`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/hexlet-basics/apis/hexlet-basics-api/changes/api/admin/course_landing_pages/:id/publish/post.md)

---

[API](https://skmtc.dev/hexlet-basics/apis/hexlet-basics-api.md) · [All operations](https://skmtc.dev/hexlet-basics/apis/hexlet-basics-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hexlet-basics/apis/hexlet-basics-api/revisions/51c7f596b47c?raw)
